|
@ -33,8 +33,11 @@ class AtomicCounter { |
|
|
public: |
|
|
public: |
|
|
AtomicCounter() : count_(0) { } |
|
|
AtomicCounter() : count_(0) { } |
|
|
void Increment() { |
|
|
void Increment() { |
|
|
|
|
|
IncrementBy(1); |
|
|
|
|
|
} |
|
|
|
|
|
void IncrementBy(int count) { |
|
|
MutexLock l(&mu_); |
|
|
MutexLock l(&mu_); |
|
|
count_++; |
|
|
|
|
|
|
|
|
count_ += count; |
|
|
} |
|
|
} |
|
|
int Read() { |
|
|
int Read() { |
|
|
MutexLock l(&mu_); |
|
|
MutexLock l(&mu_); |
|
@ -45,6 +48,10 @@ class AtomicCounter { |
|
|
count_ = 0; |
|
|
count_ = 0; |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
void DelayMilliseconds(int millis) { |
|
|
|
|
|
Env::Default()->SleepForMicroseconds(millis * 1000); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Special Env used to delay background operations
|
|
|
// Special Env used to delay background operations
|
|
@ -69,6 +76,7 @@ class SpecialEnv : public EnvWrapper { |
|
|
AtomicCounter random_read_counter_; |
|
|
AtomicCounter random_read_counter_; |
|
|
|
|
|
|
|
|
AtomicCounter sleep_counter_; |
|
|
AtomicCounter sleep_counter_; |
|
|
|
|
|
AtomicCounter sleep_time_counter_; |
|
|
|
|
|
|
|
|
explicit SpecialEnv(Env* base) : EnvWrapper(base) { |
|
|
explicit SpecialEnv(Env* base) : EnvWrapper(base) { |
|
|
delay_sstable_sync_.Release_Store(NULL); |
|
|
delay_sstable_sync_.Release_Store(NULL); |
|
@ -103,7 +111,7 @@ class SpecialEnv : public EnvWrapper { |
|
|
Status Flush() { return base_->Flush(); } |
|
|
Status Flush() { return base_->Flush(); } |
|
|
Status Sync() { |
|
|
Status Sync() { |
|
|
while (env_->delay_sstable_sync_.Acquire_Load() != NULL) { |
|
|
while (env_->delay_sstable_sync_.Acquire_Load() != NULL) { |
|
|
env_->SleepForMicroseconds(100000); |
|
|
|
|
|
|
|
|
DelayMilliseconds(100); |
|
|
} |
|
|
} |
|
|
return base_->Sync(); |
|
|
return base_->Sync(); |
|
|
} |
|
|
} |
|
@ -174,8 +182,9 @@ class SpecialEnv : public EnvWrapper { |
|
|
|
|
|
|
|
|
virtual void SleepForMicroseconds(int micros) { |
|
|
virtual void SleepForMicroseconds(int micros) { |
|
|
sleep_counter_.Increment(); |
|
|
sleep_counter_.Increment(); |
|
|
target()->SleepForMicroseconds(micros); |
|
|
|
|
|
|
|
|
sleep_time_counter_.IncrementBy(micros); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
class DBTest { |
|
|
class DBTest { |
|
@ -625,7 +634,7 @@ TEST(DBTest, GetEncountersEmptyLevel) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Step 4: Wait for compaction to finish
|
|
|
// Step 4: Wait for compaction to finish
|
|
|
env_->SleepForMicroseconds(1000000); |
|
|
|
|
|
|
|
|
DelayMilliseconds(1000); |
|
|
|
|
|
|
|
|
ASSERT_EQ(NumTableFilesAtLevel(0), 0); |
|
|
ASSERT_EQ(NumTableFilesAtLevel(0), 0); |
|
|
} while (ChangeOptions()); |
|
|
} while (ChangeOptions()); |
|
@ -1309,7 +1318,7 @@ TEST(DBTest, L0_CompactionBug_Issue44_a) { |
|
|
Reopen(); |
|
|
Reopen(); |
|
|
Reopen(); |
|
|
Reopen(); |
|
|
ASSERT_EQ("(a->v)", Contents()); |
|
|
ASSERT_EQ("(a->v)", Contents()); |
|
|
env_->SleepForMicroseconds(1000000); // Wait for compaction to finish
|
|
|
|
|
|
|
|
|
DelayMilliseconds(1000); // Wait for compaction to finish
|
|
|
ASSERT_EQ("(a->v)", Contents()); |
|
|
ASSERT_EQ("(a->v)", Contents()); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -1325,7 +1334,7 @@ TEST(DBTest, L0_CompactionBug_Issue44_b) { |
|
|
Put("",""); |
|
|
Put("",""); |
|
|
Reopen(); |
|
|
Reopen(); |
|
|
Put("",""); |
|
|
Put("",""); |
|
|
env_->SleepForMicroseconds(1000000); // Wait for compaction to finish
|
|
|
|
|
|
|
|
|
DelayMilliseconds(1000); // Wait for compaction to finish
|
|
|
Reopen(); |
|
|
Reopen(); |
|
|
Put("d","dv"); |
|
|
Put("d","dv"); |
|
|
Reopen(); |
|
|
Reopen(); |
|
@ -1335,7 +1344,7 @@ TEST(DBTest, L0_CompactionBug_Issue44_b) { |
|
|
Delete("b"); |
|
|
Delete("b"); |
|
|
Reopen(); |
|
|
Reopen(); |
|
|
ASSERT_EQ("(->)(c->cv)", Contents()); |
|
|
ASSERT_EQ("(->)(c->cv)", Contents()); |
|
|
env_->SleepForMicroseconds(1000000); // Wait for compaction to finish
|
|
|
|
|
|
|
|
|
DelayMilliseconds(1000); // Wait for compaction to finish
|
|
|
ASSERT_EQ("(->)(c->cv)", Contents()); |
|
|
ASSERT_EQ("(->)(c->cv)", Contents()); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -1520,6 +1529,30 @@ TEST(DBTest, NoSpace) { |
|
|
ASSERT_GE(env_->sleep_counter_.Read(), 5); |
|
|
ASSERT_GE(env_->sleep_counter_.Read(), 5); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
TEST(DBTest, ExponentialBackoff) { |
|
|
|
|
|
Options options = CurrentOptions(); |
|
|
|
|
|
options.env = env_; |
|
|
|
|
|
Reopen(&options); |
|
|
|
|
|
|
|
|
|
|
|
ASSERT_OK(Put("foo", "v1")); |
|
|
|
|
|
ASSERT_EQ("v1", Get("foo")); |
|
|
|
|
|
Compact("a", "z"); |
|
|
|
|
|
env_->non_writable_.Release_Store(env_); // Force errors for new files
|
|
|
|
|
|
env_->sleep_counter_.Reset(); |
|
|
|
|
|
env_->sleep_time_counter_.Reset(); |
|
|
|
|
|
for (int i = 0; i < 5; i++) { |
|
|
|
|
|
dbfull()->TEST_CompactRange(2, NULL, NULL); |
|
|
|
|
|
} |
|
|
|
|
|
env_->non_writable_.Release_Store(NULL); |
|
|
|
|
|
|
|
|
|
|
|
// Wait for compaction to finish
|
|
|
|
|
|
DelayMilliseconds(1000); |
|
|
|
|
|
|
|
|
|
|
|
ASSERT_GE(env_->sleep_counter_.Read(), 5); |
|
|
|
|
|
ASSERT_LT(env_->sleep_counter_.Read(), 10); |
|
|
|
|
|
ASSERT_GE(env_->sleep_time_counter_.Read(), 10e6); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
TEST(DBTest, NonWritableFileSystem) { |
|
|
TEST(DBTest, NonWritableFileSystem) { |
|
|
Options options = CurrentOptions(); |
|
|
Options options = CurrentOptions(); |
|
|
options.write_buffer_size = 1000; |
|
|
options.write_buffer_size = 1000; |
|
@ -1533,7 +1566,7 @@ TEST(DBTest, NonWritableFileSystem) { |
|
|
fprintf(stderr, "iter %d; errors %d\n", i, errors); |
|
|
fprintf(stderr, "iter %d; errors %d\n", i, errors); |
|
|
if (!Put("foo", big).ok()) { |
|
|
if (!Put("foo", big).ok()) { |
|
|
errors++; |
|
|
errors++; |
|
|
env_->SleepForMicroseconds(100000); |
|
|
|
|
|
|
|
|
DelayMilliseconds(100); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
ASSERT_GT(errors, 0); |
|
|
ASSERT_GT(errors, 0); |
|
@ -1589,6 +1622,7 @@ TEST(DBTest, MissingSSTFile) { |
|
|
dbfull()->TEST_CompactMemTable(); |
|
|
dbfull()->TEST_CompactMemTable(); |
|
|
ASSERT_EQ("bar", Get("foo")); |
|
|
ASSERT_EQ("bar", Get("foo")); |
|
|
|
|
|
|
|
|
|
|
|
Close(); |
|
|
ASSERT_TRUE(DeleteAnSSTFile()); |
|
|
ASSERT_TRUE(DeleteAnSSTFile()); |
|
|
Options options = CurrentOptions(); |
|
|
Options options = CurrentOptions(); |
|
|
options.paranoid_checks = true; |
|
|
options.paranoid_checks = true; |
|
@ -1742,13 +1776,13 @@ TEST(DBTest, MultiThreaded) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Let them run for a while
|
|
|
// Let them run for a while
|
|
|
env_->SleepForMicroseconds(kTestSeconds * 1000000); |
|
|
|
|
|
|
|
|
DelayMilliseconds(kTestSeconds * 1000); |
|
|
|
|
|
|
|
|
// Stop the threads and wait for them to finish
|
|
|
// Stop the threads and wait for them to finish
|
|
|
mt.stop.Release_Store(&mt); |
|
|
mt.stop.Release_Store(&mt); |
|
|
for (int id = 0; id < kNumThreads; id++) { |
|
|
for (int id = 0; id < kNumThreads; id++) { |
|
|
while (mt.thread_done[id].Acquire_Load() == NULL) { |
|
|
while (mt.thread_done[id].Acquire_Load() == NULL) { |
|
|
env_->SleepForMicroseconds(100000); |
|
|
|
|
|
|
|
|
DelayMilliseconds(100); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} while (ChangeOptions()); |
|
|
} while (ChangeOptions()); |
|
|