@ -185,7 +185,7 @@ class TestPlainTableReader : public PlainTableReader {
const Options & options , bool * expect_bloom_not_match )
const Options & options , bool * expect_bloom_not_match )
: PlainTableReader ( options , std : : move ( file ) , storage_options , icomparator ,
: PlainTableReader ( options , std : : move ( file ) , storage_options , icomparator ,
file_size , bloom_bits_per_key , hash_table_ratio ,
file_size , bloom_bits_per_key , hash_table_ratio ,
index_sparseness , table_properties ) ,
index_sparseness , table_properties , 2 * 1024 * 1024 ) ,
expect_bloom_not_match_ ( expect_bloom_not_match ) {
expect_bloom_not_match_ ( expect_bloom_not_match ) {
Status s = PopulateIndex ( const_cast < TableProperties * > ( table_properties ) ) ;
Status s = PopulateIndex ( const_cast < TableProperties * > ( table_properties ) ) ;
ASSERT_TRUE ( s . ok ( ) ) ;
ASSERT_TRUE ( s . ok ( ) ) ;
@ -206,13 +206,12 @@ extern const uint64_t kPlainTableMagicNumber;
class TestPlainTableFactory : public PlainTableFactory {
class TestPlainTableFactory : public PlainTableFactory {
public :
public :
explicit TestPlainTableFactory ( bool * expect_bloom_not_match ,
explicit TestPlainTableFactory ( bool * expect_bloom_not_match ,
uint32_t user_key_len =
uint32_t user_key_len , int bloom_bits_per_key ,
kPlainTableVariableLength ,
double hash_table_ratio ,
int bloom_bits_per_key = 0 ,
size_t index_sparseness ,
double hash_table_ratio = 0.75 ,
size_t huge_page_tlb_size )
size_t index_sparseness = 16 )
: PlainTableFactory ( user_key_len , user_key_len , hash_table_ratio ,
: PlainTableFactory ( user_key_len , user_key_len , hash_table_ratio ,
hash_table_ratio ) ,
index_sparseness , huge_page_tlb_size ) ,
bloom_bits_per_key_ ( bloom_bits_per_key ) ,
bloom_bits_per_key_ ( bloom_bits_per_key ) ,
hash_table_ratio_ ( hash_table_ratio ) ,
hash_table_ratio_ ( hash_table_ratio ) ,
index_sparseness_ ( index_sparseness ) ,
index_sparseness_ ( index_sparseness ) ,
@ -244,197 +243,209 @@ class TestPlainTableFactory : public PlainTableFactory {
} ;
} ;
TEST ( PlainTableDBTest , Flush ) {
TEST ( PlainTableDBTest , Flush ) {
for ( int bloom_bits = 0 ; bloom_bits < = 117 ; bloom_bits + = 117 ) {
for ( size_t huge_page_tlb_size = 0 ; huge_page_tlb_size < = 2 * 1024 * 1024 ;
for ( int total_order = 0 ; total_order < = 1 ; total_order + + ) {
huge_page_tlb_size + = 2 * 1024 * 1024 ) {
Options options = CurrentOptions ( ) ;
for ( int bloom_bits = 0 ; bloom_bits < = 117 ; bloom_bits + = 117 ) {
options . create_if_missing = true ;
for ( int total_order = 0 ; total_order < = 1 ; total_order + + ) {
// Set only one bucket to force bucket conflict.
Options options = CurrentOptions ( ) ;
// Test index interval for the same prefix to be 1, 2 and 4
options . create_if_missing = true ;
if ( total_order ) {
// Set only one bucket to force bucket conflict.
options . table_factory . reset (
// Test index interval for the same prefix to be 1, 2 and 4
NewTotalOrderPlainTableFactory ( 16 , bloom_bits , 2 ) ) ;
if ( total_order ) {
} else {
options . table_factory . reset ( NewTotalOrderPlainTableFactory (
options . table_factory . reset ( NewPlainTableFactory ( 16 , bloom_bits ) ) ;
16 , bloom_bits , 2 , huge_page_tlb_size ) ) ;
} else {
options . table_factory . reset ( NewPlainTableFactory (
16 , bloom_bits , 0.75 , 16 , huge_page_tlb_size ) ) ;
}
DestroyAndReopen ( & options ) ;
ASSERT_OK ( Put ( " 1000000000000foo " , " v1 " ) ) ;
ASSERT_OK ( Put ( " 0000000000000bar " , " v2 " ) ) ;
ASSERT_OK ( Put ( " 1000000000000foo " , " v3 " ) ) ;
dbfull ( ) - > TEST_FlushMemTable ( ) ;
TablePropertiesCollection ptc ;
reinterpret_cast < DB * > ( dbfull ( ) ) - > GetPropertiesOfAllTables ( & ptc ) ;
ASSERT_EQ ( 1U , ptc . size ( ) ) ;
auto row = ptc . begin ( ) ;
auto tp = row - > second ;
ASSERT_EQ ( total_order ? " 4 " : " 12 " , ( tp - > user_collected_properties ) . at (
" plain_table_hash_table_size " ) ) ;
ASSERT_EQ ( total_order ? " 9 " : " 0 " , ( tp - > user_collected_properties ) . at (
" plain_table_sub_index_size " ) ) ;
ASSERT_EQ ( " v3 " , Get ( " 1000000000000foo " ) ) ;
ASSERT_EQ ( " v2 " , Get ( " 0000000000000bar " ) ) ;
}
}
DestroyAndReopen ( & options ) ;
ASSERT_OK ( Put ( " 1000000000000foo " , " v1 " ) ) ;
ASSERT_OK ( Put ( " 0000000000000bar " , " v2 " ) ) ;
ASSERT_OK ( Put ( " 1000000000000foo " , " v3 " ) ) ;
dbfull ( ) - > TEST_FlushMemTable ( ) ;
TablePropertiesCollection ptc ;
reinterpret_cast < DB * > ( dbfull ( ) ) - > GetPropertiesOfAllTables ( & ptc ) ;
ASSERT_EQ ( 1U , ptc . size ( ) ) ;
auto row = ptc . begin ( ) ;
auto tp = row - > second ;
ASSERT_EQ (
total_order ? " 4 " : " 12 " ,
( tp - > user_collected_properties ) . at ( " plain_table_hash_table_size " ) ) ;
ASSERT_EQ (
total_order ? " 9 " : " 0 " ,
( tp - > user_collected_properties ) . at ( " plain_table_sub_index_size " ) ) ;
ASSERT_EQ ( " v3 " , Get ( " 1000000000000foo " ) ) ;
ASSERT_EQ ( " v2 " , Get ( " 0000000000000bar " ) ) ;
}
}
}
}
}
}
TEST ( PlainTableDBTest , Flush2 ) {
TEST ( PlainTableDBTest , Flush2 ) {
for ( int bloom_bits = 0 ; bloom_bits < = 117 ; bloom_bits + = 117 ) {
for ( size_t huge_page_tlb_size = 0 ; huge_page_tlb_size < = 2 * 1024 * 1024 ;
for ( int total_order = 0 ; total_order < = 1 ; total_order + + ) {
huge_page_tlb_size + = 2 * 1024 * 1024 ) {
bool expect_bloom_not_match = false ;
for ( int bloom_bits = 0 ; bloom_bits < = 117 ; bloom_bits + = 117 ) {
Options options = CurrentOptions ( ) ;
for ( int total_order = 0 ; total_order < = 1 ; total_order + + ) {
options . create_if_missing = true ;
bool expect_bloom_not_match = false ;
// Set only one bucket to force bucket conflict.
Options options = CurrentOptions ( ) ;
// Test index interval for the same prefix to be 1, 2 and 4
options . create_if_missing = true ;
if ( total_order ) {
// Set only one bucket to force bucket conflict.
options . prefix_extractor = nullptr ;
// Test index interval for the same prefix to be 1, 2 and 4
options . table_factory . reset ( new TestPlainTableFactory (
& expect_bloom_not_match , 16 , bloom_bits , 0 , 2 ) ) ;
} else {
options . table_factory . reset (
new TestPlainTableFactory ( & expect_bloom_not_match , 16 , bloom_bits ) ) ;
}
DestroyAndReopen ( & options ) ;
ASSERT_OK ( Put ( " 0000000000000bar " , " b " ) ) ;
ASSERT_OK ( Put ( " 1000000000000foo " , " v1 " ) ) ;
dbfull ( ) - > TEST_FlushMemTable ( ) ;
ASSERT_OK ( Put ( " 1000000000000foo " , " v2 " ) ) ;
dbfull ( ) - > TEST_FlushMemTable ( ) ;
ASSERT_EQ ( " v2 " , Get ( " 1000000000000foo " ) ) ;
ASSERT_OK ( Put ( " 0000000000000eee " , " v3 " ) ) ;
dbfull ( ) - > TEST_FlushMemTable ( ) ;
ASSERT_EQ ( " v3 " , Get ( " 0000000000000eee " ) ) ;
ASSERT_OK ( Delete ( " 0000000000000bar " ) ) ;
dbfull ( ) - > TEST_FlushMemTable ( ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 0000000000000bar " ) ) ;
ASSERT_OK ( Put ( " 0000000000000eee " , " v5 " ) ) ;
ASSERT_OK ( Put ( " 9000000000000eee " , " v5 " ) ) ;
dbfull ( ) - > TEST_FlushMemTable ( ) ;
ASSERT_EQ ( " v5 " , Get ( " 0000000000000eee " ) ) ;
// Test Bloom Filter
if ( bloom_bits > 0 ) {
// Neither key nor value should exist.
expect_bloom_not_match = true ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 5_not00000000bar " ) ) ;
// Key doesn't exist any more but prefix exists.
if ( total_order ) {
if ( total_order ) {
ASSERT_EQ ( " NOT_FOUND " , Get ( " 1000000000000not " ) ) ;
options . prefix_extractor = nullptr ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 0000000000000not " ) ) ;
options . table_factory . reset (
new TestPlainTableFactory ( & expect_bloom_not_match , 16 , bloom_bits ,
0 , 2 , huge_page_tlb_size ) ) ;
} else {
options . table_factory . reset (
new TestPlainTableFactory ( & expect_bloom_not_match , 16 , bloom_bits ,
0.75 , 16 , huge_page_tlb_size ) ) ;
}
DestroyAndReopen ( & options ) ;
ASSERT_OK ( Put ( " 0000000000000bar " , " b " ) ) ;
ASSERT_OK ( Put ( " 1000000000000foo " , " v1 " ) ) ;
dbfull ( ) - > TEST_FlushMemTable ( ) ;
ASSERT_OK ( Put ( " 1000000000000foo " , " v2 " ) ) ;
dbfull ( ) - > TEST_FlushMemTable ( ) ;
ASSERT_EQ ( " v2 " , Get ( " 1000000000000foo " ) ) ;
ASSERT_OK ( Put ( " 0000000000000eee " , " v3 " ) ) ;
dbfull ( ) - > TEST_FlushMemTable ( ) ;
ASSERT_EQ ( " v3 " , Get ( " 0000000000000eee " ) ) ;
ASSERT_OK ( Delete ( " 0000000000000bar " ) ) ;
dbfull ( ) - > TEST_FlushMemTable ( ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 0000000000000bar " ) ) ;
ASSERT_OK ( Put ( " 0000000000000eee " , " v5 " ) ) ;
ASSERT_OK ( Put ( " 9000000000000eee " , " v5 " ) ) ;
dbfull ( ) - > TEST_FlushMemTable ( ) ;
ASSERT_EQ ( " v5 " , Get ( " 0000000000000eee " ) ) ;
// Test Bloom Filter
if ( bloom_bits > 0 ) {
// Neither key nor value should exist.
expect_bloom_not_match = true ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 5_not00000000bar " ) ) ;
// Key doesn't exist any more but prefix exists.
if ( total_order ) {
ASSERT_EQ ( " NOT_FOUND " , Get ( " 1000000000000not " ) ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 0000000000000not " ) ) ;
}
expect_bloom_not_match = false ;
}
}
expect_bloom_not_match = false ;
}
}
}
}
}
}
}
}
TEST ( PlainTableDBTest , Iterator ) {
TEST ( PlainTableDBTest , Iterator ) {
for ( int bloom_bits = 0 ; bloom_bits < = 117 ; bloom_bits + = 117 ) {
for ( size_t huge_page_tlb_size = 0 ; huge_page_tlb_size < = 2 * 1024 * 1024 ;
for ( int total_order = 0 ; total_order < = 1 ; total_order + + ) {
huge_page_tlb_size + = 2 * 1024 * 1024 ) {
bool expect_bloom_not_match = false ;
for ( int bloom_bits = 0 ; bloom_bits < = 117 ; bloom_bits + = 117 ) {
Options options = CurrentOptions ( ) ;
for ( int total_order = 0 ; total_order < = 1 ; total_order + + ) {
options . create_if_missing = true ;
bool expect_bloom_not_match = false ;
// Set only one bucket to force bucket conflict.
Options options = CurrentOptions ( ) ;
// Test index interval for the same prefix to be 1, 2 and 4
options . create_if_missing = true ;
if ( total_order ) {
// Set only one bucket to force bucket conflict.
options . prefix_extractor = nullptr ;
// Test index interval for the same prefix to be 1, 2 and 4
options . table_factory . reset ( new TestPlainTableFactory (
if ( total_order ) {
& expect_bloom_not_match , 16 , bloom_bits , 0 , 2 ) ) ;
options . prefix_extractor = nullptr ;
} else {
options . table_factory . reset (
options . table_factory . reset (
new TestPlainTableFactory ( & expect_bloom_not_match , 16 , bloom_bits ,
new TestPlainTableFactory ( & expect_bloom_not_match , 16 , bloom_bits ) ) ;
0 , 2 , huge_page_tlb_size ) ) ;
}
} else {
DestroyAndReopen ( & options ) ;
options . table_factory . reset (
new TestPlainTableFactory ( & expect_bloom_not_match , 16 , bloom_bits ,
ASSERT_OK ( Put ( " 1000000000foo002 " , " v_2 " ) ) ;
0.75 , 16 , huge_page_tlb_size ) ) ;
ASSERT_OK ( Put ( " 0000000000000bar " , " random " ) ) ;
}
ASSERT_OK ( Put ( " 1000000000foo001 " , " v1 " ) ) ;
DestroyAndReopen ( & options ) ;
ASSERT_OK ( Put ( " 3000000000000bar " , " bar_v " ) ) ;
ASSERT_OK ( Put ( " 1000000000foo003 " , " v__3 " ) ) ;
ASSERT_OK ( Put ( " 1000000000foo002 " , " v_2 " ) ) ;
ASSERT_OK ( Put ( " 1000000000foo004 " , " v__4 " ) ) ;
ASSERT_OK ( Put ( " 0000000000000bar " , " random " ) ) ;
ASSERT_OK ( Put ( " 1000000000foo005 " , " v__5 " ) ) ;
ASSERT_OK ( Put ( " 1000000000foo001 " , " v1 " ) ) ;
ASSERT_OK ( Put ( " 1000000000foo007 " , " v__7 " ) ) ;
ASSERT_OK ( Put ( " 3000000000000bar " , " bar_v " ) ) ;
ASSERT_OK ( Put ( " 1000000000foo008 " , " v__8 " ) ) ;
ASSERT_OK ( Put ( " 1000000000foo003 " , " v__3 " ) ) ;
dbfull ( ) - > TEST_FlushMemTable ( ) ;
ASSERT_OK ( Put ( " 1000000000foo004 " , " v__4 " ) ) ;
ASSERT_EQ ( " v1 " , Get ( " 1000000000foo001 " ) ) ;
ASSERT_OK ( Put ( " 1000000000foo005 " , " v__5 " ) ) ;
ASSERT_EQ ( " v__3 " , Get ( " 1000000000foo003 " ) ) ;
ASSERT_OK ( Put ( " 1000000000foo007 " , " v__7 " ) ) ;
Iterator * iter = dbfull ( ) - > NewIterator ( ReadOptions ( ) ) ;
ASSERT_OK ( Put ( " 1000000000foo008 " , " v__8 " ) ) ;
iter - > Seek ( " 1000000000foo000 " ) ;
dbfull ( ) - > TEST_FlushMemTable ( ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " v1 " , Get ( " 1000000000foo001 " ) ) ;
ASSERT_EQ ( " 1000000000foo001 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " v__3 " , Get ( " 1000000000foo003 " ) ) ;
ASSERT_EQ ( " v1 " , iter - > value ( ) . ToString ( ) ) ;
Iterator * iter = dbfull ( ) - > NewIterator ( ReadOptions ( ) ) ;
iter - > Seek ( " 1000000000foo000 " ) ;
iter - > Next ( ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 1000000000foo001 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " 1000000000foo002 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " v1 " , iter - > value ( ) . ToString ( ) ) ;
ASSERT_EQ ( " v_2 " , iter - > value ( ) . ToString ( ) ) ;
iter - > Next ( ) ;
iter - > Next ( ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 1000000000foo003 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " 1000000000foo002 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " v__3 " , iter - > value ( ) . ToString ( ) ) ;
ASSERT_EQ ( " v_2 " , iter - > value ( ) . ToString ( ) ) ;
iter - > Next ( ) ;
iter - > Next ( ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 1000000000foo004 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " 1000000000foo003 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " v__4 " , iter - > value ( ) . ToString ( ) ) ;
ASSERT_EQ ( " v__3 " , iter - > value ( ) . ToString ( ) ) ;
iter - > Seek ( " 3000000000000bar " ) ;
iter - > Next ( ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 3000000000000bar " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " 1000000000foo004 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " bar_v " , iter - > value ( ) . ToString ( ) ) ;
ASSERT_EQ ( " v__4 " , iter - > value ( ) . ToString ( ) ) ;
iter - > Seek ( " 1000000000foo000 " ) ;
iter - > Seek ( " 3000000000000bar " ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 1000000000foo001 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " 3000000000000bar " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " v1 " , iter - > value ( ) . ToString ( ) ) ;
ASSERT_EQ ( " bar_ v" , iter - > value ( ) . ToString ( ) ) ;
iter - > Seek ( " 1000000000foo005 " ) ;
iter - > Seek ( " 1000000000foo000 " ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 1000000000foo005 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " 1000000000foo001 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " v__5 " , iter - > value ( ) . ToString ( ) ) ;
ASSERT_EQ ( " v1 " , iter - > value ( ) . ToString ( ) ) ;
iter - > Seek ( " 1000000000foo006 " ) ;
iter - > Seek ( " 1000000000foo005 " ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 1000000000foo007 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " 1000000000foo005 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " v__7 " , iter - > value ( ) . ToString ( ) ) ;
ASSERT_EQ ( " v__5 " , iter - > value ( ) . ToString ( ) ) ;
iter - > Seek ( " 1000000000foo008 " ) ;
iter - > Seek ( " 1000000000foo006 " ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 1000000000foo008 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " 1000000000foo007 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " v__8 " , iter - > value ( ) . ToString ( ) ) ;
ASSERT_EQ ( " v__7 " , iter - > value ( ) . ToString ( ) ) ;
if ( total_order = = 0 ) {
iter - > Seek ( " 1000000000foo008 " ) ;
iter - > Seek ( " 1000000000foo009 " ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 3000000000000bar " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " 1000000000foo008 " , iter - > key ( ) . ToString ( ) ) ;
}
ASSERT_EQ ( " v__8 " , iter - > value ( ) . ToString ( ) ) ;
// Test Bloom Filter
if ( total_order = = 0 ) {
if ( bloom_bits > 0 ) {
iter - > Seek ( " 1000000000foo009 " ) ;
if ( ! total_order ) {
ASSERT_TRUE ( iter - > Valid ( ) ) ;
// Neither key nor value should exist.
ASSERT_EQ ( " 3000000000000bar " , iter - > key ( ) . ToString ( ) ) ;
expect_bloom_not_match = true ;
iter - > Seek ( " 2not000000000bar " ) ;
ASSERT_TRUE ( ! iter - > Valid ( ) ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 2not000000000bar " ) ) ;
expect_bloom_not_match = false ;
} else {
expect_bloom_not_match = true ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 2not000000000bar " ) ) ;
expect_bloom_not_match = false ;
}
}
}
delete iter ;
// Test Bloom Filter
if ( bloom_bits > 0 ) {
if ( ! total_order ) {
// Neither key nor value should exist.
expect_bloom_not_match = true ;
iter - > Seek ( " 2not000000000bar " ) ;
ASSERT_TRUE ( ! iter - > Valid ( ) ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 2not000000000bar " ) ) ;
expect_bloom_not_match = false ;
} else {
expect_bloom_not_match = true ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 2not000000000bar " ) ) ;
expect_bloom_not_match = false ;
}
}
delete iter ;
}
}
}
}
}
}
}
@ -581,165 +592,173 @@ TEST(PlainTableDBTest, IteratorReverseSuffixComparator) {
}
}
TEST ( PlainTableDBTest , HashBucketConflict ) {
TEST ( PlainTableDBTest , HashBucketConflict ) {
for ( unsigned char i = 1 ; i < = 3 ; i + + ) {
for ( size_t huge_page_tlb_size = 0 ; huge_page_tlb_size < = 2 * 1024 * 1024 ;
Options options = CurrentOptions ( ) ;
huge_page_tlb_size + = 2 * 1024 * 1024 ) {
options . create_if_missing = true ;
for ( unsigned char i = 1 ; i < = 3 ; i + + ) {
// Set only one bucket to force bucket conflict.
Options options = CurrentOptions ( ) ;
// Test index interval for the same prefix to be 1, 2 and 4
options . create_if_missing = true ;
options . table_factory . reset ( NewTotalOrderPlainTableFactory ( 16 , 0 , 2 ^ i ) ) ;
// Set only one bucket to force bucket conflict.
DestroyAndReopen ( & options ) ;
// Test index interval for the same prefix to be 1, 2 and 4
ASSERT_OK ( Put ( " 5000000000000fo0 " , " v1 " ) ) ;
options . table_factory . reset (
ASSERT_OK ( Put ( " 5000000000000fo1 " , " v2 " ) ) ;
NewTotalOrderPlainTableFactory ( 16 , 0 , 2 ^ i , huge_page_tlb_size ) ) ;
ASSERT_OK ( Put ( " 5000000000000fo2 " , " v " ) ) ;
DestroyAndReopen ( & options ) ;
ASSERT_OK ( Put ( " 2000000000000fo0 " , " v3 " ) ) ;
ASSERT_OK ( Put ( " 5000000000000fo0 " , " v1 " ) ) ;
ASSERT_OK ( Put ( " 2000000000000fo1 " , " v4 " ) ) ;
ASSERT_OK ( Put ( " 5000000000000fo1 " , " v2 " ) ) ;
ASSERT_OK ( Put ( " 2000000000000fo2 " , " v " ) ) ;
ASSERT_OK ( Put ( " 5000000000000fo2 " , " v " ) ) ;
ASSERT_OK ( Put ( " 2000000000000fo3 " , " v " ) ) ;
ASSERT_OK ( Put ( " 2000000000000fo0 " , " v3 " ) ) ;
ASSERT_OK ( Put ( " 2000000000000fo1 " , " v4 " ) ) ;
dbfull ( ) - > TEST_FlushMemTable ( ) ;
ASSERT_OK ( Put ( " 2000000000000fo2 " , " v " ) ) ;
ASSERT_OK ( Put ( " 2000000000000fo3 " , " v " ) ) ;
ASSERT_EQ ( " v1 " , Get ( " 5000000000000fo0 " ) ) ;
ASSERT_EQ ( " v2 " , Get ( " 5000000000000fo1 " ) ) ;
ASSERT_EQ ( " v3 " , Get ( " 2000000000000fo0 " ) ) ;
ASSERT_EQ ( " v4 " , Get ( " 2000000000000fo1 " ) ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 5000000000000bar " ) ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 2000000000000bar " ) ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 5000000000000fo8 " ) ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 2000000000000fo8 " ) ) ;
ReadOptions ro ;
Iterator * iter = dbfull ( ) - > NewIterator ( ro ) ;
iter - > Seek ( " 5000000000000fo0 " ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 5000000000000fo0 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Next ( ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 5000000000000fo1 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Seek ( " 5000000000000fo1 " ) ;
dbfull ( ) - > TEST_FlushMemTable ( ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 5000000000000fo1 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Seek ( " 2000000000000fo0 " ) ;
ASSERT_EQ ( " v1 " , Get ( " 5000000000000fo0 " ) ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " v2 " , Get ( " 5000000000000fo1 " ) ) ;
ASSERT_EQ ( " 2000000000000fo0 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " v3 " , Get ( " 2000000000000fo0 " ) ) ;
iter - > Next ( ) ;
ASSERT_EQ ( " v4 " , Get ( " 2000000000000fo1 " ) ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 2000000000000fo1 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Seek ( " 2000000000000fo1 " ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 5000000000000bar " ) ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 2000000000000bar " ) ) ;
ASSERT_EQ ( " 2000000000000fo1 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 5000000000000fo8 " ) ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 2000000000000fo8 " ) ) ;
iter - > Seek ( " 2000000000000bar " ) ;
ReadOptions ro ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
Iterator * iter = dbfull ( ) - > NewIterator ( ro ) ;
ASSERT_EQ ( " 2000000000000fo0 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Seek ( " 5000000000000bar " ) ;
iter - > Seek ( " 5000000000000fo0 " ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 5000000000000fo0 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " 5000000000000fo0 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Next ( ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 5000000000000fo1 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Seek ( " 5000000000000fo1 " ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 5000000000000fo1 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Seek ( " 2000000000000fo8 " ) ;
iter - > Seek ( " 2000000000000fo0 " ) ;
ASSERT_TRUE ( ! iter - > Valid ( ) | |
ASSERT_TRUE ( iter - > Valid ( ) ) ;
options . comparator - > Compare ( iter - > key ( ) , " 20000001 " ) > 0 ) ;
ASSERT_EQ ( " 2000000000000fo0 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Next ( ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 2000000000000fo1 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Seek ( " 2000000000000fo1 " ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 2000000000000fo1 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Seek ( " 2000000000000bar " ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 2000000000000fo0 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Seek ( " 5000000000000bar " ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 5000000000000fo0 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Seek ( " 5000000000000fo8 " ) ;
iter - > Seek ( " 2000000000000fo8 " ) ;
ASSERT_TRUE ( ! iter - > Valid ( ) ) ;
ASSERT_TRUE ( ! iter - > Valid ( ) | |
options . comparator - > Compare ( iter - > key ( ) , " 20000001 " ) > 0 ) ;
iter - > Seek ( " 1000000000000fo2 " ) ;
iter - > Seek ( " 5000000000000fo8 " ) ;
ASSERT_TRUE ( ! iter - > Valid ( ) ) ;
ASSERT_TRUE ( ! iter - > Valid ( ) ) ;
iter - > Seek ( " 3000000000000fo2 " ) ;
iter - > Seek ( " 1 000000000000fo2" ) ;
ASSERT_TRUE ( ! iter - > Valid ( ) ) ;
ASSERT_TRUE ( ! iter - > Valid ( ) ) ;
iter - > Seek ( " 8000000000000fo2 " ) ;
iter - > Seek ( " 3 000000000000fo2" ) ;
ASSERT_TRUE ( ! iter - > Valid ( ) ) ;
ASSERT_TRUE ( ! iter - > Valid ( ) ) ;
delete iter ;
iter - > Seek ( " 8000000000000fo2 " ) ;
ASSERT_TRUE ( ! iter - > Valid ( ) ) ;
delete iter ;
}
}
}
}
}
TEST ( PlainTableDBTest , HashBucketConflictReverseSuffixComparator ) {
TEST ( PlainTableDBTest , HashBucketConflictReverseSuffixComparator ) {
for ( unsigned char i = 1 ; i < = 3 ; i + + ) {
for ( size_t huge_page_tlb_size = 0 ; huge_page_tlb_size < = 2 * 1024 * 1024 ;
Options options = CurrentOptions ( ) ;
huge_page_tlb_size + = 2 * 1024 * 1024 ) {
options . create_if_missing = true ;
for ( unsigned char i = 1 ; i < = 3 ; i + + ) {
SimpleSuffixReverseComparator comp ;
Options options = CurrentOptions ( ) ;
options . comparator = & comp ;
options . create_if_missing = true ;
// Set only one bucket to force bucket conflict.
SimpleSuffixReverseComparator comp ;
// Test index interval for the same prefix to be 1, 2 and 4
options . comparator = & comp ;
options . table_factory . reset ( NewTotalOrderPlainTableFactory ( 16 , 0 , 2 ^ i ) ) ;
// Set only one bucket to force bucket conflict.
DestroyAndReopen ( & options ) ;
// Test index interval for the same prefix to be 1, 2 and 4
ASSERT_OK ( Put ( " 5000000000000fo0 " , " v1 " ) ) ;
options . table_factory . reset (
ASSERT_OK ( Put ( " 5000000000000fo1 " , " v2 " ) ) ;
NewTotalOrderPlainTableFactory ( 16 , 0 , 2 ^ i , huge_page_tlb_size ) ) ;
ASSERT_OK ( Put ( " 5000000000000fo2 " , " v " ) ) ;
DestroyAndReopen ( & options ) ;
ASSERT_OK ( Put ( " 2000000000000fo0 " , " v3 " ) ) ;
ASSERT_OK ( Put ( " 5000000000000fo0 " , " v1 " ) ) ;
ASSERT_OK ( Put ( " 2000000000000fo1 " , " v4 " ) ) ;
ASSERT_OK ( Put ( " 5000000000000fo1 " , " v2 " ) ) ;
ASSERT_OK ( Put ( " 2000000000000fo2 " , " v " ) ) ;
ASSERT_OK ( Put ( " 5000000000000fo2 " , " v " ) ) ;
ASSERT_OK ( Put ( " 2000000000000fo3 " , " v " ) ) ;
ASSERT_OK ( Put ( " 2000000000000fo0 " , " v3 " ) ) ;
ASSERT_OK ( Put ( " 2000000000000fo1 " , " v4 " ) ) ;
dbfull ( ) - > TEST_FlushMemTable ( ) ;
ASSERT_OK ( Put ( " 2000000000000fo2 " , " v " ) ) ;
ASSERT_OK ( Put ( " 2000000000000fo3 " , " v " ) ) ;
ASSERT_EQ ( " v1 " , Get ( " 5000000000000fo0 " ) ) ;
ASSERT_EQ ( " v2 " , Get ( " 5000000000000fo1 " ) ) ;
ASSERT_EQ ( " v3 " , Get ( " 2000000000000fo0 " ) ) ;
ASSERT_EQ ( " v4 " , Get ( " 2000000000000fo1 " ) ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 5000000000000bar " ) ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 2000000000000bar " ) ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 5000000000000fo8 " ) ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 2000000000000fo8 " ) ) ;
ReadOptions ro ;
Iterator * iter = dbfull ( ) - > NewIterator ( ro ) ;
iter - > Seek ( " 5000000000000fo1 " ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 5000000000000fo1 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Next ( ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 5000000000000fo0 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Seek ( " 5000000000000fo1 " ) ;
dbfull ( ) - > TEST_FlushMemTable ( ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 5000000000000fo1 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Seek ( " 2000000000000fo1 " ) ;
ASSERT_EQ ( " v1 " , Get ( " 5000000000000fo0 " ) ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " v2 " , Get ( " 5000000000000fo1 " ) ) ;
ASSERT_EQ ( " 2000000000000fo1 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " v3 " , Get ( " 2000000000000fo0 " ) ) ;
iter - > Next ( ) ;
ASSERT_EQ ( " v4 " , Get ( " 2000000000000fo1 " ) ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 2000000000000fo0 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Seek ( " 2000000000000fo1 " ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 5000000000000bar " ) ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 2000000000000bar " ) ) ;
ASSERT_EQ ( " 2000000000000fo1 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 5000000000000fo8 " ) ) ;
ASSERT_EQ ( " NOT_FOUND " , Get ( " 2000000000000fo8 " ) ) ;
iter - > Seek ( " 2000000000000var " ) ;
ReadOptions ro ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
Iterator * iter = dbfull ( ) - > NewIterator ( ro ) ;
ASSERT_EQ ( " 2000000000000fo3 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Seek ( " 5000000000000var " ) ;
iter - > Seek ( " 5000000000000fo1 " ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 5000000000000fo2 " , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( " 5000000000000fo1 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Next ( ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 5000000000000fo0 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Seek ( " 5000000000000fo1 " ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 5000000000000fo1 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Seek ( " 2000000000000fo1 " ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 2000000000000fo1 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Next ( ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 2000000000000fo0 " , iter - > key ( ) . ToString ( ) ) ;
std : : string seek_key = " 2000000000000bar " ;
iter - > Seek ( " 2000000000000fo1 " ) ;
iter - > Seek ( seek_key ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_TRUE ( ! iter - > Valid ( ) | |
ASSERT_EQ ( " 2000000000000fo1 " , iter - > key ( ) . ToString ( ) ) ;
options . prefix_extractor - > Transform ( iter - > key ( ) ) ! =
options . prefix_extractor - > Transform ( seek_key ) ) ;
iter - > Seek ( " 1000000000000fo2 " ) ;
iter - > Seek ( " 2000000000000var " ) ;
ASSERT_TRUE ( ! iter - > Valid ( ) ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 2000000000000fo3 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Seek ( " 5000000000000var " ) ;
ASSERT_TRUE ( iter - > Valid ( ) ) ;
ASSERT_EQ ( " 5000000000000fo2 " , iter - > key ( ) . ToString ( ) ) ;
iter - > Seek ( " 3000000000000fo2 " ) ;
std : : string seek_key = " 2000000000000bar " ;
ASSERT_TRUE ( ! iter - > Valid ( ) ) ;
iter - > Seek ( seek_key ) ;
ASSERT_TRUE ( ! iter - > Valid ( ) | |
options . prefix_extractor - > Transform ( iter - > key ( ) ) ! =
options . prefix_extractor - > Transform ( seek_key ) ) ;
iter - > Seek ( " 8000000000000fo2 " ) ;
iter - > Seek ( " 1 000000000000fo2" ) ;
ASSERT_TRUE ( ! iter - > Valid ( ) ) ;
ASSERT_TRUE ( ! iter - > Valid ( ) ) ;
delete iter ;
iter - > Seek ( " 3000000000000fo2 " ) ;
ASSERT_TRUE ( ! iter - > Valid ( ) ) ;
iter - > Seek ( " 8000000000000fo2 " ) ;
ASSERT_TRUE ( ! iter - > Valid ( ) ) ;
delete iter ;
}
}
}
}
}