@ -43,13 +43,14 @@ class TtlTest {
// Open database with TTL support when TTL not provided with db_ttl_ pointer
void OpenTtl ( ) {
assert ( db_ttl_ = = nullptr ) ; // db should be closed before opening again
ASSERT_TRUE ( db_ttl_ = =
nullptr ) ; // db should be closed before opening again
ASSERT_OK ( UtilityDB : : OpenTtlDB ( options_ , dbname_ , & db_ttl_ ) ) ;
}
// Open database with TTL support when TTL provided with db_ttl_ pointer
void OpenTtl ( int32_t ttl ) {
assert ( db_ttl_ = = nullptr ) ;
ASSERT_TRUE ( db_ttl_ = = nullptr ) ;
ASSERT_OK ( UtilityDB : : OpenTtlDB ( options_ , dbname_ , & db_ttl_ , ttl ) ) ;
}
@ -63,7 +64,7 @@ class TtlTest {
// Open database with TTL support in read_only mode
void OpenReadOnlyTtl ( int32_t ttl ) {
assert ( db_ttl_ = = nullptr ) ;
ASSERT_TRUE ( db_ttl_ = = nullptr ) ;
ASSERT_OK ( UtilityDB : : OpenTtlDB ( options_ , dbname_ , & db_ttl_ , ttl , true ) ) ;
}
@ -97,7 +98,7 @@ class TtlTest {
// Makes a write-batch with key-vals from kvmap_ and 'Write''s it
void MakePutWriteBatch ( const BatchOperation * batch_ops , int num_ops ) {
assert ( num_ops < = ( int ) kvmap_ . size ( ) ) ;
ASSERT_LE ( num_ops , ( int ) kvmap_ . size ( ) ) ;
static WriteOptions wopts ;
static FlushOptions flush_opts ;
WriteBatch batch ;
@ -111,7 +112,7 @@ class TtlTest {
batch . Delete ( kv_it_ - > first ) ;
break ;
default :
assert ( false ) ;
ASSERT_TRUE ( false ) ;
}
}
db_ttl_ - > Write ( wopts , & batch ) ;
@ -119,26 +120,38 @@ class TtlTest {
}
// Puts num_entries starting from start_pos_map from kvmap_ into the database
void PutValues ( int start_pos_map , int num_entries , bool flush = true ) {
assert ( db_ttl_ ) ;
void PutValues ( int start_pos_map , int num_entries , bool flush = true ,
ColumnFamilyHandle * cf = nullptr ) {
ASSERT_TRUE ( db_ttl_ ) ;
ASSERT_LE ( start_pos_map + num_entries , ( int ) kvmap_ . size ( ) ) ;
static WriteOptions wopts ;
static FlushOptions flush_opts ;
kv_it_ = kvmap_ . begin ( ) ;
advance ( kv_it_ , start_pos_map ) ;
for ( int i = 0 ; kv_it_ ! = kvmap_ . end ( ) & & i < num_entries ; i + + , kv_it_ + + ) {
ASSERT_OK ( db_ttl_ - > Put ( wopts , kv_it_ - > first , kv_it_ - > second ) ) ;
ASSERT_OK ( cf = = nullptr
? db_ttl_ - > Put ( wopts , kv_it_ - > first , kv_it_ - > second )
: db_ttl_ - > Put ( wopts , cf , kv_it_ - > first , kv_it_ - > second ) ) ;
}
// Put a mock kv at the end because CompactionFilter doesn't delete last key
ASSERT_OK ( db_ttl_ - > Put ( wopts , " keymock " , " valuemock " ) ) ;
ASSERT_OK ( cf = = nullptr ? db_ttl_ - > Put ( wopts , " keymock " , " valuemock " )
: db_ttl_ - > Put ( wopts , cf , " keymock " , " valuemock " ) ) ;
if ( flush ) {
db_ttl_ - > Flush ( flush_opts ) ;
if ( cf = = nullptr ) {
db_ttl_ - > Flush ( flush_opts ) ;
} else {
db_ttl_ - > Flush ( flush_opts , cf ) ;
}
}
}
// Runs a manual compaction
void ManualCompact ( ) {
db_ttl_ - > CompactRange ( nullptr , nullptr ) ;
void ManualCompact ( ColumnFamilyHandle * cf = nullptr ) {
if ( cf = = nullptr ) {
db_ttl_ - > CompactRange ( nullptr , nullptr ) ;
} else {
db_ttl_ - > CompactRange ( cf , nullptr , nullptr ) ;
}
}
// checks the whole kvmap_ to return correct values using KeyMayExist
@ -151,12 +164,12 @@ class TtlTest {
if ( ret = = false | | value_found = = false ) {
fprintf ( stderr , " KeyMayExist could not find key=%s in the database but "
" should have \n " , kv . first . c_str ( ) ) ;
assert ( false ) ;
ASSERT_TRUE ( false ) ;
} else if ( val . compare ( kv . second ) ! = 0 ) {
fprintf ( stderr , " value for key=%s present in database is %s but "
" should be %s \n " , kv . first . c_str ( ) , val . c_str ( ) ,
kv . second . c_str ( ) ) ;
assert ( false ) ;
ASSERT_TRUE ( false ) ;
}
}
}
@ -167,16 +180,18 @@ class TtlTest {
// Also checks that value that we got is the same as inserted; and =kNewValue
// if test_compaction_change is true
void SleepCompactCheck ( int slp_tim , int st_pos , int span , bool check = true ,
bool test_compaction_change = false ) {
assert ( db_ttl_ ) ;
bool test_compaction_change = false ,
ColumnFamilyHandle * cf = nullptr ) {
ASSERT_TRUE ( db_ttl_ ) ;
sleep ( slp_tim ) ;
ManualCompact ( ) ;
ManualCompact ( cf ) ;
static ReadOptions ropts ;
kv_it_ = kvmap_ . begin ( ) ;
advance ( kv_it_ , st_pos ) ;
std : : string v ;
for ( int i = 0 ; kv_it_ ! = kvmap_ . end ( ) & & i < span ; i + + , kv_it_ + + ) {
Status s = db_ttl_ - > Get ( ropts , kv_it_ - > first , & v ) ;
Status s = ( cf = = nullptr ) ? db_ttl_ - > Get ( ropts , kv_it_ - > first , & v )
: db_ttl_ - > Get ( ropts , cf , kv_it_ - > first , & v ) ;
if ( s . ok ( ) ! = check ) {
fprintf ( stderr , " key=%s " , kv_it_ - > first . c_str ( ) ) ;
if ( ! s . ok ( ) ) {
@ -184,18 +199,18 @@ class TtlTest {
} else {
fprintf ( stderr , " is present in db but was expected to be absent \n " ) ;
}
assert ( false ) ;
ASSERT_TRUE ( false ) ;
} else if ( s . ok ( ) ) {
if ( test_compaction_change & & v . compare ( kNewValue_ ) ! = 0 ) {
fprintf ( stderr , " value for key=%s present in database is %s but "
" should be %s \n " , kv_it_ - > first . c_str ( ) , v . c_str ( ) ,
kNewValue_ . c_str ( ) ) ;
assert ( false ) ;
ASSERT_TRUE ( false ) ;
} else if ( ! test_compaction_change & & v . compare ( kv_it_ - > second ) ! = 0 ) {
fprintf ( stderr , " value for key=%s present in database is %s but "
" should be %s \n " , kv_it_ - > first . c_str ( ) , v . c_str ( ) ,
kv_it_ - > second . c_str ( ) ) ;
assert ( false ) ;
ASSERT_TRUE ( false ) ;
}
}
}
@ -203,7 +218,7 @@ class TtlTest {
// Similar as SleepCompactCheck but uses TtlIterator to read from db
void SleepCompactCheckIter ( int slp , int st_pos , int span , bool check = true ) {
assert ( db_ttl_ ) ;
ASSERT_TRUE ( db_ttl_ ) ;
sleep ( slp ) ;
ManualCompact ( ) ;
static ReadOptions ropts ;
@ -301,10 +316,10 @@ class TtlTest {
// Choose carefully so that Put, Gets & Compaction complete in 1 second buffer
const int64_t kSampleSize_ = 100 ;
private :
std : : string dbname_ ;
StackableDB * db_ttl_ ;
private :
Options options_ ;
KVMap kvmap_ ;
KVMap : : iterator kv_it_ ;
@ -496,6 +511,54 @@ TEST(TtlTest, KeyMayExist) {
CloseTtl ( ) ;
}
TEST ( TtlTest , ColumnFamiliesTest ) {
DB * db ;
Options options ;
options . create_if_missing = true ;
DB : : Open ( options , dbname_ , & db ) ;
ColumnFamilyHandle * handle ;
ASSERT_OK ( db - > CreateColumnFamily ( ColumnFamilyOptions ( options ) ,
" ttl_column_family " , & handle ) ) ;
delete handle ;
delete db ;
std : : vector < ColumnFamilyDescriptor > column_families ;
column_families . push_back ( ColumnFamilyDescriptor (
kDefaultColumnFamilyName , ColumnFamilyOptions ( options ) ) ) ;
column_families . push_back ( ColumnFamilyDescriptor (
" ttl_column_family " , ColumnFamilyOptions ( options ) ) ) ;
std : : vector < ColumnFamilyHandle * > handles ;
ASSERT_OK ( UtilityDB : : OpenTtlDB ( DBOptions ( options ) , dbname_ , column_families ,
& handles , & db_ttl_ , { 2 , 4 } , false ) ) ;
ASSERT_EQ ( handles . size ( ) , 2U ) ;
MakeKVMap ( kSampleSize_ ) ;
PutValues ( 0 , kSampleSize_ , false , handles [ 0 ] ) ;
PutValues ( 0 , kSampleSize_ , false , handles [ 1 ] ) ;
// everything should be there after 1 second
SleepCompactCheck ( 1 , 0 , kSampleSize_ , true , false , handles [ 0 ] ) ;
SleepCompactCheck ( 0 , 0 , kSampleSize_ , true , false , handles [ 1 ] ) ;
// only column family 1 should be alive after 3 seconds
SleepCompactCheck ( 2 , 0 , kSampleSize_ , false , false , handles [ 0 ] ) ;
SleepCompactCheck ( 0 , 0 , kSampleSize_ , true , false , handles [ 1 ] ) ;
// nothing should be there after 5 seconds
SleepCompactCheck ( 2 , 0 , kSampleSize_ , false , false , handles [ 0 ] ) ;
SleepCompactCheck ( 0 , 0 , kSampleSize_ , false , false , handles [ 1 ] ) ;
for ( auto h : handles ) {
delete h ;
}
delete db_ttl_ ;
db_ttl_ = nullptr ;
}
} // namespace rocksdb
// A black-box test for the ttl wrapper around rocksdb