@ -30,6 +30,7 @@ enum Tag {
kNewFile = 7 ,
// 8 was used for large value refs
kPrevLogNumber = 9 ,
kDeletedLogNumber = 10 ,
// these are new formats divergent from open source leveldb
kNewFile2 = 100 ,
@ -44,6 +45,11 @@ enum Tag {
enum CustomTag {
kTerminate = 1 , // The end of customized fields
kNeedCompaction = 2 ,
// Since Manifest is not entirely currently forward-compatible, and the only
// forward-compatbile part is the CutsomtTag of kNewFile, we currently encode
// kDeletedLogNumber as part of a CustomTag as a hack. This should be removed
// when manifest becomes forward-comptabile.
kDeletedLogNumberHack = 3 ,
kPathId = 65 ,
} ;
// If this bit for the custom tag is set, opening DB should fail if
@ -63,12 +69,14 @@ void VersionEdit::Clear() {
last_sequence_ = 0 ;
next_file_number_ = 0 ;
max_column_family_ = 0 ;
deleted_log_number_ = 0 ;
has_comparator_ = false ;
has_log_number_ = false ;
has_prev_log_number_ = false ;
has_next_file_number_ = false ;
has_last_sequence_ = false ;
has_max_column_family_ = false ;
has_deleted_log_number_ = false ;
deleted_files_ . clear ( ) ;
new_files_ . clear ( ) ;
column_family_ = 0 ;
@ -97,6 +105,24 @@ bool VersionEdit::EncodeTo(std::string* dst) const {
if ( has_max_column_family_ ) {
PutVarint32Varint32 ( dst , kMaxColumnFamily , max_column_family_ ) ;
}
if ( has_deleted_log_number_ ) {
// TODO(myabandeh): uncomment me when manifest is forward-compatible
// PutVarint32Varint64(dst, kDeletedLogNumber, deleted_log_number_);
// Since currently manifest is not forward compatible we encode this entry
// disguised as a kNewFile4 entry which has forward-compatible extensions.
PutVarint32 ( dst , kNewFile4 ) ;
PutVarint32Varint64 ( dst , 0u , 0ull ) ; // level and number
PutVarint64 ( dst , 0ull ) ; // file size
InternalKey dummy_key ( Slice ( " dummy_key " ) , 0ull , ValueType : : kTypeValue ) ;
PutLengthPrefixedSlice ( dst , dummy_key . Encode ( ) ) ; // smallest
PutLengthPrefixedSlice ( dst , dummy_key . Encode ( ) ) ; // largest
PutVarint64Varint64 ( dst , 0ull , 0ull ) ; // smallest_seqno and largerst
PutVarint32 ( dst , CustomTag : : kDeletedLogNumberHack ) ;
std : : string buf ;
PutFixed64 ( & buf , deleted_log_number_ ) ;
PutLengthPrefixedSlice ( dst , Slice ( buf ) ) ;
PutVarint32 ( dst , CustomTag : : kTerminate ) ;
}
for ( const auto & deleted : deleted_files_ ) {
PutVarint32Varint32Varint64 ( dst , kDeletedFile , deleted . first /* level */ ,
@ -218,6 +244,10 @@ const char* VersionEdit::DecodeNewFile4From(Slice* input) {
uint64_t number ;
uint32_t path_id = 0 ;
uint64_t file_size ;
// Since this is the only forward-compatible part of the code, we hack new
// extension into this record. When we do, we set this boolean to distinguish
// the record from the normal NewFile records.
bool this_is_not_a_new_file_record = false ;
if ( GetLevel ( input , & level , & msg ) & & GetVarint64 ( input , & number ) & &
GetVarint64 ( input , & file_size ) & & GetInternalKey ( input , & f . smallest ) & &
GetInternalKey ( input , & f . largest ) & &
@ -252,6 +282,15 @@ const char* VersionEdit::DecodeNewFile4From(Slice* input) {
}
f . marked_for_compaction = ( field [ 0 ] = = 1 ) ;
break ;
case kDeletedLogNumberHack :
// This is a hack to encode kDeletedLogNumber in a forward-compatbile
// fashion.
this_is_not_a_new_file_record = true ;
if ( ! GetFixed64 ( & field , & deleted_log_number_ ) ) {
return " deleted log number malformatted " ;
}
has_deleted_log_number_ = true ;
break ;
default :
if ( ( custom_tag & kCustomTagNonSafeIgnoreMask ) ! = 0 ) {
// Should not proceed if cannot understand it
@ -263,6 +302,10 @@ const char* VersionEdit::DecodeNewFile4From(Slice* input) {
} else {
return " new-file4 entry " ;
}
if ( this_is_not_a_new_file_record ) {
// Since this has nothing to do with NewFile, return immediately.
return nullptr ;
}
f . fd = FileDescriptor ( number , path_id , file_size ) ;
new_files_ . push_back ( std : : make_pair ( level , f ) ) ;
return nullptr ;
@ -331,6 +374,14 @@ Status VersionEdit::DecodeFrom(const Slice& src) {
}
break ;
case kDeletedLogNumber :
if ( GetVarint64 ( & input , & deleted_log_number_ ) ) {
has_deleted_log_number_ = true ;
} else {
msg = " deleted log number " ;
}
break ;
case kCompactPointer :
if ( GetLevel ( & input , & level , & msg ) & &
GetInternalKey ( & input , & key ) ) {
@ -513,6 +564,10 @@ std::string VersionEdit::DebugString(bool hex_key) const {
r . append ( " \n MaxColumnFamily: " ) ;
AppendNumberTo ( & r , max_column_family_ ) ;
}
if ( has_deleted_log_number_ ) {
r . append ( " \n DeletedLogNumber: " ) ;
AppendNumberTo ( & r , deleted_log_number_ ) ;
}
r . append ( " \n } \n " ) ;
return r ;
}
@ -582,6 +637,9 @@ std::string VersionEdit::DebugJSON(int edit_num, bool hex_key) const {
if ( has_max_column_family_ ) {
jw < < " MaxColumnFamily " < < max_column_family_ ;
}
if ( has_deleted_log_number_ ) {
jw < < " DeletedLogNumber " < < deleted_log_number_ ;
}
jw . EndObject ( ) ;