@ -43,6 +43,11 @@ void WriteBatch::Handler::Merge(const Slice& key, const Slice& value) {
throw std : : runtime_error ( " Handler::Merge not implemented! " ) ;
throw std : : runtime_error ( " Handler::Merge not implemented! " ) ;
}
}
void WriteBatch : : Handler : : LogData ( const Slice & blob ) {
// If the user has not specified something to do with blobs, then we ignore
// them.
}
void WriteBatch : : Clear ( ) {
void WriteBatch : : Clear ( ) {
rep_ . clear ( ) ;
rep_ . clear ( ) ;
rep_ . resize ( kHeader ) ;
rep_ . resize ( kHeader ) ;
@ -59,10 +64,9 @@ Status WriteBatch::Iterate(Handler* handler) const {
}
}
input . remove_prefix ( kHeader ) ;
input . remove_prefix ( kHeader ) ;
Slice key , value ;
Slice key , value , blob ;
int found = 0 ;
int found = 0 ;
while ( ! input . empty ( ) ) {
while ( ! input . empty ( ) ) {
found + + ;
char tag = input [ 0 ] ;
char tag = input [ 0 ] ;
input . remove_prefix ( 1 ) ;
input . remove_prefix ( 1 ) ;
switch ( tag ) {
switch ( tag ) {
@ -70,6 +74,7 @@ Status WriteBatch::Iterate(Handler* handler) const {
if ( GetLengthPrefixedSlice ( & input , & key ) & &
if ( GetLengthPrefixedSlice ( & input , & key ) & &
GetLengthPrefixedSlice ( & input , & value ) ) {
GetLengthPrefixedSlice ( & input , & value ) ) {
handler - > Put ( key , value ) ;
handler - > Put ( key , value ) ;
found + + ;
} else {
} else {
return Status : : Corruption ( " bad WriteBatch Put " ) ;
return Status : : Corruption ( " bad WriteBatch Put " ) ;
}
}
@ -77,6 +82,7 @@ Status WriteBatch::Iterate(Handler* handler) const {
case kTypeDeletion :
case kTypeDeletion :
if ( GetLengthPrefixedSlice ( & input , & key ) ) {
if ( GetLengthPrefixedSlice ( & input , & key ) ) {
handler - > Delete ( key ) ;
handler - > Delete ( key ) ;
found + + ;
} else {
} else {
return Status : : Corruption ( " bad WriteBatch Delete " ) ;
return Status : : Corruption ( " bad WriteBatch Delete " ) ;
}
}
@ -85,10 +91,18 @@ Status WriteBatch::Iterate(Handler* handler) const {
if ( GetLengthPrefixedSlice ( & input , & key ) & &
if ( GetLengthPrefixedSlice ( & input , & key ) & &
GetLengthPrefixedSlice ( & input , & value ) ) {
GetLengthPrefixedSlice ( & input , & value ) ) {
handler - > Merge ( key , value ) ;
handler - > Merge ( key , value ) ;
found + + ;
} else {
} else {
return Status : : Corruption ( " bad WriteBatch Merge " ) ;
return Status : : Corruption ( " bad WriteBatch Merge " ) ;
}
}
break ;
break ;
case kTypeLogData :
if ( GetLengthPrefixedSlice ( & input , & blob ) ) {
handler - > LogData ( blob ) ;
} else {
return Status : : Corruption ( " bad WriteBatch Blob " ) ;
}
break ;
default :
default :
return Status : : Corruption ( " unknown WriteBatch tag " ) ;
return Status : : Corruption ( " unknown WriteBatch tag " ) ;
}
}
@ -136,6 +150,10 @@ void WriteBatch::Merge(const Slice& key, const Slice& value) {
PutLengthPrefixedSlice ( & rep_ , value ) ;
PutLengthPrefixedSlice ( & rep_ , value ) ;
}
}
void WriteBatch : : PutLogData ( const Slice & blob ) {
rep_ . push_back ( static_cast < char > ( kTypeLogData ) ) ;
PutLengthPrefixedSlice ( & rep_ , blob ) ;
}
namespace {
namespace {
class MemTableInserter : public WriteBatch : : Handler {
class MemTableInserter : public WriteBatch : : Handler {