@ -14,19 +14,75 @@
# include <cmath>
# include <cmath>
# include <vector>
# include <vector>
# include "port/stack_trace.h"
# include "rocksdb/table.h"
# include "rocksdb/table.h"
# include "rocksdb/table_properties.h"
# include "rocksdb/table_properties.h"
# include "rocksdb/utilities/table_properties_collectors.h"
# include "rocksdb/utilities/table_properties_collectors.h"
# include "test_util/testharness.h"
# include "util/random.h"
# include "util/random.h"
# include "utilities/table_properties_collectors/compact_on_deletion_collector.h"
# include "utilities/table_properties_collectors/compact_on_deletion_collector.h"
int main ( int /*argc*/ , char * * /*argv*/ ) {
namespace ROCKSDB_NAMESPACE {
TEST ( CompactOnDeletionCollector , DeletionRatio ) {
TablePropertiesCollectorFactory : : Context context ;
context . column_family_id =
TablePropertiesCollectorFactory : : Context : : kUnknownColumnFamily ;
const size_t kTotalEntries = 100 ;
{
// Disable deletion ratio.
for ( double deletion_ratio : { - 1.5 , - 1.0 , 0.0 , 1.5 , 2.0 } ) {
auto factory = NewCompactOnDeletionCollectorFactory ( 0 , 0 , deletion_ratio ) ;
std : : unique_ptr < TablePropertiesCollector > collector (
factory - > CreateTablePropertiesCollector ( context ) ) ;
for ( size_t i = 0 ; i < kTotalEntries ; i + + ) {
// All entries are deletion entries.
collector - > AddUserKey ( " hello " , " rocksdb " , kEntryDelete , 0 , 0 ) ;
ASSERT_FALSE ( collector - > NeedCompact ( ) ) ;
}
collector - > Finish ( nullptr ) ;
ASSERT_FALSE ( collector - > NeedCompact ( ) ) ;
}
}
{
for ( double deletion_ratio : { 0.3 , 0.5 , 0.8 , 1.0 } ) {
auto factory = NewCompactOnDeletionCollectorFactory ( 0 , 0 , deletion_ratio ) ;
const size_t deletion_entries_trigger =
static_cast < size_t > ( deletion_ratio * kTotalEntries ) ;
for ( int delta : { - 1 , 0 , 1 } ) {
// Actual deletion entry ratio <, =, > deletion_ratio
size_t actual_deletion_entries = deletion_entries_trigger + delta ;
std : : unique_ptr < TablePropertiesCollector > collector (
factory - > CreateTablePropertiesCollector ( context ) ) ;
for ( size_t i = 0 ; i < kTotalEntries ; i + + ) {
if ( i < actual_deletion_entries ) {
collector - > AddUserKey ( " hello " , " rocksdb " , kEntryDelete , 0 , 0 ) ;
} else {
collector - > AddUserKey ( " hello " , " rocksdb " , kEntryPut , 0 , 0 ) ;
}
ASSERT_FALSE ( collector - > NeedCompact ( ) ) ;
}
collector - > Finish ( nullptr ) ;
if ( delta > = 0 ) {
// >= deletion_ratio
ASSERT_TRUE ( collector - > NeedCompact ( ) ) ;
} else {
ASSERT_FALSE ( collector - > NeedCompact ( ) ) ;
}
}
}
}
}
TEST ( CompactOnDeletionCollector , SlidingWindow ) {
const int kWindowSizes [ ] =
const int kWindowSizes [ ] =
{ 1000 , 10000 , 10000 , 127 , 128 , 129 , 255 , 256 , 257 , 2 , 10000 } ;
{ 1000 , 10000 , 10000 , 127 , 128 , 129 , 255 , 256 , 257 , 2 , 10000 } ;
const int kDeletionTriggers [ ] =
const int kDeletionTriggers [ ] =
{ 500 , 9500 , 4323 , 47 , 61 , 128 , 250 , 250 , 250 , 2 , 2 } ;
{ 500 , 9500 , 4323 , 47 , 61 , 128 , 250 , 250 , 250 , 2 , 2 } ;
ROCKSDB_NAMESPACE : : TablePropertiesCollectorFactory : : Context context ;
TablePropertiesCollectorFactory : : Context context ;
context . column_family_id = ROCKSDB_NAMESPACE : :
context . column_family_id =
TablePropertiesCollectorFactory : : Context : : kUnknownColumnFamily ;
TablePropertiesCollectorFactory : : Context : : kUnknownColumnFamily ;
std : : vector < int > window_sizes ;
std : : vector < int > window_sizes ;
@ -38,7 +94,7 @@ int main(int /*argc*/, char** /*argv*/) {
}
}
// randomize tests
// randomize tests
ROCKSDB_NAMESPACE : : R andom rnd ( 301 ) ;
Random rnd ( 301 ) ;
const int kMaxTestSize = 100000l ;
const int kMaxTestSize = 100000l ;
for ( int random_test = 0 ; random_test < 10 ; random_test + + ) {
for ( int random_test = 0 ; random_test < 10 ; random_test + + ) {
int window_size = rnd . Uniform ( kMaxTestSize ) + 1 ;
int window_size = rnd . Uniform ( kMaxTestSize ) + 1 ;
@ -58,21 +114,19 @@ int main(int /*argc*/, char** /*argv*/) {
const int kBias = ( kNumDeletionTrigger + kBucketSize - 1 ) / kBucketSize ;
const int kBias = ( kNumDeletionTrigger + kBucketSize - 1 ) / kBucketSize ;
// Simple test
// Simple test
{
{
auto factory = ROCKSDB_NAMESPACE : : NewCompactOnDeletionCollectorFactory (
auto factory = NewCompactOnDeletionCollectorFactory ( kWindowSize ,
kWindowSize , kNumDeletionTrigger ) ;
kNumDeletionTrigger ) ;
const int kSample = 10 ;
const int kSample = 10 ;
for ( int delete_rate = 0 ; delete_rate < = kSample ; + + delete_rate ) {
for ( int delete_rate = 0 ; delete_rate < = kSample ; + + delete_rate ) {
std : : unique_ptr < ROCKSDB_NAMESPACE : : TablePropertiesCollector > collector (
std : : unique_ptr < TablePropertiesCollector > collector (
factory - > CreateTablePropertiesCollector ( context ) ) ;
factory - > CreateTablePropertiesCollector ( context ) ) ;
int deletions = 0 ;
int deletions = 0 ;
for ( int i = 0 ; i < kPaddedWindowSize ; + + i ) {
for ( int i = 0 ; i < kPaddedWindowSize ; + + i ) {
if ( i % kSample < delete_rate ) {
if ( i % kSample < delete_rate ) {
collector - > AddUserKey ( " hello " , " rocksdb " ,
collector - > AddUserKey ( " hello " , " rocksdb " , kEntryDelete , 0 , 0 ) ;
ROCKSDB_NAMESPACE : : kEntryDelete , 0 , 0 ) ;
deletions + + ;
deletions + + ;
} else {
} else {
collector - > AddUserKey ( " hello " , " rocksdb " ,
collector - > AddUserKey ( " hello " , " rocksdb " , kEntryPut , 0 , 0 ) ;
ROCKSDB_NAMESPACE : : kEntryPut , 0 , 0 ) ;
}
}
}
}
if ( collector - > NeedCompact ( ) ! =
if ( collector - > NeedCompact ( ) ! =
@ -82,7 +136,7 @@ int main(int /*argc*/, char** /*argv*/) {
" with kWindowSize = %d and kNumDeletionTrigger = %d \n " ,
" with kWindowSize = %d and kNumDeletionTrigger = %d \n " ,
deletions , kNumDeletionTrigger ,
deletions , kNumDeletionTrigger ,
kWindowSize , kNumDeletionTrigger ) ;
kWindowSize , kNumDeletionTrigger ) ;
assert ( false ) ;
ASSERT_TRUE ( false ) ;
}
}
collector - > Finish ( nullptr ) ;
collector - > Finish ( nullptr ) ;
}
}
@ -90,35 +144,31 @@ int main(int /*argc*/, char** /*argv*/) {
// Only one section of a file satisfies the compaction trigger
// Only one section of a file satisfies the compaction trigger
{
{
auto factory = ROCKSDB_NAMESPACE : : NewCompactOnDeletionCollectorFactory (
auto factory = NewCompactOnDeletionCollectorFactory ( kWindowSize ,
kWindowSize , kNumDeletionTrigger ) ;
kNumDeletionTrigger ) ;
const int kSample = 10 ;
const int kSample = 10 ;
for ( int delete_rate = 0 ; delete_rate < = kSample ; + + delete_rate ) {
for ( int delete_rate = 0 ; delete_rate < = kSample ; + + delete_rate ) {
std : : unique_ptr < ROCKSDB_NAMESPACE : : TablePropertiesCollector > collector (
std : : unique_ptr < TablePropertiesCollector > collector (
factory - > CreateTablePropertiesCollector ( context ) ) ;
factory - > CreateTablePropertiesCollector ( context ) ) ;
int deletions = 0 ;
int deletions = 0 ;
for ( int section = 0 ; section < 5 ; + + section ) {
for ( int section = 0 ; section < 5 ; + + section ) {
int initial_entries = rnd . Uniform ( kWindowSize ) + kWindowSize ;
int initial_entries = rnd . Uniform ( kWindowSize ) + kWindowSize ;
for ( int i = 0 ; i < initial_entries ; + + i ) {
for ( int i = 0 ; i < initial_entries ; + + i ) {
collector - > AddUserKey ( " hello " , " rocksdb " ,
collector - > AddUserKey ( " hello " , " rocksdb " , kEntryPut , 0 , 0 ) ;
ROCKSDB_NAMESPACE : : kEntryPut , 0 , 0 ) ;
}
}
}
}
for ( int i = 0 ; i < kPaddedWindowSize ; + + i ) {
for ( int i = 0 ; i < kPaddedWindowSize ; + + i ) {
if ( i % kSample < delete_rate ) {
if ( i % kSample < delete_rate ) {
collector - > AddUserKey ( " hello " , " rocksdb " ,
collector - > AddUserKey ( " hello " , " rocksdb " , kEntryDelete , 0 , 0 ) ;
ROCKSDB_NAMESPACE : : kEntryDelete , 0 , 0 ) ;
deletions + + ;
deletions + + ;
} else {
} else {
collector - > AddUserKey ( " hello " , " rocksdb " ,
collector - > AddUserKey ( " hello " , " rocksdb " , kEntryPut , 0 , 0 ) ;
ROCKSDB_NAMESPACE : : kEntryPut , 0 , 0 ) ;
}
}
}
}
for ( int section = 0 ; section < 5 ; + + section ) {
for ( int section = 0 ; section < 5 ; + + section ) {
int ending_entries = rnd . Uniform ( kWindowSize ) + kWindowSize ;
int ending_entries = rnd . Uniform ( kWindowSize ) + kWindowSize ;
for ( int i = 0 ; i < ending_entries ; + + i ) {
for ( int i = 0 ; i < ending_entries ; + + i ) {
collector - > AddUserKey ( " hello " , " rocksdb " ,
collector - > AddUserKey ( " hello " , " rocksdb " , kEntryPut , 0 , 0 ) ;
ROCKSDB_NAMESPACE : : kEntryPut , 0 , 0 ) ;
}
}
}
}
if ( collector - > NeedCompact ( ) ! = ( deletions > = kNumDeletionTrigger ) & &
if ( collector - > NeedCompact ( ) ! = ( deletions > = kNumDeletionTrigger ) & &
@ -128,7 +178,7 @@ int main(int /*argc*/, char** /*argv*/) {
collector - > NeedCompact ( ) ,
collector - > NeedCompact ( ) ,
deletions , kNumDeletionTrigger , kWindowSize ,
deletions , kNumDeletionTrigger , kWindowSize ,
kNumDeletionTrigger ) ;
kNumDeletionTrigger ) ;
assert ( false ) ;
ASSERT_TRUE ( false ) ;
}
}
collector - > Finish ( nullptr ) ;
collector - > Finish ( nullptr ) ;
}
}
@ -137,9 +187,9 @@ int main(int /*argc*/, char** /*argv*/) {
// TEST 3: Issues a lots of deletes, but their density is not
// TEST 3: Issues a lots of deletes, but their density is not
// high enough to trigger compaction.
// high enough to trigger compaction.
{
{
std : : unique_ptr < ROCKSDB_NAMESPACE : : TablePropertiesCollector > collector ;
std : : unique_ptr < TablePropertiesCollector > collector ;
auto factory = ROCKSDB_NAMESPACE : : NewCompactOnDeletionCollectorFactory (
auto factory = NewCompactOnDeletionCollectorFactory ( kWindowSize ,
kWindowSize , kNumDeletionTrigger ) ;
kNumDeletionTrigger ) ;
collector . reset ( factory - > CreateTablePropertiesCollector ( context ) ) ;
collector . reset ( factory - > CreateTablePropertiesCollector ( context ) ) ;
assert ( collector - > NeedCompact ( ) = = false ) ;
assert ( collector - > NeedCompact ( ) = = false ) ;
// Insert "kNumDeletionTrigger * 0.95" deletions for every
// Insert "kNumDeletionTrigger * 0.95" deletions for every
@ -149,11 +199,9 @@ int main(int /*argc*/, char** /*argv*/) {
for ( int section = 0 ; section < 200 ; + + section ) {
for ( int section = 0 ; section < 200 ; + + section ) {
for ( int i = 0 ; i < kPaddedWindowSize ; + + i ) {
for ( int i = 0 ; i < kPaddedWindowSize ; + + i ) {
if ( i < kDeletionsPerSection ) {
if ( i < kDeletionsPerSection ) {
collector - > AddUserKey ( " hello " , " rocksdb " ,
collector - > AddUserKey ( " hello " , " rocksdb " , kEntryDelete , 0 , 0 ) ;
ROCKSDB_NAMESPACE : : kEntryDelete , 0 , 0 ) ;
} else {
} else {
collector - > AddUserKey ( " hello " , " rocksdb " ,
collector - > AddUserKey ( " hello " , " rocksdb " , kEntryPut , 0 , 0 ) ;
ROCKSDB_NAMESPACE : : kEntryPut , 0 , 0 ) ;
}
}
}
}
}
}
@ -162,13 +210,20 @@ int main(int /*argc*/, char** /*argv*/) {
fprintf ( stderr , " [Error] collector->NeedCompact() != false "
fprintf ( stderr , " [Error] collector->NeedCompact() != false "
" with kWindowSize = %d and kNumDeletionTrigger = %d \n " ,
" with kWindowSize = %d and kNumDeletionTrigger = %d \n " ,
kWindowSize , kNumDeletionTrigger ) ;
kWindowSize , kNumDeletionTrigger ) ;
assert ( false ) ;
ASSERT_TRUE ( false ) ;
}
}
collector - > Finish ( nullptr ) ;
collector - > Finish ( nullptr ) ;
}
}
}
}
}
}
fprintf ( stderr , " PASSED \n " ) ;
}
} // namespace ROCKSDB_NAMESPACE
int main ( int argc , char * * argv ) {
ROCKSDB_NAMESPACE : : port : : InstallStackTraceHandler ( ) ;
: : testing : : InitGoogleTest ( & argc , argv ) ;
return RUN_ALL_TESTS ( ) ;
}
}
# else
# else
int main ( int /*argc*/ , char * * /*argv*/ ) {
int main ( int /*argc*/ , char * * /*argv*/ ) {