@ -230,6 +230,10 @@ TEST_F(DBBasicTestWithTimestamp, GcPreserveLatestVersionBelowFullHistoryLow) {
ASSERT_OK ( s ) ;
ASSERT_EQ ( " v1 " , value ) ;
std : : string key_ts ;
ASSERT_TRUE ( db_ - > Get ( ropts , " k3 " , & value , & key_ts ) . IsNotFound ( ) ) ;
ASSERT_EQ ( Timestamp ( 2 , 0 ) , key_ts ) ;
Close ( ) ;
}
@ -543,23 +547,29 @@ TEST_F(DBBasicTestWithTimestamp, TrimHistoryTest) {
options . comparator = & test_cmp ;
DestroyAndReopen ( options ) ;
auto check_value_by_ts = [ ] ( DB * db , Slice key , std : : string readTs ,
Status status , std : : string checkValue ) {
Status status , std : : string checkValue ,
std : : string expected_ts ) {
ReadOptions ropts ;
Slice ts = readTs ;
ropts . timestamp = & ts ;
std : : string value ;
Status s = db - > Get ( ropts , key , & value ) ;
std : : string key_ts ;
Status s = db - > Get ( ropts , key , & value , & key_ts ) ;
ASSERT_TRUE ( s = = status ) ;
if ( s . ok ( ) ) {
ASSERT_EQ ( checkValue , value ) ;
}
if ( s . ok ( ) | | s . IsNotFound ( ) ) {
ASSERT_EQ ( expected_ts , key_ts ) ;
}
} ;
// Construct data of different versions with different ts
ASSERT_OK ( db_ - > Put ( WriteOptions ( ) , " k1 " , Timestamp ( 2 , 0 ) , " v1 " ) ) ;
ASSERT_OK ( db_ - > Put ( WriteOptions ( ) , " k1 " , Timestamp ( 4 , 0 ) , " v2 " ) ) ;
ASSERT_OK ( db_ - > Delete ( WriteOptions ( ) , " k1 " , Timestamp ( 5 , 0 ) ) ) ;
ASSERT_OK ( db_ - > Put ( WriteOptions ( ) , " k1 " , Timestamp ( 6 , 0 ) , " v3 " ) ) ;
check_value_by_ts ( db_ , " k1 " , Timestamp ( 7 , 0 ) , Status : : OK ( ) , " v3 " ) ;
check_value_by_ts ( db_ , " k1 " , Timestamp ( 7 , 0 ) , Status : : OK ( ) , " v3 " ,
Timestamp ( 6 , 0 ) ) ;
ASSERT_OK ( Flush ( ) ) ;
Close ( ) ;
@ -572,13 +582,15 @@ TEST_F(DBBasicTestWithTimestamp, TrimHistoryTest) {
// Trim data whose version > Timestamp(5, 0), read(k1, ts(7)) <- NOT_FOUND.
ASSERT_OK ( DB : : OpenAndTrimHistory ( db_options , dbname_ , column_families ,
& handles_ , & db_ , Timestamp ( 5 , 0 ) ) ) ;
check_value_by_ts ( db_ , " k1 " , Timestamp ( 7 , 0 ) , Status : : NotFound ( ) , " " ) ;
check_value_by_ts ( db_ , " k1 " , Timestamp ( 7 , 0 ) , Status : : NotFound ( ) , " " ,
Timestamp ( 5 , 0 ) ) ;
Close ( ) ;
// Trim data whose timestamp > Timestamp(4, 0), read(k1, ts(7)) <- v2
ASSERT_OK ( DB : : OpenAndTrimHistory ( db_options , dbname_ , column_families ,
& handles_ , & db_ , Timestamp ( 4 , 0 ) ) ) ;
check_value_by_ts ( db_ , " k1 " , Timestamp ( 7 , 0 ) , Status : : OK ( ) , " v2 " ) ;
check_value_by_ts ( db_ , " k1 " , Timestamp ( 7 , 0 ) , Status : : OK ( ) , " v2 " ,
Timestamp ( 4 , 0 ) ) ;
Close ( ) ;
}
@ -1210,12 +1222,27 @@ TEST_F(DBBasicTestWithTimestamp, MultiGetWithFastLocalBloom) {
std : : vector < Slice > keys ( batch_size ) ;
std : : vector < PinnableSlice > values ( batch_size ) ;
std : : vector < Status > statuses ( batch_size ) ;
std : : vector < std : : string > timestamps ( batch_size ) ;
keys [ 0 ] = " foo " ;
ColumnFamilyHandle * cfh = db_ - > DefaultColumnFamily ( ) ;
db_ - > MultiGet ( read_opts , cfh , batch_size , keys . data ( ) , values . data ( ) ,
statuses . data ( ) ) ;
timestamps . data ( ) , statuses . data ( ) , true ) ;
ASSERT_OK ( statuses [ 0 ] ) ;
ASSERT_EQ ( Timestamp ( 1 , 0 ) , timestamps [ 0 ] ) ;
for ( auto & elem : values ) {
elem . Reset ( ) ;
}
ASSERT_OK ( db_ - > SingleDelete ( WriteOptions ( ) , " foo " , Timestamp ( 2 , 0 ) ) ) ;
ts = Timestamp ( 3 , 0 ) ;
read_ts = ts ;
read_opts . timestamp = & read_ts ;
db_ - > MultiGet ( read_opts , cfh , batch_size , keys . data ( ) , values . data ( ) ,
timestamps . data ( ) , statuses . data ( ) , true ) ;
ASSERT_TRUE ( statuses [ 0 ] . IsNotFound ( ) ) ;
ASSERT_EQ ( Timestamp ( 2 , 0 ) , timestamps [ 0 ] ) ;
Close ( ) ;
}
@ -1251,12 +1278,31 @@ TEST_P(DBBasicTestWithTimestampTableOptions, MultiGetWithPrefix) {
std : : vector < Slice > keys ( batch_size ) ;
std : : vector < PinnableSlice > values ( batch_size ) ;
std : : vector < Status > statuses ( batch_size ) ;
std : : vector < std : : string > timestamps ( batch_size ) ;
keys [ 0 ] = " foo " ;
ColumnFamilyHandle * cfh = db_ - > DefaultColumnFamily ( ) ;
db_ - > MultiGet ( read_opts , cfh , batch_size , keys . data ( ) , values . data ( ) ,
statuses . data ( ) ) ;
timestamps . data ( ) , statuses . data ( ) , true ) ;
ASSERT_OK ( statuses [ 0 ] ) ;
ASSERT_EQ ( Timestamp ( 1 , 0 ) , timestamps [ 0 ] ) ;
for ( auto & elem : values ) {
elem . Reset ( ) ;
}
ASSERT_OK ( db_ - > SingleDelete ( WriteOptions ( ) , " foo " , Timestamp ( 2 , 0 ) ) ) ;
// TODO re-enable after fixing a bug of kHashSearch
if ( GetParam ( ) ! = BlockBasedTableOptions : : IndexType : : kHashSearch ) {
ASSERT_OK ( Flush ( ) ) ;
}
ts = Timestamp ( 3 , 0 ) ;
read_ts = ts ;
db_ - > MultiGet ( read_opts , cfh , batch_size , keys . data ( ) , values . data ( ) ,
timestamps . data ( ) , statuses . data ( ) , true ) ;
ASSERT_TRUE ( statuses [ 0 ] . IsNotFound ( ) ) ;
ASSERT_EQ ( Timestamp ( 2 , 0 ) , timestamps [ 0 ] ) ;
Close ( ) ;
}
@ -1507,8 +1553,10 @@ TEST_F(DBBasicTestWithTimestamp, CompactDeletionWithTimestampMarkerToBottom) {
ts = Timestamp ( 3 , 0 ) ;
read_ts = ts ;
read_opts . timestamp = & read_ts ;
s = db_ - > Get ( read_opts , " a " , & value ) ;
std : : string key_ts ;
s = db_ - > Get ( read_opts , " a " , & value , & key_ts ) ;
ASSERT_TRUE ( s . IsNotFound ( ) ) ;
ASSERT_EQ ( Timestamp ( 3 , 0 ) , key_ts ) ;
// Time-travel to the past before deletion
ts = Timestamp ( 2 , 0 ) ;
@ -1613,9 +1661,8 @@ TEST_P(DBBasicTestWithTimestampFilterPrefixSettings, GetAndMultiGet) {
std : : unique_ptr < Iterator > it1 ( db_ - > NewIterator ( read_opts ) ) ;
ASSERT_NE ( nullptr , it1 ) ;
ASSERT_OK ( it1 - > status ( ) ) ;
// TODO(zjay) Fix seek with prefix
// it1->Seek(keys[i]);
// ASSERT_TRUE(it1->Valid());
it1 - > Seek ( keys [ i ] ) ;
ASSERT_TRUE ( it1 - > Valid ( ) ) ;
}
for ( int i = 2 ; i < 4 ; i + + ) {
@ -2400,12 +2447,18 @@ TEST_P(DBBasicTestWithTimestampCompressionSettings, PutDeleteGet) {
ropts . timestamp = & ts ;
for ( uint64_t i = 0 ; i ! = static_cast < uint64_t > ( kNumKeysPerFile ) ; + + i ) {
std : : string value ;
Status s = db_ - > Get ( ropts , Key1 ( i ) , & value ) ;
std : : string key_ts ;
Status s = db_ - > Get ( ropts , Key1 ( i ) , & value , & key_ts ) ;
if ( ( i % 3 ) = = 2 ) {
ASSERT_OK ( s ) ;
ASSERT_EQ ( " new_value_2 " , value ) ;
ASSERT_EQ ( Timestamp ( 5 , 0 ) , key_ts ) ;
} else if ( ( i % 3 ) = = 1 ) {
ASSERT_TRUE ( s . IsNotFound ( ) ) ;
ASSERT_EQ ( Timestamp ( 5 , 0 ) , key_ts ) ;
} else {
ASSERT_TRUE ( s . IsNotFound ( ) ) ;
ASSERT_EQ ( Timestamp ( 3 , 0 ) , key_ts ) ;
}
}
}