@ -21,12 +21,20 @@
namespace ROCKSDB_NAMESPACE {
namespace ROCKSDB_NAMESPACE {
static void TestEncodeDecode ( const VersionEdit & edit ) {
static void TestEncodeDecode ( const VersionEdit & edit ) {
// Encoding one `VersionEdit` and decoding it again should result in the
// exact same `VersionEdit`. However, a special handling is applied to file
// boundaries: `FileMetaData.smallest`, `FileMetaData.largest` when
// user-defined timestamps should not be persisted. In that scenario, this
// invariant does not hold. We disable this scenario in this util method to
// enable all other test cases continue to verify this invariant, while the
// special case is separately covered in test
// `EncodeDecodeNewFile4HandleFileBoundary`.
std : : string encoded , encoded2 ;
std : : string encoded , encoded2 ;
edit . EncodeTo ( & encoded ) ;
edit . EncodeTo ( & encoded , 0 /* ts_sz */ ) ;
VersionEdit parsed ;
VersionEdit parsed ;
Status s = parsed . DecodeFrom ( encoded ) ;
Status s = parsed . DecodeFrom ( encoded ) ;
ASSERT_TRUE ( s . ok ( ) ) < < s . ToString ( ) ;
ASSERT_TRUE ( s . ok ( ) ) < < s . ToString ( ) ;
parsed . EncodeTo ( & encoded2 ) ;
parsed . EncodeTo ( & encoded2 , 0 /* ts_sz */ ) ;
ASSERT_EQ ( encoded , encoded2 ) ;
ASSERT_EQ ( encoded , encoded2 ) ;
}
}
@ -93,7 +101,7 @@ TEST_F(VersionEditTest, EncodeDecodeNewFile4) {
TestEncodeDecode ( edit ) ;
TestEncodeDecode ( edit ) ;
std : : string encoded , encoded2 ;
std : : string encoded , encoded2 ;
edit . EncodeTo ( & encoded ) ;
edit . EncodeTo ( & encoded , 0 /* ts_sz */ ) ;
VersionEdit parsed ;
VersionEdit parsed ;
Status s = parsed . DecodeFrom ( encoded ) ;
Status s = parsed . DecodeFrom ( encoded ) ;
ASSERT_TRUE ( s . ok ( ) ) < < s . ToString ( ) ;
ASSERT_TRUE ( s . ok ( ) ) < < s . ToString ( ) ;
@ -119,6 +127,57 @@ TEST_F(VersionEditTest, EncodeDecodeNewFile4) {
ASSERT_TRUE ( new_files [ 3 ] . second . user_defined_timestamps_persisted ) ;
ASSERT_TRUE ( new_files [ 3 ] . second . user_defined_timestamps_persisted ) ;
}
}
TEST_F ( VersionEditTest , EncodeDecodeNewFile4HandleFileBoundary ) {
static const uint64_t kBig = 1ull < < 50 ;
size_t ts_sz = 16 ;
static std : : string min_ts ( ts_sz , static_cast < unsigned char > ( 0 ) ) ;
VersionEdit edit ;
std : : string smallest = " foo " ;
std : : string largest = " zoo " ;
// In real manifest writing scenarios, one `VersionEdit` should not contain
// files with different `user_defined_timestamps_persisted` flag value.
// This is just for testing file boundaries handling w.r.t persisting user
// defined timestamps during `VersionEdit` encoding.
edit . AddFile (
3 , 300 , 3 , 100 , InternalKey ( smallest + min_ts , kBig + 500 , kTypeValue ) ,
InternalKey ( largest + min_ts , kBig + 600 , kTypeDeletion ) , kBig + 500 ,
kBig + 600 , true , Temperature : : kUnknown , kInvalidBlobFileNumber ,
kUnknownOldestAncesterTime , kUnknownFileCreationTime ,
300 /* epoch_number */ , kUnknownFileChecksum ,
kUnknownFileChecksumFuncName , kNullUniqueId64x2 ,
0 /* compensated_range_deletion_size */ , 0 /* tail_size */ ,
false /* user_defined_timestamps_persisted */ ) ;
edit . AddFile ( 3 , 300 , 3 , 100 ,
InternalKey ( smallest + min_ts , kBig + 500 , kTypeValue ) ,
InternalKey ( largest + min_ts , kBig + 600 , kTypeDeletion ) ,
kBig + 500 , kBig + 600 , true , Temperature : : kUnknown ,
kInvalidBlobFileNumber , kUnknownOldestAncesterTime ,
kUnknownFileCreationTime , 300 /* epoch_number */ ,
kUnknownFileChecksum , kUnknownFileChecksumFuncName ,
kNullUniqueId64x2 , 0 /* compensated_range_deletion_size */ ,
0 /* tail_size */ , true /* user_defined_timestamps_persisted */ ) ;
std : : string encoded ;
edit . EncodeTo ( & encoded , ts_sz ) ;
VersionEdit parsed ;
Status s = parsed . DecodeFrom ( encoded ) ;
ASSERT_TRUE ( s . ok ( ) ) < < s . ToString ( ) ;
auto & new_files = parsed . GetNewFiles ( ) ;
ASSERT_TRUE ( new_files . size ( ) = = 2 ) ;
ASSERT_FALSE ( new_files [ 0 ] . second . user_defined_timestamps_persisted ) ;
// First file's boundaries do not contain user-defined timestamps.
ASSERT_EQ ( InternalKey ( smallest , kBig + 500 , kTypeValue ) . Encode ( ) ,
new_files [ 0 ] . second . smallest . Encode ( ) ) ;
ASSERT_EQ ( InternalKey ( largest , kBig + 600 , kTypeDeletion ) . Encode ( ) ,
new_files [ 0 ] . second . largest . Encode ( ) ) ;
ASSERT_TRUE ( new_files [ 1 ] . second . user_defined_timestamps_persisted ) ;
// Second file's boundaries contain user-defined timestamps.
ASSERT_EQ ( InternalKey ( smallest + min_ts , kBig + 500 , kTypeValue ) . Encode ( ) ,
new_files [ 1 ] . second . smallest . Encode ( ) ) ;
ASSERT_EQ ( InternalKey ( largest + min_ts , kBig + 600 , kTypeDeletion ) . Encode ( ) ,
new_files [ 1 ] . second . largest . Encode ( ) ) ;
}
TEST_F ( VersionEditTest , ForwardCompatibleNewFile4 ) {
TEST_F ( VersionEditTest , ForwardCompatibleNewFile4 ) {
static const uint64_t kBig = 1ull < < 50 ;
static const uint64_t kBig = 1ull < < 50 ;
VersionEdit edit ;
VersionEdit edit ;
@ -158,7 +217,7 @@ TEST_F(VersionEditTest, ForwardCompatibleNewFile4) {
}
}
} ) ;
} ) ;
ROCKSDB_NAMESPACE : : SyncPoint : : GetInstance ( ) - > EnableProcessing ( ) ;
ROCKSDB_NAMESPACE : : SyncPoint : : GetInstance ( ) - > EnableProcessing ( ) ;
edit . EncodeTo ( & encoded ) ;
edit . EncodeTo ( & encoded , 0 /* ts_sz */ ) ;
ROCKSDB_NAMESPACE : : SyncPoint : : GetInstance ( ) - > DisableProcessing ( ) ;
ROCKSDB_NAMESPACE : : SyncPoint : : GetInstance ( ) - > DisableProcessing ( ) ;
VersionEdit parsed ;
VersionEdit parsed ;
@ -198,7 +257,7 @@ TEST_F(VersionEditTest, NewFile4NotSupportedField) {
PutLengthPrefixedSlice ( str , str1 ) ;
PutLengthPrefixedSlice ( str , str1 ) ;
} ) ;
} ) ;
ROCKSDB_NAMESPACE : : SyncPoint : : GetInstance ( ) - > EnableProcessing ( ) ;
ROCKSDB_NAMESPACE : : SyncPoint : : GetInstance ( ) - > EnableProcessing ( ) ;
edit . EncodeTo ( & encoded ) ;
edit . EncodeTo ( & encoded , 0 /* ts_sz */ ) ;
ROCKSDB_NAMESPACE : : SyncPoint : : GetInstance ( ) - > DisableProcessing ( ) ;
ROCKSDB_NAMESPACE : : SyncPoint : : GetInstance ( ) - > DisableProcessing ( ) ;
VersionEdit parsed ;
VersionEdit parsed ;
@ -214,7 +273,7 @@ TEST_F(VersionEditTest, EncodeEmptyFile) {
1 /*epoch_number*/ , kUnknownFileChecksum ,
1 /*epoch_number*/ , kUnknownFileChecksum ,
kUnknownFileChecksumFuncName , kNullUniqueId64x2 , 0 , 0 , true ) ;
kUnknownFileChecksumFuncName , kNullUniqueId64x2 , 0 , 0 , true ) ;
std : : string buffer ;
std : : string buffer ;
ASSERT_TRUE ( ! edit . EncodeTo ( & buffer ) ) ;
ASSERT_TRUE ( ! edit . EncodeTo ( & buffer , 0 /* ts_sz */ ) ) ;
}
}
TEST_F ( VersionEditTest , ColumnFamilyTest ) {
TEST_F ( VersionEditTest , ColumnFamilyTest ) {
@ -583,7 +642,7 @@ TEST_F(VersionEditTest, IgnorableTags) {
edit . SetColumnFamily ( kColumnFamilyId ) ;
edit . SetColumnFamily ( kColumnFamilyId ) ;
std : : string encoded ;
std : : string encoded ;
ASSERT_TRUE ( edit . EncodeTo ( & encoded ) ) ;
ASSERT_TRUE ( edit . EncodeTo ( & encoded , 0 /* ts_sz */ ) ) ;
VersionEdit decoded ;
VersionEdit decoded ;
ASSERT_OK ( decoded . DecodeFrom ( encoded ) ) ;
ASSERT_OK ( decoded . DecodeFrom ( encoded ) ) ;