@ -10,8 +10,12 @@
# ifdef GFLAGS
# include "db_stress_tool/db_stress_common.h"
# include <cmath>
# include "util/file_checksum_helper.h"
# include "util/xxhash.h"
ROCKSDB_NAMESPACE : : DbStressEnvWrapper * db_stress_env = nullptr ;
# ifndef NDEBUG
// If non-null, injects read error at a rate specified by the
@ -226,5 +230,106 @@ size_t GenerateValue(uint32_t rand, char* v, size_t max_sz) {
v [ value_sz ] = ' \0 ' ;
return value_sz ; // the size of the value set.
}
namespace {
class MyXXH64Checksum : public FileChecksumGenerator {
public :
explicit MyXXH64Checksum ( bool big ) : big_ ( big ) {
state_ = XXH64_createState ( ) ;
XXH64_reset ( state_ , 0 ) ;
}
virtual ~ MyXXH64Checksum ( ) override { XXH64_freeState ( state_ ) ; }
void Update ( const char * data , size_t n ) override {
XXH64_update ( state_ , data , n ) ;
}
void Finalize ( ) override {
assert ( str_ . empty ( ) ) ;
uint64_t digest = XXH64_digest ( state_ ) ;
// Store as little endian raw bytes
PutFixed64 ( & str_ , digest ) ;
if ( big_ ) {
// Throw in some more data for stress testing (448 bits total)
PutFixed64 ( & str_ , GetSliceHash64 ( str_ ) ) ;
PutFixed64 ( & str_ , GetSliceHash64 ( str_ ) ) ;
PutFixed64 ( & str_ , GetSliceHash64 ( str_ ) ) ;
PutFixed64 ( & str_ , GetSliceHash64 ( str_ ) ) ;
PutFixed64 ( & str_ , GetSliceHash64 ( str_ ) ) ;
PutFixed64 ( & str_ , GetSliceHash64 ( str_ ) ) ;
}
}
std : : string GetChecksum ( ) const override {
assert ( ! str_ . empty ( ) ) ;
return str_ ;
}
const char * Name ( ) const override {
return big_ ? " MyBigChecksum " : " MyXXH64Checksum " ;
}
private :
bool big_ ;
XXH64_state_t * state_ ;
std : : string str_ ;
} ;
class DbStressChecksumGenFactory : public FileChecksumGenFactory {
std : : string default_func_name_ ;
std : : unique_ptr < FileChecksumGenerator > CreateFromFuncName (
const std : : string & func_name ) {
std : : unique_ptr < FileChecksumGenerator > rv ;
if ( func_name = = " FileChecksumCrc32c " ) {
rv . reset ( new FileChecksumGenCrc32c ( FileChecksumGenContext ( ) ) ) ;
} else if ( func_name = = " MyXXH64Checksum " ) {
rv . reset ( new MyXXH64Checksum ( false /* big */ ) ) ;
} else if ( func_name = = " MyBigChecksum " ) {
rv . reset ( new MyXXH64Checksum ( true /* big */ ) ) ;
} else {
// Should be a recognized function when we get here
assert ( false ) ;
}
return rv ;
}
public :
explicit DbStressChecksumGenFactory ( const std : : string & default_func_name )
: default_func_name_ ( default_func_name ) { }
std : : unique_ptr < FileChecksumGenerator > CreateFileChecksumGenerator (
const FileChecksumGenContext & context ) override {
if ( context . requested_checksum_func_name . empty ( ) ) {
return CreateFromFuncName ( default_func_name_ ) ;
} else {
return CreateFromFuncName ( context . requested_checksum_func_name ) ;
}
}
const char * Name ( ) const override { return " FileChecksumGenCrc32cFactory " ; }
} ;
} // namespace
std : : shared_ptr < FileChecksumGenFactory > GetFileChecksumImpl (
const std : : string & name ) {
// Translate from friendly names to internal names
std : : string internal_name ;
if ( name = = " crc32c " ) {
internal_name = " FileChecksumCrc32c " ;
} else if ( name = = " xxh64 " ) {
internal_name = " MyXXH64Checksum " ;
} else if ( name = = " big " ) {
internal_name = " MyBigChecksum " ;
} else {
assert ( name . empty ( ) | | name = = " none " ) ;
return nullptr ;
}
return std : : make_shared < DbStressChecksumGenFactory > ( internal_name ) ;
}
} // namespace ROCKSDB_NAMESPACE
# endif // GFLAGS