@ -40,8 +40,10 @@ class ExternalSSTFileBasicTest : public DBTestBase {
}
}
Status GenerateAndAddExternalFile (
Status GenerateAndAddExternalFile (
const Options options , std : : vector < int > keys , int file_id ,
const Options options , std : : vector < int > keys ,
const std : : vector < ValueType > & value_types , int file_id ,
std : : map < std : : string , std : : string > * true_data ) {
std : : map < std : : string , std : : string > * true_data ) {
assert ( value_types . size ( ) = = 1 | | keys . size ( ) = = value_types . size ( ) ) ;
std : : string file_path = sst_files_dir_ + ToString ( file_id ) ;
std : : string file_path = sst_files_dir_ + ToString ( file_id ) ;
SstFileWriter sst_file_writer ( EnvOptions ( ) , options ) ;
SstFileWriter sst_file_writer ( EnvOptions ( ) , options ) ;
@ -49,11 +51,28 @@ class ExternalSSTFileBasicTest : public DBTestBase {
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
return s ;
return s ;
}
}
for ( int k : keys ) {
for ( size_t i = 0 ; i < keys . size ( ) ; i + + ) {
std : : string key = Key ( k ) ;
std : : string key = Key ( keys [ i ] ) ;
std : : string value = Key ( k ) + ToString ( file_id ) ;
std : : string value = Key ( keys [ i ] ) + ToString ( file_id ) ;
s = sst_file_writer . Add ( key , value ) ;
ValueType value_type =
( * true_data ) [ key ] = value ;
( value_types . size ( ) = = 1 ? value_types [ 0 ] : value_types [ i ] ) ;
switch ( value_type ) {
case ValueType : : kTypeValue :
s = sst_file_writer . Put ( key , value ) ;
( * true_data ) [ key ] = value ;
break ;
case ValueType : : kTypeMerge :
s = sst_file_writer . Merge ( key , value ) ;
// we only use TestPutOperator in this test
( * true_data ) [ key ] = value ;
break ;
case ValueType : : kTypeDeletion :
s = sst_file_writer . Delete ( key ) ;
true_data - > erase ( key ) ;
break ;
default :
return Status : : InvalidArgument ( " Value type is not supported " ) ;
}
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
sst_file_writer . Finish ( ) ;
sst_file_writer . Finish ( ) ;
return s ;
return s ;
@ -66,10 +85,17 @@ class ExternalSSTFileBasicTest : public DBTestBase {
ifo . allow_global_seqno = true ;
ifo . allow_global_seqno = true ;
s = db_ - > IngestExternalFile ( { file_path } , ifo ) ;
s = db_ - > IngestExternalFile ( { file_path } , ifo ) ;
}
}
return s ;
return s ;
}
}
Status GenerateAndAddExternalFile (
const Options options , std : : vector < int > keys , const ValueType value_type ,
int file_id , std : : map < std : : string , std : : string > * true_data ) {
return GenerateAndAddExternalFile ( options , keys ,
std : : vector < ValueType > ( 1 , value_type ) ,
file_id , true_data ) ;
}
~ ExternalSSTFileBasicTest ( ) { test : : DestroyDir ( env_ , sst_files_dir_ ) ; }
~ ExternalSSTFileBasicTest ( ) { test : : DestroyDir ( env_ , sst_files_dir_ ) ; }
protected :
protected :
@ -89,7 +115,7 @@ TEST_F(ExternalSSTFileBasicTest, Basic) {
std : : string file1 = sst_files_dir_ + " file1.sst " ;
std : : string file1 = sst_files_dir_ + " file1.sst " ;
ASSERT_OK ( sst_file_writer . Open ( file1 ) ) ;
ASSERT_OK ( sst_file_writer . Open ( file1 ) ) ;
for ( int k = 0 ; k < 100 ; k + + ) {
for ( int k = 0 ; k < 100 ; k + + ) {
ASSERT_OK ( sst_file_writer . Add ( Key ( k ) , Key ( k ) + " _val " ) ) ;
ASSERT_OK ( sst_file_writer . Put ( Key ( k ) , Key ( k ) + " _val " ) ) ;
}
}
ExternalSstFileInfo file1_info ;
ExternalSstFileInfo file1_info ;
Status s = sst_file_writer . Finish ( & file1_info ) ;
Status s = sst_file_writer . Finish ( & file1_info ) ;
@ -103,7 +129,7 @@ TEST_F(ExternalSSTFileBasicTest, Basic) {
ASSERT_EQ ( file1_info . smallest_key , Key ( 0 ) ) ;
ASSERT_EQ ( file1_info . smallest_key , Key ( 0 ) ) ;
ASSERT_EQ ( file1_info . largest_key , Key ( 99 ) ) ;
ASSERT_EQ ( file1_info . largest_key , Key ( 99 ) ) ;
// sst_file_writer already finished, cannot add this value
// sst_file_writer already finished, cannot add this value
s = sst_file_writer . Add ( Key ( 100 ) , " bad_val " ) ;
s = sst_file_writer . Put ( Key ( 100 ) , " bad_val " ) ;
ASSERT_FALSE ( s . ok ( ) ) < < s . ToString ( ) ;
ASSERT_FALSE ( s . ok ( ) ) < < s . ToString ( ) ;
DestroyAndReopen ( options ) ;
DestroyAndReopen ( options ) ;
@ -128,7 +154,7 @@ TEST_F(ExternalSSTFileBasicTest, NoCopy) {
std : : string file1 = sst_files_dir_ + " file1.sst " ;
std : : string file1 = sst_files_dir_ + " file1.sst " ;
ASSERT_OK ( sst_file_writer . Open ( file1 ) ) ;
ASSERT_OK ( sst_file_writer . Open ( file1 ) ) ;
for ( int k = 0 ; k < 100 ; k + + ) {
for ( int k = 0 ; k < 100 ; k + + ) {
ASSERT_OK ( sst_file_writer . Add ( Key ( k ) , Key ( k ) + " _val " ) ) ;
ASSERT_OK ( sst_file_writer . Put ( Key ( k ) , Key ( k ) + " _val " ) ) ;
}
}
ExternalSstFileInfo file1_info ;
ExternalSstFileInfo file1_info ;
Status s = sst_file_writer . Finish ( & file1_info ) ;
Status s = sst_file_writer . Finish ( & file1_info ) ;
@ -142,7 +168,7 @@ TEST_F(ExternalSSTFileBasicTest, NoCopy) {
std : : string file2 = sst_files_dir_ + " file2.sst " ;
std : : string file2 = sst_files_dir_ + " file2.sst " ;
ASSERT_OK ( sst_file_writer . Open ( file2 ) ) ;
ASSERT_OK ( sst_file_writer . Open ( file2 ) ) ;
for ( int k = 100 ; k < 300 ; k + + ) {
for ( int k = 100 ; k < 300 ; k + + ) {
ASSERT_OK ( sst_file_writer . Add ( Key ( k ) , Key ( k ) + " _val " ) ) ;
ASSERT_OK ( sst_file_writer . Put ( Key ( k ) , Key ( k ) + " _val " ) ) ;
}
}
ExternalSstFileInfo file2_info ;
ExternalSstFileInfo file2_info ;
s = sst_file_writer . Finish ( & file2_info ) ;
s = sst_file_writer . Finish ( & file2_info ) ;
@ -156,7 +182,7 @@ TEST_F(ExternalSSTFileBasicTest, NoCopy) {
std : : string file3 = sst_files_dir_ + " file3.sst " ;
std : : string file3 = sst_files_dir_ + " file3.sst " ;
ASSERT_OK ( sst_file_writer . Open ( file3 ) ) ;
ASSERT_OK ( sst_file_writer . Open ( file3 ) ) ;
for ( int k = 110 ; k < 125 ; k + + ) {
for ( int k = 110 ; k < 125 ; k + + ) {
ASSERT_OK ( sst_file_writer . Add ( Key ( k ) , Key ( k ) + " _val_overlap " ) ) ;
ASSERT_OK ( sst_file_writer . Put ( Key ( k ) , Key ( k ) + " _val_overlap " ) ) ;
}
}
ExternalSstFileInfo file3_info ;
ExternalSstFileInfo file3_info ;
s = sst_file_writer . Finish ( & file3_info ) ;
s = sst_file_writer . Finish ( & file3_info ) ;
@ -191,33 +217,36 @@ TEST_F(ExternalSSTFileBasicTest, IngestFileWithGlobalSeqnoPickedSeqno) {
int file_id = 1 ;
int file_id = 1 ;
ASSERT_OK ( GenerateAndAddExternalFile ( options , { 1 , 2 , 3 , 4 , 5 , 6 } , file_id + + ,
ASSERT_OK ( GenerateAndAddExternalFile ( options , { 1 , 2 , 3 , 4 , 5 , 6 } ,
ValueType : : kTypeValue , file_id + + ,
& true_data ) ) ;
& true_data ) ) ;
// File dont overwrite any keys, No seqno needed
// File dont overwrite any keys, No seqno needed
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 0 ) ;
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 0 ) ;
ASSERT_OK ( GenerateAndAddExternalFile ( options , { 10 , 11 , 12 , 13 } , file_id + + ,
ASSERT_OK ( GenerateAndAddExternalFile ( options , { 10 , 11 , 12 , 13 } ,
ValueType : : kTypeValue , file_id + + ,
& true_data ) ) ;
& true_data ) ) ;
// File dont overwrite any keys, No seqno needed
// File dont overwrite any keys, No seqno needed
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 0 ) ;
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 0 ) ;
ASSERT_OK (
ASSERT_OK ( GenerateAndAddExternalFile (
GenerateAndAddExternalFile ( options , { 1 , 4 , 6 } , file_id + + , & true_data ) ) ;
options , { 1 , 4 , 6 } , ValueType : : kTypeValue , file_id + + , & true_data ) ) ;
// File overwrite some keys, a seqno will be assigned
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 1 ) ;
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 1 ) ;
ASSERT_OK ( GenerateAndAddExternalFile ( options , { 11 , 15 , 19 } , file_id + + ,
ASSERT_OK ( GenerateAndAddExternalFile (
& true_data ) ) ;
options , { 11 , 15 , 19 } , ValueType : : kTypeValue , file_id + + , & true_data ) ) ;
// File overwrite some keys, a seqno will be assigned
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 2 ) ;
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 2 ) ;
ASSERT_OK (
ASSERT_OK ( GenerateAndAddExternalFile (
GenerateAndAddExternalFile ( options , { 120 , 130 } , file_id + + , & true_data ) ) ;
options , { 120 , 130 } , ValueType : : kTypeValue , file_id + + , & true_data ) ) ;
// File dont overwrite any keys, No seqno needed
// File dont overwrite any keys, No seqno needed
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 2 ) ;
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 2 ) ;
ASSERT_OK (
ASSERT_OK ( GenerateAndAddExternalFile (
GenerateAndAddExternalFile ( options , { 1 , 130 } , file_id + + , & true_data ) ) ;
options , { 1 , 130 } , ValueType : : kTypeValue , file_id + + , & true_data ) ) ;
// File overwrite some keys, a seqno will be assigned
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 3 ) ;
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 3 ) ;
@ -228,17 +257,115 @@ TEST_F(ExternalSSTFileBasicTest, IngestFileWithGlobalSeqnoPickedSeqno) {
}
}
SequenceNumber last_seqno = dbfull ( ) - > GetLatestSequenceNumber ( ) ;
SequenceNumber last_seqno = dbfull ( ) - > GetLatestSequenceNumber ( ) ;
ASSERT_OK ( GenerateAndAddExternalFile ( options , { 60 , 61 , 62 } , file_id + + ,
ASSERT_OK ( GenerateAndAddExternalFile (
& true_data ) ) ;
options , { 60 , 61 , 62 } , ValueType : : kTypeValue , file_id + + , & true_data ) ) ;
// File dont overwrite any keys, No seqno needed
// File dont overwrite any keys, No seqno needed
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno ) ;
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno ) ;
ASSERT_OK ( GenerateAndAddExternalFile ( options , { 40 , 41 , 42 } , file_id + + ,
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 40 , 41 , 42 } , ValueType : : kTypeValue , file_id + + , & true_data ) ) ;
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 1 ) ;
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 20 , 30 , 40 } , ValueType : : kTypeValue , file_id + + , & true_data ) ) ;
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 2 ) ;
const Snapshot * snapshot = db_ - > GetSnapshot ( ) ;
// We will need a seqno for the file regardless if the file overwrite
// keys in the DB or not because we have a snapshot
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 1000 , 1002 } , ValueType : : kTypeValue , file_id + + , & true_data ) ) ;
// A global seqno will be assigned anyway because of the snapshot
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 3 ) ;
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 2000 , 3002 } , ValueType : : kTypeValue , file_id + + , & true_data ) ) ;
// A global seqno will be assigned anyway because of the snapshot
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 4 ) ;
ASSERT_OK ( GenerateAndAddExternalFile ( options , { 1 , 20 , 40 , 100 , 150 } ,
ValueType : : kTypeValue , file_id + + ,
& true_data ) ) ;
& true_data ) ) ;
// A global seqno will be assigned anyway because of the snapshot
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 5 ) ;
db_ - > ReleaseSnapshot ( snapshot ) ;
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 5000 , 5001 } , ValueType : : kTypeValue , file_id + + , & true_data ) ) ;
// No snapshot anymore, no need to assign a seqno
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 5 ) ;
size_t kcnt = 0 ;
VerifyDBFromMap ( true_data , & kcnt , false ) ;
} while ( ChangeCompactOptions ( ) ) ;
}
TEST_F ( ExternalSSTFileBasicTest , IngestFileWithMultipleValueType ) {
do {
Options options = CurrentOptions ( ) ;
options . merge_operator . reset ( new TestPutOperator ( ) ) ;
DestroyAndReopen ( options ) ;
std : : map < std : : string , std : : string > true_data ;
int file_id = 1 ;
ASSERT_OK ( GenerateAndAddExternalFile ( options , { 1 , 2 , 3 , 4 , 5 , 6 } ,
ValueType : : kTypeValue , file_id + + ,
& true_data ) ) ;
// File dont overwrite any keys, No seqno needed
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 0 ) ;
ASSERT_OK ( GenerateAndAddExternalFile ( options , { 10 , 11 , 12 , 13 } ,
ValueType : : kTypeValue , file_id + + ,
& true_data ) ) ;
// File dont overwrite any keys, No seqno needed
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 0 ) ;
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 1 , 4 , 6 } , ValueType : : kTypeMerge , file_id + + , & true_data ) ) ;
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 1 ) ;
ASSERT_OK ( GenerateAndAddExternalFile ( options , { 11 , 15 , 19 } ,
ValueType : : kTypeDeletion , file_id + + ,
& true_data ) ) ;
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 2 ) ;
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 120 , 130 } , ValueType : : kTypeMerge , file_id + + , & true_data ) ) ;
// File dont overwrite any keys, No seqno needed
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 2 ) ;
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 1 , 130 } , ValueType : : kTypeDeletion , file_id + + , & true_data ) ) ;
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 3 ) ;
// Write some keys through normal write path
for ( int i = 0 ; i < 50 ; i + + ) {
ASSERT_OK ( Put ( Key ( i ) , " memtable " ) ) ;
true_data [ Key ( i ) ] = " memtable " ;
}
SequenceNumber last_seqno = dbfull ( ) - > GetLatestSequenceNumber ( ) ;
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 60 , 61 , 62 } , ValueType : : kTypeValue , file_id + + , & true_data ) ) ;
// File dont overwrite any keys, No seqno needed
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno ) ;
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 40 , 41 , 42 } , ValueType : : kTypeMerge , file_id + + , & true_data ) ) ;
// File overwrite some keys, a seqno will be assigned
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 1 ) ;
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 1 ) ;
ASSERT_OK ( GenerateAndAddExternalFile ( options , { 20 , 30 , 40 } , file_id + + ,
ASSERT_OK ( GenerateAndAddExternalFile ( options , { 20 , 30 , 40 } ,
ValueType : : kTypeDeletion , file_id + + ,
& true_data ) ) ;
& true_data ) ) ;
// File overwrite some keys, a seqno will be assigned
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 2 ) ;
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 2 ) ;
@ -247,25 +374,143 @@ TEST_F(ExternalSSTFileBasicTest, IngestFileWithGlobalSeqnoPickedSeqno) {
// We will need a seqno for the file regardless if the file overwrite
// We will need a seqno for the file regardless if the file overwrite
// keys in the DB or not because we have a snapshot
// keys in the DB or not because we have a snapshot
ASSERT_OK ( GenerateAndAddExternalFile ( options , { 1000 , 1002 } , file_id + + ,
ASSERT_OK ( GenerateAndAddExternalFile (
& true_data ) ) ;
options , { 1000 , 1002 } , ValueType : : kTypeMerge , file_id + + , & true_data ) ) ;
// A global seqno will be assigned anyway because of the snapshot
// A global seqno will be assigned anyway because of the snapshot
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 3 ) ;
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 3 ) ;
ASSERT_OK ( GenerateAndAddExternalFile ( options , { 2000 , 3002 } , file_id + + ,
ASSERT_OK ( GenerateAndAddExternalFile (
& true_data ) ) ;
options , { 2000 , 3002 } , ValueType : : kTypeMerge , file_id + + , & true_data ) ) ;
// A global seqno will be assigned anyway because of the snapshot
// A global seqno will be assigned anyway because of the snapshot
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 4 ) ;
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 4 ) ;
ASSERT_OK ( GenerateAndAddExternalFile ( options , { 1 , 20 , 40 , 100 , 150 } ,
ASSERT_OK ( GenerateAndAddExternalFile ( options , { 1 , 20 , 40 , 100 , 150 } ,
file_id + + , & true_data ) ) ;
ValueType : : kTypeMerge , file_id + + ,
& true_data ) ) ;
// A global seqno will be assigned anyway because of the snapshot
// A global seqno will be assigned anyway because of the snapshot
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 5 ) ;
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 5 ) ;
db_ - > ReleaseSnapshot ( snapshot ) ;
db_ - > ReleaseSnapshot ( snapshot ) ;
ASSERT_OK ( GenerateAndAddExternalFile ( options , { 5000 , 5001 } , file_id + + ,
ASSERT_OK ( GenerateAndAddExternalFile (
& true_data ) ) ;
options , { 5000 , 5001 } , ValueType : : kTypeValue , file_id + + , & true_data ) ) ;
// No snapshot anymore, no need to assign a seqno
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 5 ) ;
size_t kcnt = 0 ;
VerifyDBFromMap ( true_data , & kcnt , false ) ;
} while ( ChangeCompactOptions ( ) ) ;
}
TEST_F ( ExternalSSTFileBasicTest , IngestFileWithMixedValueType ) {
do {
Options options = CurrentOptions ( ) ;
options . merge_operator . reset ( new TestPutOperator ( ) ) ;
DestroyAndReopen ( options ) ;
std : : map < std : : string , std : : string > true_data ;
int file_id = 1 ;
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 1 , 2 , 3 , 4 , 5 , 6 } ,
{ ValueType : : kTypeValue , ValueType : : kTypeMerge , ValueType : : kTypeValue ,
ValueType : : kTypeMerge , ValueType : : kTypeValue , ValueType : : kTypeMerge } ,
file_id + + , & true_data ) ) ;
// File dont overwrite any keys, No seqno needed
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 0 ) ;
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 10 , 11 , 12 , 13 } ,
{ ValueType : : kTypeValue , ValueType : : kTypeMerge , ValueType : : kTypeValue ,
ValueType : : kTypeMerge } ,
file_id + + , & true_data ) ) ;
// File dont overwrite any keys, No seqno needed
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 0 ) ;
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 1 , 4 , 6 } , { ValueType : : kTypeDeletion , ValueType : : kTypeValue ,
ValueType : : kTypeMerge } ,
file_id + + , & true_data ) ) ;
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 1 ) ;
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 11 , 15 , 19 } , { ValueType : : kTypeDeletion , ValueType : : kTypeMerge ,
ValueType : : kTypeValue } ,
file_id + + , & true_data ) ) ;
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 2 ) ;
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 120 , 130 } , { ValueType : : kTypeValue , ValueType : : kTypeMerge } ,
file_id + + , & true_data ) ) ;
// File dont overwrite any keys, No seqno needed
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 2 ) ;
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 1 , 130 } , { ValueType : : kTypeMerge , ValueType : : kTypeDeletion } ,
file_id + + , & true_data ) ) ;
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , 3 ) ;
// Write some keys through normal write path
for ( int i = 0 ; i < 50 ; i + + ) {
ASSERT_OK ( Put ( Key ( i ) , " memtable " ) ) ;
true_data [ Key ( i ) ] = " memtable " ;
}
SequenceNumber last_seqno = dbfull ( ) - > GetLatestSequenceNumber ( ) ;
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 60 , 61 , 62 } ,
{ ValueType : : kTypeValue , ValueType : : kTypeMerge , ValueType : : kTypeValue } ,
file_id + + , & true_data ) ) ;
// File dont overwrite any keys, No seqno needed
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno ) ;
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 40 , 41 , 42 } , { ValueType : : kTypeValue , ValueType : : kTypeDeletion ,
ValueType : : kTypeDeletion } ,
file_id + + , & true_data ) ) ;
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 1 ) ;
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 20 , 30 , 40 } ,
{ ValueType : : kTypeDeletion , ValueType : : kTypeDeletion ,
ValueType : : kTypeDeletion } ,
file_id + + , & true_data ) ) ;
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 2 ) ;
const Snapshot * snapshot = db_ - > GetSnapshot ( ) ;
// We will need a seqno for the file regardless if the file overwrite
// keys in the DB or not because we have a snapshot
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 1000 , 1002 } , { ValueType : : kTypeValue , ValueType : : kTypeMerge } ,
file_id + + , & true_data ) ) ;
// A global seqno will be assigned anyway because of the snapshot
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 3 ) ;
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 2000 , 3002 } , { ValueType : : kTypeValue , ValueType : : kTypeMerge } ,
file_id + + , & true_data ) ) ;
// A global seqno will be assigned anyway because of the snapshot
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 4 ) ;
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 1 , 20 , 40 , 100 , 150 } ,
{ ValueType : : kTypeDeletion , ValueType : : kTypeDeletion ,
ValueType : : kTypeValue , ValueType : : kTypeMerge , ValueType : : kTypeMerge } ,
file_id + + , & true_data ) ) ;
// A global seqno will be assigned anyway because of the snapshot
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 5 ) ;
db_ - > ReleaseSnapshot ( snapshot ) ;
ASSERT_OK ( GenerateAndAddExternalFile (
options , { 5000 , 5001 } , { ValueType : : kTypeValue , ValueType : : kTypeMerge } ,
file_id + + , & true_data ) ) ;
// No snapshot anymore, no need to assign a seqno
// No snapshot anymore, no need to assign a seqno
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 5 ) ;
ASSERT_EQ ( dbfull ( ) - > GetLatestSequenceNumber ( ) , last_seqno + 5 ) ;
@ -280,7 +525,7 @@ TEST_F(ExternalSSTFileBasicTest, FadviseTrigger) {
size_t total_fadvised_bytes = 0 ;
size_t total_fadvised_bytes = 0 ;
rocksdb : : SyncPoint : : GetInstance ( ) - > SetCallBack (
rocksdb : : SyncPoint : : GetInstance ( ) - > SetCallBack (
" SstFileWriter::InvalidatePageCache " , [ & ] ( void * arg ) {
" SstFileWriter::Rep:: InvalidatePageCache " , [ & ] ( void * arg ) {
size_t fadvise_size = * ( reinterpret_cast < size_t * > ( arg ) ) ;
size_t fadvise_size = * ( reinterpret_cast < size_t * > ( arg ) ) ;
total_fadvised_bytes + = fadvise_size ;
total_fadvised_bytes + = fadvise_size ;
} ) ;
} ) ;
@ -293,19 +538,18 @@ TEST_F(ExternalSSTFileBasicTest, FadviseTrigger) {
new SstFileWriter ( EnvOptions ( ) , options , nullptr , false ) ) ;
new SstFileWriter ( EnvOptions ( ) , options , nullptr , false ) ) ;
ASSERT_OK ( sst_file_writer - > Open ( sst_file_path ) ) ;
ASSERT_OK ( sst_file_writer - > Open ( sst_file_path ) ) ;
for ( int i = 0 ; i < kNumKeys ; i + + ) {
for ( int i = 0 ; i < kNumKeys ; i + + ) {
ASSERT_OK ( sst_file_writer - > Add ( Key ( i ) , Key ( i ) ) ) ;
ASSERT_OK ( sst_file_writer - > Put ( Key ( i ) , Key ( i ) ) ) ;
}
}
ASSERT_OK ( sst_file_writer - > Finish ( ) ) ;
ASSERT_OK ( sst_file_writer - > Finish ( ) ) ;
// fadvise disabled
// fadvise disabled
ASSERT_EQ ( total_fadvised_bytes , 0 ) ;
ASSERT_EQ ( total_fadvised_bytes , 0 ) ;
sst_file_path = sst_files_dir_ + " file_fadvise_enable.sst " ;
sst_file_path = sst_files_dir_ + " file_fadvise_enable.sst " ;
sst_file_writer . reset (
sst_file_writer . reset (
new SstFileWriter ( EnvOptions ( ) , options , nullptr , true ) ) ;
new SstFileWriter ( EnvOptions ( ) , options , nullptr , true ) ) ;
ASSERT_OK ( sst_file_writer - > Open ( sst_file_path ) ) ;
ASSERT_OK ( sst_file_writer - > Open ( sst_file_path ) ) ;
for ( int i = 0 ; i < kNumKeys ; i + + ) {
for ( int i = 0 ; i < kNumKeys ; i + + ) {
ASSERT_OK ( sst_file_writer - > Add ( Key ( i ) , Key ( i ) ) ) ;
ASSERT_OK ( sst_file_writer - > Put ( Key ( i ) , Key ( i ) ) ) ;
}
}
ASSERT_OK ( sst_file_writer - > Finish ( ) ) ;
ASSERT_OK ( sst_file_writer - > Finish ( ) ) ;
// fadvise enabled
// fadvise enabled