@ -20,10 +20,11 @@ TransactionLogIteratorImpl::TransactionLogIteratorImpl(
currentFileIndex_ ( 0 ) ,
currentFileIndex_ ( 0 ) ,
lastFlushedSequence_ ( lastFlushedSequence ) {
lastFlushedSequence_ ( lastFlushedSequence ) {
assert ( startingSequenceNumber_ < = * lastFlushedSequence_ ) ;
assert ( startingSequenceNumber_ < = * lastFlushedSequence_ ) ;
assert ( files_ . get ( ) ! = nullptr ) ;
assert ( files_ ! = nullptr ) ;
reporter_ . env = options_ - > env ;
reporter_ . env = options_ - > env ;
reporter_ . info_log = options_ - > info_log . get ( ) ;
reporter_ . info_log = options_ - > info_log . get ( ) ;
SeekToStartSequence ( ) ; // Seek till starting sequence
}
}
Status TransactionLogIteratorImpl : : OpenLogFile (
Status TransactionLogIteratorImpl : : OpenLogFile (
@ -52,7 +53,7 @@ Status TransactionLogIteratorImpl::OpenLogFile(
BatchResult TransactionLogIteratorImpl : : GetBatch ( ) {
BatchResult TransactionLogIteratorImpl : : GetBatch ( ) {
assert ( isValid_ ) ; // cannot call in a non valid state.
assert ( isValid_ ) ; // cannot call in a non valid state.
BatchResult result ;
BatchResult result ;
result . sequence = currentSequence _ ;
result . sequence = currentBatch Seq_ ;
result . writeBatchPtr = std : : move ( currentBatch_ ) ;
result . writeBatchPtr = std : : move ( currentBatch_ ) ;
return result ;
return result ;
}
}
@ -65,24 +66,21 @@ bool TransactionLogIteratorImpl::Valid() {
return started_ & & isValid_ ;
return started_ & & isValid_ ;
}
}
void TransactionLogIteratorImpl : : Next ( ) {
void TransactionLogIteratorImpl : : SeekToStartSequence ( ) {
LogFile * currentLogFile = files_ . get ( ) - > at ( currentFileIndex_ ) . get ( ) ;
std : : string scratch ;
Slice record ;
// First seek to the given seqNo. in the current file.
std : : string scratch ;
Slice record ;
if ( ! started_ ) {
started_ = true ; // this piece only runs onced.
isValid_ = false ;
isValid_ = false ;
if ( startingSequenceNumber_ > * lastFlushedSequence_ ) {
if ( startingSequenceNumber_ > * lastFlushedSequence_ ) {
currentStatus_ = Status : : IOError ( " Looking for a sequence, "
currentStatus_ = Status : : IOError ( " Looking for a sequence, "
" which is not flushed yet. " ) ;
" which is not flushed yet. " ) ;
return ;
}
if ( files_ - > size ( ) = = 0 ) {
return ;
return ;
}
}
Status s = OpenLogReader ( currentLogFile ) ;
Status s = OpenLogReader ( files_ - > at ( 0 ) . get ( ) ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
currentStatus_ = s ;
currentStatus_ = s ;
isValid_ = false ;
return ;
return ;
}
}
while ( currentLogReader_ - > ReadRecord ( & record , & scratch ) ) {
while ( currentLogReader_ - > ReadRecord ( & record , & scratch ) ) {
@ -92,23 +90,39 @@ void TransactionLogIteratorImpl::Next() {
continue ;
continue ;
}
}
UpdateCurrentWriteBatch ( record ) ;
UpdateCurrentWriteBatch ( record ) ;
if ( currentSequence_ > = startingSequenceNumber_ ) {
if ( currentBatchSeq_ + currentBatchCount_ - 1 > =
assert ( currentSequence_ < = * lastFlushedSequence_ ) ;
startingSequenceNumber_ ) {
assert ( currentBatchSeq_ < = * lastFlushedSequence_ ) ;
isValid_ = true ;
isValid_ = true ;
break ;
started_ = true ; // set started_ as we could seek till starting sequence
return ;
} else {
} else {
isValid_ = false ;
isValid_ = false ;
}
}
}
}
if ( isValid_ ) {
// Could not find start sequence in first file. Normally this must be the
// Done for this iteration
// only file. Otherwise log the error and let the iterator return next entry
return ;
if ( files_ - > size ( ) ! = 1 ) {
currentStatus_ = Status : : Corruption ( " Start sequence was not found, "
" skipping to the next available " ) ;
reporter_ . Corruption ( 0 , currentStatus_ ) ;
started_ = true ; // Let Next find next available entry
Next ( ) ;
}
}
}
void TransactionLogIteratorImpl : : Next ( ) {
// TODO:Next() says that it requires Valid to be true but this is not true
// assert(Valid());
std : : string scratch ;
Slice record ;
isValid_ = false ;
if ( ! started_ ) { // Runs every time until we can seek to the start sequence
return SeekToStartSequence ( ) ;
}
}
bool openNextFile = true ;
while ( true ) {
while ( openNextFile ) {
assert ( currentLogReader_ ) ;
assert ( currentLogReader_ ) ;
if ( currentSequence_ < * lastFlushedSequence_ ) {
if ( currentBatch Seq_ < * lastFlushedSequence_ ) {
if ( currentLogReader_ - > IsEOF ( ) ) {
if ( currentLogReader_ - > IsEOF ( ) ) {
currentLogReader_ - > UnmarkEOF ( ) ;
currentLogReader_ - > UnmarkEOF ( ) ;
}
}
@ -119,30 +133,28 @@ void TransactionLogIteratorImpl::Next() {
continue ;
continue ;
} else {
} else {
UpdateCurrentWriteBatch ( record ) ;
UpdateCurrentWriteBatch ( record ) ;
openNextFile = false ;
return ;
break ;
}
}
}
}
}
}
if ( openNextFile ) {
// Open the next file
if ( currentFileIndex_ < files_ . get ( ) - > size ( ) - 1 ) {
if ( currentFileIndex_ < files_ - > size ( ) - 1 ) {
+ + currentFileIndex_ ;
+ + currentFileIndex_ ;
Status status = OpenLogReader ( files_ . get ( ) - > at ( currentFileIndex_ ) . get ( ) ) ;
Status status = OpenLogReader ( files_ - > at ( currentFileIndex_ ) . get ( ) ) ;
if ( ! status . ok ( ) ) {
if ( ! status . ok ( ) ) {
isValid_ = false ;
currentStatus_ = status ;
return ;
}
} else {
isValid_ = false ;
isValid_ = false ;
openNextFile = false ;
currentStatus_ = status ;
if ( currentSequence_ = = * lastFlushedSequence_ ) {
return ;
currentStatus_ = Status : : OK ( ) ;
}
} else {
} else {
currentStatus_ = Status : : IOError ( " NO MORE DATA LEFT " ) ;
isValid_ = false ;
}
if ( currentBatchSeq_ = = * lastFlushedSequence_ ) {
currentStatus_ = Status : : OK ( ) ;
} else {
currentStatus_ = Status : : IOError ( " NO MORE DATA LEFT " ) ;
}
}
return ;
}
}
}
}
}
}
@ -150,7 +162,8 @@ void TransactionLogIteratorImpl::Next() {
void TransactionLogIteratorImpl : : UpdateCurrentWriteBatch ( const Slice & record ) {
void TransactionLogIteratorImpl : : UpdateCurrentWriteBatch ( const Slice & record ) {
WriteBatch * batch = new WriteBatch ( ) ;
WriteBatch * batch = new WriteBatch ( ) ;
WriteBatchInternal : : SetContents ( batch , record ) ;
WriteBatchInternal : : SetContents ( batch , record ) ;
currentSequence_ = WriteBatchInternal : : Sequence ( batch ) ;
currentBatchSeq_ = WriteBatchInternal : : Sequence ( batch ) ;
currentBatchCount_ = WriteBatchInternal : : Count ( batch ) ;
currentBatch_ . reset ( batch ) ;
currentBatch_ . reset ( batch ) ;
isValid_ = true ;
isValid_ = true ;
currentStatus_ = Status : : OK ( ) ;
currentStatus_ = Status : : OK ( ) ;