@ -20,7 +20,6 @@
# include "utilities/merge_operators.h"
# include "utilities/merge_operators.h"
# include "util/testharness.h"
# include "util/testharness.h"
using namespace std ;
using namespace rocksdb ;
using namespace rocksdb ;
namespace {
namespace {
@ -76,7 +75,7 @@ class CountMergeOperator : public AssociativeMergeOperator {
} ;
} ;
namespace {
namespace {
std : : shared_ptr < DB > OpenDb ( const string & dbname , const bool ttl = false ,
std : : shared_ptr < DB > OpenDb ( const std : : st ring & dbname , const bool ttl = false ,
const size_t max_successive_merges = 0 ,
const size_t max_successive_merges = 0 ,
const uint32_t min_partial_merge_operands = 2 ) {
const uint32_t min_partial_merge_operands = 2 ) {
DB * db ;
DB * db ;
@ -90,7 +89,7 @@ std::shared_ptr<DB> OpenDb(const string& dbname, const bool ttl = false,
// DBWithTTL is not supported in ROCKSDB_LITE
// DBWithTTL is not supported in ROCKSDB_LITE
# ifndef ROCKSDB_LITE
# ifndef ROCKSDB_LITE
if ( ttl ) {
if ( ttl ) {
cout < < " Opening database with TTL \n " ;
std : : cout < < " Opening database with TTL \n " ;
DBWithTTL * db_with_ttl ;
DBWithTTL * db_with_ttl ;
s = DBWithTTL : : Open ( options , dbname , & db_with_ttl ) ;
s = DBWithTTL : : Open ( options , dbname , & db_with_ttl ) ;
db = db_with_ttl ;
db = db_with_ttl ;
@ -102,7 +101,7 @@ std::shared_ptr<DB> OpenDb(const string& dbname, const bool ttl = false,
s = DB : : Open ( options , dbname , & db ) ;
s = DB : : Open ( options , dbname , & db ) ;
# endif // !ROCKSDB_LITE
# endif // !ROCKSDB_LITE
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
cerr < < s . ToString ( ) < < endl ;
std : : cerr < < s . ToString ( ) < < std : : endl ;
assert ( false ) ;
assert ( false ) ;
}
}
return std : : shared_ptr < DB > ( db ) ;
return std : : shared_ptr < DB > ( db ) ;
@ -142,7 +141,7 @@ class Counters {
// if the underlying level db operation failed.
// if the underlying level db operation failed.
// mapped to a levedb Put
// mapped to a levedb Put
bool set ( const string & key , uint64_t value ) {
bool set ( const std : : st ring & key , uint64_t value ) {
// just treat the internal rep of int64 as the string
// just treat the internal rep of int64 as the string
Slice slice ( ( char * ) & value , sizeof ( value ) ) ;
Slice slice ( ( char * ) & value , sizeof ( value ) ) ;
auto s = db_ - > Put ( put_option_ , key , slice ) ;
auto s = db_ - > Put ( put_option_ , key , slice ) ;
@ -150,26 +149,26 @@ class Counters {
if ( s . ok ( ) ) {
if ( s . ok ( ) ) {
return true ;
return true ;
} else {
} else {
cerr < < s . ToString ( ) < < endl ;
std : : cerr < < s . ToString ( ) < < std : : endl ;
return false ;
return false ;
}
}
}
}
// mapped to a rocksdb Delete
// mapped to a rocksdb Delete
bool remove ( const string & key ) {
bool remove ( const std : : st ring & key ) {
auto s = db_ - > Delete ( delete_option_ , key ) ;
auto s = db_ - > Delete ( delete_option_ , key ) ;
if ( s . ok ( ) ) {
if ( s . ok ( ) ) {
return true ;
return true ;
} else {
} else {
cerr < < s . ToString ( ) < < std : : endl ;
std : : cerr < < s . ToString ( ) < < std : : endl ;
return false ;
return false ;
}
}
}
}
// mapped to a rocksdb Get
// mapped to a rocksdb Get
bool get ( const string & key , uint64_t * value ) {
bool get ( const std : : st ring & key , uint64_t * value ) {
string str ;
std : : st ring str ;
auto s = db_ - > Get ( get_option_ , key , & str ) ;
auto s = db_ - > Get ( get_option_ , key , & str ) ;
if ( s . IsNotFound ( ) ) {
if ( s . IsNotFound ( ) ) {
@ -179,35 +178,33 @@ class Counters {
} else if ( s . ok ( ) ) {
} else if ( s . ok ( ) ) {
// deserialization
// deserialization
if ( str . size ( ) ! = sizeof ( uint64_t ) ) {
if ( str . size ( ) ! = sizeof ( uint64_t ) ) {
cerr < < " value corruption \n " ;
std : : cerr < < " value corruption \n " ;
return false ;
return false ;
}
}
* value = DecodeFixed64 ( & str [ 0 ] ) ;
* value = DecodeFixed64 ( & str [ 0 ] ) ;
return true ;
return true ;
} else {
} else {
cerr < < s . ToString ( ) < < std : : endl ;
std : : cerr < < s . ToString ( ) < < std : : endl ;
return false ;
return false ;
}
}
}
}
// 'add' is implemented as get -> modify -> set
// 'add' is implemented as get -> modify -> set
// An alternative is a single merge operation, see MergeBasedCounters
// An alternative is a single merge operation, see MergeBasedCounters
virtual bool add ( const string & key , uint64_t value ) {
virtual bool add ( const std : : st ring & key , uint64_t value ) {
uint64_t base = default_ ;
uint64_t base = default_ ;
return get ( key , & base ) & & set ( key , base + value ) ;
return get ( key , & base ) & & set ( key , base + value ) ;
}
}
// convenience functions for testing
// convenience functions for testing
void assert_set ( const string & key , uint64_t value ) {
void assert_set ( const std : : st ring & key , uint64_t value ) {
assert ( set ( key , value ) ) ;
assert ( set ( key , value ) ) ;
}
}
void assert_remove ( const string & key ) {
void assert_remove ( const std : : string & key ) { assert ( remove ( key ) ) ; }
assert ( remove ( key ) ) ;
}
uint64_t assert_get ( const string & key ) {
uint64_t assert_get ( const std : : string & key ) {
uint64_t value = default_ ;
uint64_t value = default_ ;
int result = get ( key , & value ) ;
int result = get ( key , & value ) ;
assert ( result ) ;
assert ( result ) ;
@ -215,7 +212,7 @@ class Counters {
return value ;
return value ;
}
}
void assert_add ( const string & key , uint64_t value ) {
void assert_add ( const std : : st ring & key , uint64_t value ) {
int result = add ( key , value ) ;
int result = add ( key , value ) ;
assert ( result ) ;
assert ( result ) ;
if ( result = = 0 ) exit ( 1 ) ; // Disable unused variable warning.
if ( result = = 0 ) exit ( 1 ) ; // Disable unused variable warning.
@ -234,7 +231,7 @@ class MergeBasedCounters : public Counters {
}
}
// mapped to a rocksdb Merge operation
// mapped to a rocksdb Merge operation
virtual bool add ( const string & key , uint64_t value ) override {
virtual bool add ( const std : : st ring & key , uint64_t value ) override {
char encoded [ sizeof ( uint64_t ) ] ;
char encoded [ sizeof ( uint64_t ) ] ;
EncodeFixed64 ( encoded , value ) ;
EncodeFixed64 ( encoded , value ) ;
Slice slice ( encoded , sizeof ( uint64_t ) ) ;
Slice slice ( encoded , sizeof ( uint64_t ) ) ;
@ -243,7 +240,7 @@ class MergeBasedCounters : public Counters {
if ( s . ok ( ) ) {
if ( s . ok ( ) ) {
return true ;
return true ;
} else {
} else {
cerr < < s . ToString ( ) < < endl ;
std : : cerr < < s . ToString ( ) < < std : : endl ;
return false ;
return false ;
}
}
}
}
@ -254,7 +251,7 @@ void dumpDb(DB* db) {
auto it = unique_ptr < Iterator > ( db - > NewIterator ( ReadOptions ( ) ) ) ;
auto it = unique_ptr < Iterator > ( db - > NewIterator ( ReadOptions ( ) ) ) ;
for ( it - > SeekToFirst ( ) ; it - > Valid ( ) ; it - > Next ( ) ) {
for ( it - > SeekToFirst ( ) ; it - > Valid ( ) ; it - > Next ( ) ) {
uint64_t value = DecodeFixed64 ( it - > value ( ) . data ( ) ) ;
uint64_t value = DecodeFixed64 ( it - > value ( ) . data ( ) ) ;
cout < < it - > key ( ) . ToString ( ) < < " : " < < value < < endl ;
std : : cout < < it - > key ( ) . ToString ( ) < < " : " < < value < < std : : endl ;
}
}
assert ( it - > status ( ) . ok ( ) ) ; // Check for any errors found during the scan
assert ( it - > status ( ) . ok ( ) ) ; // Check for any errors found during the scan
}
}
@ -302,9 +299,9 @@ void testCounters(Counters& counters, DB* db, bool test_compaction) {
if ( test_compaction ) {
if ( test_compaction ) {
db - > Flush ( o ) ;
db - > Flush ( o ) ;
cout < < " Compaction started ... \n " ;
std : : cout < < " Compaction started ... \n " ;
db - > CompactRange ( CompactRangeOptions ( ) , nullptr , nullptr ) ;
db - > CompactRange ( CompactRangeOptions ( ) , nullptr , nullptr ) ;
cout < < " Compaction ended \n " ;
std : : cout < < " Compaction ended \n " ;
dumpDb ( db ) ;
dumpDb ( db ) ;
@ -400,7 +397,7 @@ void testSingleBatchSuccessiveMerge(DB* db, size_t max_num_merges,
// Get the value
// Get the value
resetNumMergeOperatorCalls ( ) ;
resetNumMergeOperatorCalls ( ) ;
string get_value_str ;
std : : st ring get_value_str ;
{
{
Status s = db - > Get ( ReadOptions ( ) , key , & get_value_str ) ;
Status s = db - > Get ( ReadOptions ( ) , key , & get_value_str ) ;
assert ( s . ok ( ) ) ;
assert ( s . ok ( ) ) ;
@ -412,24 +409,24 @@ void testSingleBatchSuccessiveMerge(DB* db, size_t max_num_merges,
static_cast < size_t > ( ( num_merges % ( max_num_merges + 1 ) ) ) ) ;
static_cast < size_t > ( ( num_merges % ( max_num_merges + 1 ) ) ) ) ;
}
}
void runTest ( int argc , const string & dbname , const bool use_ttl = false ) {
void runTest ( int argc , const std : : st ring & dbname , const bool use_ttl = false ) {
bool compact = false ;
bool compact = false ;
if ( argc > 1 ) {
if ( argc > 1 ) {
compact = true ;
compact = true ;
cout < < " Turn on Compaction \n " ;
std : : cout < < " Turn on Compaction \n " ;
}
}
{
{
auto db = OpenDb ( dbname , use_ttl ) ;
auto db = OpenDb ( dbname , use_ttl ) ;
{
{
cout < < " Test read-modify-write counters... \n " ;
std : : cout < < " Test read-modify-write counters... \n " ;
Counters counters ( db , 0 ) ;
Counters counters ( db , 0 ) ;
testCounters ( counters , db . get ( ) , true ) ;
testCounters ( counters , db . get ( ) , true ) ;
}
}
{
{
cout < < " Test merge-based counters... \n " ;
std : : cout < < " Test merge-based counters... \n " ;
MergeBasedCounters counters ( db , 0 ) ;
MergeBasedCounters counters ( db , 0 ) ;
testCounters ( counters , db . get ( ) , compact ) ;
testCounters ( counters , db . get ( ) , compact ) ;
}
}
@ -438,7 +435,7 @@ void runTest(int argc, const string& dbname, const bool use_ttl = false) {
DestroyDB ( dbname , Options ( ) ) ;
DestroyDB ( dbname , Options ( ) ) ;
{
{
cout < < " Test merge in memtable... \n " ;
std : : cout < < " Test merge in memtable... \n " ;
size_t max_merge = 5 ;
size_t max_merge = 5 ;
auto db = OpenDb ( dbname , use_ttl , max_merge ) ;
auto db = OpenDb ( dbname , use_ttl , max_merge ) ;
MergeBasedCounters counters ( db , 0 ) ;
MergeBasedCounters counters ( db , 0 ) ;
@ -449,7 +446,7 @@ void runTest(int argc, const string& dbname, const bool use_ttl = false) {
}
}
{
{
cout < < " Test Partial-Merge \n " ;
std : : cout < < " Test Partial-Merge \n " ;
size_t max_merge = 100 ;
size_t max_merge = 100 ;
for ( uint32_t min_merge = 5 ; min_merge < 25 ; min_merge + = 5 ) {
for ( uint32_t min_merge = 5 ; min_merge < 25 ; min_merge + = 5 ) {
for ( uint32_t count = min_merge - 1 ; count < = min_merge + 1 ; count + + ) {
for ( uint32_t count = min_merge - 1 ; count < = min_merge + 1 ; count + + ) {
@ -469,7 +466,7 @@ void runTest(int argc, const string& dbname, const bool use_ttl = false) {
}
}
{
{
cout < < " Test merge-operator not set after reopen \n " ;
std : : cout < < " Test merge-operator not set after reopen \n " ;
{
{
auto db = OpenDb ( dbname ) ;
auto db = OpenDb ( dbname ) ;
MergeBasedCounters counters ( db , 0 ) ;
MergeBasedCounters counters ( db , 0 ) ;
@ -489,7 +486,7 @@ void runTest(int argc, const string& dbname, const bool use_ttl = false) {
/* Temporary remove this test
/* Temporary remove this test
{
{
cout < < " Test merge-operator not set after reopen (recovery case) \n " ;
std : : cout < < " Test merge-operator not set after reopen (recovery case) \n " ;
{
{
auto db = OpenDb ( dbname ) ;
auto db = OpenDb ( dbname ) ;
MergeBasedCounters counters ( db , 0 ) ;
MergeBasedCounters counters ( db , 0 ) ;