⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scan.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
			// nothing more can be read.  Else check scan limit			if (currentInstant < stopAt && stopAt != LogCounter.INVALID_LOG_INSTANT)			{				currentInstant = LogCounter.INVALID_LOG_INSTANT;				return null;	// we went past the stopAt			}			byte[] data = input.getData();			if (data.length < recordLength)			{				// make a new array of sufficient size and reset the arrary				// in the input stream				data = new byte[recordLength];				input.setData(data);			}			// If the log is encrypted, we must do the filtering after reading			// and decrypting the record.			if (logFactory.databaseEncrypted())			{				scan.readFully(data, 0, recordLength);				int len = logFactory.decrypt(data, 0, recordLength, data, 0);				if (SanityManager.DEBUG)					SanityManager.ASSERT(len == recordLength);				input.setLimit(0, recordLength);			}			else // no need to decrypt, only get the group and tid if we filter 			{				if (groupmask == 0 && tranId == null)				{					// no filter, get the whole thing					scan.readFully(data, 0, recordLength);					input.setLimit(0, recordLength);				}				else				{					// Read only enough so that group and the tran id is in					// the data buffer.  Group is stored as compressed int					// and tran id is stored as who knows what.  read min					// of peekAmount or recordLength					readAmount = (recordLength > peekAmount) ?						peekAmount : recordLength; 					// in the data buffer, we now have enough to peek					scan.readFully(data, 0, readAmount);					input.setLimit(0, readAmount);				}			}			lr = (LogRecord) input.readObject();			// skip the checksum log records, there is no need to look at them 			// during backward scans. They are used only in forwardscan during recovery. 			if(lr.isChecksum())			{				candidate = false; 			}else if (groupmask != 0 || tranId != null)			{				// skip the checksum log records  				if(lr.isChecksum())					candidate = false; 				if (candidate && groupmask != 0 && (groupmask & lr.group()) == 0)					candidate = false; // no match, throw this log record out 				if (candidate && tranId != null)				{					TransactionId tid = lr.getTransactionId();					if (!tid.equals(tranId)) // nomatch						candidate = false; // throw this log record out				}				// if this log record is not filtered out, we need to read				// in the rest of the log record to the input buffer.				// Except if it is an encrypted database, in which case the				// entire log record have already be read in for				// decryption.				if (candidate && !logFactory.databaseEncrypted())				{					// read the rest of the log into the buffer					if (SanityManager.DEBUG)						SanityManager.ASSERT(readAmount > 0);					if (readAmount < recordLength)					{						// Need to remember where we are because the log						// record may have read part of it off the input						// stream already and that position is lost when we						// set limit again.						int inputPosition = input.getPosition();						scan.readFully(data, readAmount,									   recordLength-readAmount); 						input.setLimit(0, recordLength);						input.setPosition(inputPosition);					}				}			}			// go back to the start of the log record so that the next time			// this method is called, it is positioned right past the last byte			// of the record.			curpos = recordStartPosition;			scan.seek(curpos);		} while (candidate == false);		return lr;	}	/**		Read the next log record.		Switching log to a previous log file if necessary, 		Resize the input stream byte array if necessary.  		@see StreamLogScan#getNextRecord		Side effects include: 				on a successful read, setting currentInstant, knownGoodLogEnd				on a log file switch, setting currentLogFileNumber, currentLogFileLength.				on detecting a fuzzy log end that needs clearing, it will call				logFactory to clear the fuzzy log end.		@return the next LogRecord, or null if the end of the		scan has been reached.	*/	private LogRecord getNextRecordForward(ArrayInputStream input, 									 TransactionId tranId,  									 int groupmask)		 throws StandardException,  IOException, ClassNotFoundException	{		if (SanityManager.DEBUG)			SanityManager.ASSERT(scanDirection == FORWARD, "can only called by forward scan");		// NOTE:		//		// if forward scan, scan is positioned at the first byte of the		// next record, or the end of file - note the the 'end of file'		// is defined at the time the scan is initialized.  If we are		// on the current log file, it may well have grown by now...		//		// This is not a problem in reality because the only forward		// scan on the log now is recovery redo and the log does not		// grow.  If in the future, a foward scan of the log is used		// for some other reasons, need to keep this in mind.		//		// first we need to make sure the entire log record is on the		// log, or else this is a fuzzy log end.		// RESOLVE: can get this from knownGoodLogEnd if this is not the first		// time getNext is called.  Probably just as fast to call		// scan.getFilePointer though...		long recordStartPosition = scan.getFilePointer();		boolean candidate;		// if we have filtering, peek at the group and/or the transaction id,		// do them in one read rather than 2 reads.		int peekAmount = LogRecord.formatOverhead() + LogRecord.maxGroupStoredSize();		if (tranId != null)			peekAmount += LogRecord.maxTransactionIdStoredSize(tranId);		int readAmount;			// the number of bytes actually read		LogRecord lr;		do		{			// this log record is a candidate unless proven otherwise			candidate = true;			lr = null;			readAmount = -1;			// if we are not right at the end but this position + 4 is at			// or exceeds the end, we know we don't have a complete log			// record.  This is the log file and chalk it up as the fuzzy			// end.			if (recordStartPosition + 4 > currentLogFileLength)			{				// since there is no end of log file marker, we are at the				// end of the log.				if (SanityManager.DEBUG)                {                    if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))                    {                        SanityManager.DEBUG(LogToFile.DBG_FLAG,                             "detected fuzzy log end on log file " +                                 currentLogFileNumber +                             " record start position " + recordStartPosition +                             " file length " + currentLogFileLength);                    }                }								//if  recordStartPosition == currentLogFileLength				//there is NO fuzz, it just a properly ended log 				//without the end marker. 				if(recordStartPosition != currentLogFileLength)					fuzzyLogEnd = true ;				// don't bother to write the end of log file marker because				// if it is not overwritten by the next log record then				// the next time the database is recovered it will come				// back right here				return null;			}			// read in the length before the log record			int recordLength = scan.readInt();			while (recordLength == 0 || recordStartPosition + recordLength +				   LogToFile.LOG_RECORD_OVERHEAD > currentLogFileLength) 			{				// if recordLength is zero or the log record goes beyond the				// current file, then we have detected the end of a log file.				//				// If recordLength == 0 then we know that this log file has either				// been properly switched or it had a 1/2 written log record which 				// was subsequently cleared by clearFuzzyEnd.				//				// If recordLength != 0 but log record goes beyond the current log				// file, we have detected a fuzzy end.  This is the last log file				// since we will clear it by clearFuzzyEnd.				if (recordLength != 0) // this is a fuzzy log end				{					if (SanityManager.DEBUG)                    {                        if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))                        {                            SanityManager.DEBUG(                                LogToFile.DBG_FLAG,                                 "detected fuzzy log end on log file " +                                     currentLogFileNumber +                                 " record start position " +                                     recordStartPosition +                                 " file length " + currentLogFileLength + 								" recordLength=" + recordLength );                        }                    }					fuzzyLogEnd = true;					scan.close();					scan = null;					return null;				}				// recordLength == 0				if (SanityManager.DEBUG)                 {                    if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))                    {                        if (recordStartPosition + 4 == currentLogFileLength)                        {                            SanityManager.DEBUG(LogToFile.DBG_FLAG,                                 "detected proper log end on log file " +                                 currentLogFileNumber);                        }                        else                        {                            SanityManager.DEBUG(LogToFile.DBG_FLAG,                                     "detected zapped log end on log file " +                                         currentLogFileNumber +                                    " end marker at " +                                         recordStartPosition +                                     " real end at " + currentLogFileLength);                        }                    }				}								// don't go thru the trouble of switching log file if we				// have will have gone past stopAt if we want to stop here				if (stopAt != LogCounter.INVALID_LOG_INSTANT &&					LogCounter.getLogFileNumber(stopAt) == currentLogFileNumber)				{					return null;				}				//				// we have a log end marker and we don't want to stop yet, switch				// log file				//				scan.close();				// set this.currentLogFileNumber				scan = logFactory.getLogFileAtBeginning(++currentLogFileNumber);				if (scan == null) // we have seen the last log file				{					return null;				}				if (SanityManager.DEBUG)                 {                    if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))                    {                        SanityManager.DEBUG(LogToFile.DBG_FLAG,                             "switched to next log file " +                             currentLogFileNumber);                    }                }				// scan is position just past the log header				recordStartPosition = scan.getFilePointer();				// set this.currentLogFileLength				currentLogFileLength = scan.length();				if (recordStartPosition+4 >= currentLogFileLength) // empty log file				{					if (SanityManager.DEBUG)                    {                        if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))                        {                            SanityManager.DEBUG(LogToFile.DBG_FLAG,                                 "log file " + currentLogFileNumber +                                 " is empty");                        }                    }					// ideally, we would want to start writing on this new					// empty log file, but the scan is closed and there is					// no way to tell the difference between an empty log					// file and a log file which is not there.  We will be					// writing to the end of the previous log file instead					// but when we next switch the log, the empty log file					// will be written over.					return null;				}				// we have successfully switched to the next log file.				// scan is positioned just before the next log record				// see if this one is written in entirety				recordLength = scan.readInt();			}			// we know the entire log record is on this log file			// read the current log instant			currentInstant = scan.readLong();						/*check if the current instant happens is less than the last one. 			 *This can happen if system crashed before writing the log instant			 *completely. If the instant is partially written it will be less			 *than the last one and should be the last record that was suppose to			 *get written. Currentlt preallocated files are filled with zeros,			 *this should hold good.			 *Note: In case of Non-preallocated files earlier check with log			 * file lengths should have found the end. But in prellocated files, log file			 *length is not sufficiant to find the log end. This check 			 *is must to find the end in preallocated log files. 			 */			if(currentInstant < knownGoodLogEnd)			{				fuzzyLogEnd = true ;				return null;			}			// sanity check it 			if (SanityManager.DEBUG)			{				if (LogCounter.getLogFileNumber(currentInstant) !=					currentLogFileNumber ||					LogCounter.getLogFilePosition(currentInstant) !=					recordStartPosition)					SanityManager.THROWASSERT(							  "Wrong LogInstant on log record " +								LogCounter.toDebugString(currentInstant) + 								 " version real position (" +								 currentLogFileNumber + "," +								 recordStartPosition + ")");			}			// if stopAt == INVALID_LOG_INSTANT, no stop instant, read till			// nothing more can be read.  Else check scan limit			if (stopAt != LogCounter.INVALID_LOG_INSTANT && currentInstant > stopAt)			{				currentInstant = LogCounter.INVALID_LOG_INSTANT;				return null;			// we went past the stopAt			}			// read in the log record			byte[] data = input.getData();			if (data.length < recordLength)			{				// make a new array of sufficient size and reset the arrary				// in the input stream				data = new byte[recordLength];				input.setData(data);			}			// If the log is encrypted, we must do the filtering after			// reading and decryptiong the record.			if (logFactory.databaseEncrypted())			{				scan.readFully(data, 0, recordLength);				int len = logFactory.decrypt(data, 0, recordLength, data, 0);				if (SanityManager.DEBUG)					SanityManager.ASSERT(len == recordLength);				input.setLimit(0, len);			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -