22 static std::string RandomString(Random* rnd,
int len) {
34 AtomicCounter() : count_(0) { }
38 void IncrementBy(
int count) {
52 void DelayMilliseconds(
int millis) {
85 count_random_reads_ =
false;
101 ~SSTableFile() {
delete base_; }
107 return base_->
Append(data);
114 DelayMilliseconds(100);
116 return base_->
Sync();
125 ~ManifestFile() {
delete base_; }
130 return base_->
Append(data);
139 return base_->
Sync();
150 if (strstr(f.c_str(),
".sst") != NULL) {
151 *r =
new SSTableFile(
this, *r);
152 }
else if (strstr(f.c_str(),
"MANIFEST") != NULL) {
153 *r =
new ManifestFile(
this, *r);
163 AtomicCounter* counter_;
166 :
target_(target), counter_(counter) {
168 virtual ~CountingFile() {
delete target_; }
170 char* scratch)
const {
171 counter_->Increment();
172 return target_->
Read(offset, n, result, scratch);
178 *r =
new CountingFile(*r, &random_read_counter_);
184 sleep_counter_.Increment();
185 sleep_time_counter_.IncrementBy(micros);
230 if (option_config_ >=
kEnd) {
241 switch (option_config_) {
278 if (options != NULL) {
284 last_options_ = opts;
286 return DB::Open(opts, dbname_, &db_);
289 Status Put(
const std::string& k,
const std::string& v) {
297 std::string
Get(
const std::string& k,
const Snapshot* snapshot = NULL) {
301 Status s = db_->
Get(options, k, &result);
303 result =
"NOT_FOUND";
304 }
else if (!s.
ok()) {
313 std::vector<std::string> forward;
318 result.push_back(
'(');
320 result.push_back(
')');
321 forward.push_back(s);
347 while (iter->
Valid()) {
350 result +=
"CORRUPTED";
380 std::string property;
384 return atoi(property.c_str());
389 for (
int level = 0; level < config::kNumLevels; level++) {
398 int last_non_zero_offset = 0;
399 for (
int level = 0; level < config::kNumLevels; level++) {
402 snprintf(buf,
sizeof(buf),
"%s%d", (level ?
"," :
""), f);
405 last_non_zero_offset = result.size();
408 result.resize(last_non_zero_offset);
413 std::vector<std::string> files;
415 return static_cast<int>(files.size());
419 Range r(start, limit);
431 void MakeTables(
int n,
const std::string& small,
const std::string& large) {
432 for (
int i = 0; i < n; i++) {
441 void FillLevels(
const std::string& smallest,
const std::string& largest) {
442 MakeTables(config::kNumLevels, smallest, largest);
446 fprintf(stderr,
"---\n%s:\n", label);
447 fprintf(stderr,
"maxoverlap: %lld\n",
448 static_cast<long long>(
449 dbfull()->TEST_MaxNextLevelOverlappingBytes()));
450 for (
int level = 0; level < config::kNumLevels; level++) {
453 fprintf(stderr,
" level %3d : %d files\n", level, num);
459 std::string property;
469 result =
"(invalid)";
475 std::vector<std::string> filenames;
479 for (
size_t i = 0; i < filenames.size(); i++) {
493 }
while (ChangeOptions());
504 }
while (ChangeOptions());
515 }
while (ChangeOptions());
520 Options options = CurrentOptions();
528 env_->delay_sstable_sync_.Release_Store(
env_);
529 Put(
"k1", std::string(100000,
'x'));
530 Put(
"k2", std::string(100000,
'y'));
532 env_->delay_sstable_sync_.Release_Store(NULL);
533 }
while (ChangeOptions());
539 dbfull()->TEST_CompactMemTable();
541 }
while (ChangeOptions());
547 for (
int i = 0; i < 2; i++) {
548 std::string key = (i == 0) ? std::string(
"foo") : std::string(200,
'x');
554 dbfull()->TEST_CompactMemTable();
559 }
while (ChangeOptions());
570 dbfull()->TEST_CompactMemTable();
572 dbfull()->TEST_CompactMemTable();
574 }
while (ChangeOptions());
584 dbfull()->TEST_CompactMemTable();
586 }
while (ChangeOptions());
601 }
while (ChangeOptions());
615 int compaction_count = 0;
616 while (NumTableFilesAtLevel(0) == 0 ||
617 NumTableFilesAtLevel(2) == 0) {
618 ASSERT_LE(compaction_count, 100) <<
"could not fill levels 0 and 2";
622 dbfull()->TEST_CompactMemTable();
626 dbfull()->TEST_CompactRange(1, NULL, NULL);
632 for (
int i = 0; i < 1000; i++) {
637 DelayMilliseconds(1000);
640 }
while (ChangeOptions());
647 ASSERT_EQ(IterStatus(iter),
"(invalid)");
650 ASSERT_EQ(IterStatus(iter),
"(invalid)");
653 ASSERT_EQ(IterStatus(iter),
"(invalid)");
665 ASSERT_EQ(IterStatus(iter),
"(invalid)");
669 ASSERT_EQ(IterStatus(iter),
"(invalid)");
674 ASSERT_EQ(IterStatus(iter),
"(invalid)");
678 ASSERT_EQ(IterStatus(iter),
"(invalid)");
683 ASSERT_EQ(IterStatus(iter),
"(invalid)");
688 ASSERT_EQ(IterStatus(iter),
"(invalid)");
691 ASSERT_EQ(IterStatus(iter),
"(invalid)");
709 ASSERT_EQ(IterStatus(iter),
"(invalid)");
713 ASSERT_EQ(IterStatus(iter),
"(invalid)");
722 ASSERT_EQ(IterStatus(iter),
"(invalid)");
726 ASSERT_EQ(IterStatus(iter),
"(invalid)");
737 ASSERT_EQ(IterStatus(iter),
"(invalid)");
766 ASSERT_EQ(IterStatus(iter),
"(invalid)");
774 ASSERT_EQ(IterStatus(iter),
"(invalid)");
781 ASSERT_OK(Put(
"b", std::string(100000,
'b')));
783 ASSERT_OK(Put(
"d", std::string(100000,
'd')));
784 ASSERT_OK(Put(
"e", std::string(100000,
'e')));
791 ASSERT_EQ(IterStatus(iter),
"b->" + std::string(100000,
'b'));
795 ASSERT_EQ(IterStatus(iter),
"d->" + std::string(100000,
'd'));
797 ASSERT_EQ(IterStatus(iter),
"e->" + std::string(100000,
'e'));
799 ASSERT_EQ(IterStatus(iter),
"(invalid)");
802 ASSERT_EQ(IterStatus(iter),
"e->" + std::string(100000,
'e'));
804 ASSERT_EQ(IterStatus(iter),
"d->" + std::string(100000,
'd'));
808 ASSERT_EQ(IterStatus(iter),
"b->" + std::string(100000,
'b'));
812 ASSERT_EQ(IterStatus(iter),
"(invalid)");
831 }
while (ChangeOptions());
853 }
while (ChangeOptions());
865 }
while (ChangeOptions());
872 Options options = CurrentOptions();
879 ASSERT_OK(Put(
"big1", std::string(10000000,
'x')));
880 ASSERT_OK(Put(
"big2", std::string(1000,
'y')));
886 ASSERT_EQ(std::string(10000000,
'x'), Get(
"big1"));
887 ASSERT_EQ(std::string(1000,
'y'), Get(
"big2"));
888 }
while (ChangeOptions());
891 static std::string
Key(
int i) {
893 snprintf(buf,
sizeof(buf),
"key%06d", i);
894 return std::string(buf);
898 Options options = CurrentOptions();
904 int starting_num_tables = TotalTableFiles();
905 for (
int i = 0; i < N; i++) {
908 int ending_num_tables = TotalTableFiles();
909 ASSERT_GT(ending_num_tables, starting_num_tables);
911 for (
int i = 0; i < N; i++) {
917 for (
int i = 0; i < N; i++) {
924 Options options = CurrentOptions();
926 ASSERT_OK(Put(
"big1", std::string(200000,
'1')));
927 ASSERT_OK(Put(
"big2", std::string(200000,
'2')));
928 ASSERT_OK(Put(
"small3", std::string(10,
'3')));
929 ASSERT_OK(Put(
"small4", std::string(10,
'4')));
935 Options options = CurrentOptions();
939 ASSERT_EQ(std::string(200000,
'1'), Get(
"big1"));
940 ASSERT_EQ(std::string(200000,
'2'), Get(
"big2"));
941 ASSERT_EQ(std::string(10,
'3'), Get(
"small3"));
942 ASSERT_EQ(std::string(10,
'4'), Get(
"small4"));
947 Options options = CurrentOptions();
955 std::vector<std::string> values;
956 for (
int i = 0; i < 80; i++) {
957 values.push_back(RandomString(&rnd, 100000));
963 dbfull()->TEST_CompactRange(0, NULL, NULL);
967 for (
int i = 0; i < 80; i++) {
973 Options options = CurrentOptions();
980 const int kMaxFiles = config::kNumLevels + config::kL0_StopWritesTrigger;
984 for (
int i = 0; i < 5 * kMaxFiles; i++) {
987 fprintf(stderr,
"after %d: %d files\n",
int(i+1), TotalTableFiles());
992 Options options = CurrentOptions();
996 FillLevels(
"A",
"Z");
1004 const std::string
value(1000,
'x');
1007 for (
int i = 0; i < 100000; i++) {
1009 snprintf(key,
sizeof(key),
"B%010d", i);
1013 dbfull()->TEST_CompactMemTable();
1014 dbfull()->TEST_CompactRange(0, NULL, NULL);
1018 Put(
"B100",
"bvalue2");
1020 dbfull()->TEST_CompactMemTable();
1024 ASSERT_LE(dbfull()->TEST_MaxNextLevelOverlappingBytes(), 20*1048576);
1025 dbfull()->TEST_CompactRange(0, NULL, NULL);
1026 ASSERT_LE(dbfull()->TEST_MaxNextLevelOverlappingBytes(), 20*1048576);
1027 dbfull()->TEST_CompactRange(1, NULL, NULL);
1028 ASSERT_LE(dbfull()->TEST_MaxNextLevelOverlappingBytes(), 20*1048576);
1032 bool result = (val >= low) && (val <= high);
1034 fprintf(stderr,
"Value %llu is not in range [%llu, %llu]\n",
1035 (
unsigned long long)(val),
1036 (
unsigned long long)(low),
1037 (
unsigned long long)(high));
1044 Options options = CurrentOptions();
1056 static const int S1 = 100000;
1057 static const int S2 = 105000;
1059 for (
int i = 0; i < N; i++) {
1067 for (
int run = 0; run < 3; run++) {
1070 for (
int compact_start = 0; compact_start < N; compact_start += 10) {
1071 for (
int i = 0; i < N; i += 10) {
1073 ASSERT_TRUE(Between(Size(
"",
Key(i)+
".suffix"), S1*(i+1), S2*(i+1)));
1079 std::string cstart_str =
Key(compact_start);
1080 std::string cend_str =
Key(compact_start + 9);
1081 Slice cstart = cstart_str;
1082 Slice cend = cend_str;
1083 dbfull()->TEST_CompactRange(0, &cstart, &cend);
1089 }
while (ChangeOptions());
1094 Options options = CurrentOptions();
1099 std::string big1 = RandomString(&rnd, 100000);
1110 for (
int run = 0; run < 3; run++) {
1125 dbfull()->TEST_CompactRange(0, NULL, NULL);
1127 }
while (ChangeOptions());
1131 Put(
"foo",
"hello");
1137 Put(
"foo",
"newvalue1");
1138 for (
int i = 0; i < 100; i++) {
1141 Put(
"foo",
"newvalue2");
1178 }
while (ChangeOptions());
1184 FillLevels(
"a",
"z");
1186 std::string big = RandomString(&rnd, 50000);
1188 Put(
"pastfoo",
"v");
1191 Put(
"pastfoo2",
"v2");
1193 ASSERT_OK(dbfull()->TEST_CompactMemTable());
1197 ASSERT_TRUE(Between(Size(
"",
"pastfoo"), 50000, 60000));
1199 ASSERT_EQ(AllEntriesFor(
"foo"),
"[ tiny, " + big +
" ]");
1201 dbfull()->TEST_CompactRange(0, NULL, &x);
1202 ASSERT_EQ(AllEntriesFor(
"foo"),
"[ tiny ]");
1205 dbfull()->TEST_CompactRange(1, NULL, &x);
1206 ASSERT_EQ(AllEntriesFor(
"foo"),
"[ tiny ]");
1208 ASSERT_TRUE(Between(Size(
"",
"pastfoo"), 0, 1000));
1209 }
while (ChangeOptions());
1214 ASSERT_OK(dbfull()->TEST_CompactMemTable());
1215 const int last = config::kMaxMemCompactLevel;
1216 ASSERT_EQ(NumTableFilesAtLevel(last), 1);
1221 dbfull()->TEST_CompactMemTable();
1222 ASSERT_EQ(NumTableFilesAtLevel(last), 1);
1223 ASSERT_EQ(NumTableFilesAtLevel(last-1), 1);
1227 ASSERT_EQ(AllEntriesFor(
"foo"),
"[ v2, DEL, v1 ]");
1228 ASSERT_OK(dbfull()->TEST_CompactMemTable());
1229 ASSERT_EQ(AllEntriesFor(
"foo"),
"[ v2, DEL, v1 ]");
1231 dbfull()->TEST_CompactRange(last-2, NULL, &z);
1234 ASSERT_EQ(AllEntriesFor(
"foo"),
"[ v2, v1 ]");
1235 dbfull()->TEST_CompactRange(last-1, NULL, NULL);
1238 ASSERT_EQ(AllEntriesFor(
"foo"),
"[ v2 ]");
1243 ASSERT_OK(dbfull()->TEST_CompactMemTable());
1244 const int last = config::kMaxMemCompactLevel;
1245 ASSERT_EQ(NumTableFilesAtLevel(last), 1);
1250 dbfull()->TEST_CompactMemTable();
1251 ASSERT_EQ(NumTableFilesAtLevel(last), 1);
1252 ASSERT_EQ(NumTableFilesAtLevel(last-1), 1);
1255 ASSERT_EQ(AllEntriesFor(
"foo"),
"[ DEL, v1 ]");
1256 ASSERT_OK(dbfull()->TEST_CompactMemTable());
1257 ASSERT_EQ(AllEntriesFor(
"foo"),
"[ DEL, v1 ]");
1258 dbfull()->TEST_CompactRange(last-2, NULL, NULL);
1260 ASSERT_EQ(AllEntriesFor(
"foo"),
"[ DEL, v1 ]");
1261 dbfull()->TEST_CompactRange(last-1, NULL, NULL);
1269 ASSERT_EQ(config::kMaxMemCompactLevel, 2) <<
"Fix test to match config";
1274 dbfull()->TEST_CompactMemTable();
1277 dbfull()->TEST_CompactMemTable();
1286 dbfull()->TEST_CompactMemTable();
1290 dbfull()->TEST_CompactMemTable();
1294 dbfull()->TEST_CompactRange(1, NULL, NULL);
1295 dbfull()->TEST_CompactRange(2, NULL, NULL);
1302 dbfull()->TEST_CompactMemTable();
1305 }
while (ChangeOptions());
1321 DelayMilliseconds(1000);
1337 DelayMilliseconds(1000);
1347 DelayMilliseconds(1000);
1354 virtual const char* Name()
const {
return "leveldb.NewComparator"; }
1355 virtual int Compare(
const Slice& a,
const Slice& b)
const {
1358 virtual void FindShortestSeparator(std::string* s,
const Slice& l)
const {
1361 virtual void FindShortSuccessor(std::string* key)
const {
1366 Options new_options = CurrentOptions();
1368 Status s = TryReopen(&new_options);
1377 virtual const char* Name()
const {
return "test.NumberComparator"; }
1378 virtual int Compare(
const Slice& a,
const Slice& b)
const {
1379 return ToNumber(a) - ToNumber(b);
1381 virtual void FindShortestSeparator(std::string* s,
const Slice& l)
const {
1385 virtual void FindShortSuccessor(std::string* key)
const {
1389 static int ToNumber(
const Slice& x) {
1400 NumberComparator
cmp;
1401 Options new_options = CurrentOptions();
1406 DestroyAndReopen(&new_options);
1409 for (
int i = 0; i < 2; i++) {
1416 Compact(
"[0]",
"[9999]");
1419 for (
int run = 0; run < 2; run++) {
1420 for (
int i = 0; i < 1000; i++) {
1422 snprintf(buf,
sizeof(buf),
"[%d]", i*10);
1425 Compact(
"[0]",
"[1000000]");
1430 ASSERT_EQ(config::kMaxMemCompactLevel, 2)
1431 <<
"Need to update this test to match kMaxMemCompactLevel";
1433 MakeTables(3,
"p",
"q");
1445 Compact(
"p1",
"p9");
1449 MakeTables(3,
"c",
"e");
1457 MakeTables(1,
"a",
"z");
1464 std::string dbname =
test::TmpDir() +
"/db_options_test";
1505 ASSERT_TRUE(!s.
ok()) <<
"Locking did not prevent re-opening db";
1510 Options options = CurrentOptions();
1517 const int num_files = CountFiles();
1518 env_->no_space_.Release_Store(
env_);
1519 env_->sleep_counter_.Reset();
1520 for (
int i = 0; i < 5; i++) {
1521 for (
int level = 0; level < config::kNumLevels-1; level++) {
1522 dbfull()->TEST_CompactRange(level, NULL, NULL);
1525 env_->no_space_.Release_Store(NULL);
1533 Options options = CurrentOptions();
1540 env_->non_writable_.Release_Store(
env_);
1541 env_->sleep_counter_.Reset();
1542 env_->sleep_time_counter_.Reset();
1543 for (
int i = 0; i < 5; i++) {
1544 dbfull()->TEST_CompactRange(2, NULL, NULL);
1546 env_->non_writable_.Release_Store(NULL);
1549 DelayMilliseconds(1000);
1557 Options options = CurrentOptions();
1562 env_->non_writable_.Release_Store(
env_);
1563 std::string big(100000,
'x');
1565 for (
int i = 0; i < 20; i++) {
1566 fprintf(stderr,
"iter %d; errors %d\n", i, errors);
1567 if (!Put(
"foo", big).ok()) {
1569 DelayMilliseconds(100);
1573 env_->non_writable_.Release_Store(NULL);
1585 for (
int iter = 0; iter < 2; iter++) {
1587 ? &
env_->manifest_sync_error_
1588 : &
env_->manifest_write_error_;
1591 Options options = CurrentOptions();
1593 options.create_if_missing =
true;
1594 options.error_if_exists =
false;
1595 DestroyAndReopen(&options);
1600 dbfull()->TEST_CompactMemTable();
1602 const int last = config::kMaxMemCompactLevel;
1603 ASSERT_EQ(NumTableFilesAtLevel(last), 1);
1607 dbfull()->TEST_CompactRange(last, NULL, NULL);
1622 dbfull()->TEST_CompactMemTable();
1627 Options options = CurrentOptions();
1629 Status s = TryReopen(&options);
1638 const int num_files = CountFiles();
1639 for (
int i = 0; i < 10; i++) {
1647 env_->count_random_reads_ =
true;
1648 Options options = CurrentOptions();
1655 const int N = 10000;
1656 for (
int i = 0; i < N; i++) {
1660 for (
int i = 0; i < N; i += 100) {
1663 dbfull()->TEST_CompactMemTable();
1666 env_->delay_sstable_sync_.Release_Store(
env_);
1669 env_->random_read_counter_.Reset();
1670 for (
int i = 0; i < N; i++) {
1673 int reads =
env_->random_read_counter_.Read();
1674 fprintf(stderr,
"%d present => %d reads\n", N, reads);
1679 env_->random_read_counter_.Reset();
1680 for (
int i = 0; i < N; i++) {
1683 reads =
env_->random_read_counter_.Read();
1684 fprintf(stderr,
"%d missing => %d reads\n", N, reads);
1687 env_->delay_sstable_sync_.Release_Store(NULL);
1696 static const int kNumThreads = 4;
1697 static const int kTestSeconds = 10;
1698 static const int kNumKeys = 1000;
1712 static void MTThreadBody(
void*
arg) {
1713 MTThread* t =
reinterpret_cast<MTThread*
>(
arg);
1715 DB* db = t->state->test->db_;
1717 fprintf(stderr,
"... starting thread %d\n",
id);
1718 Random rnd(1000 +
id);
1721 while (t->state->stop.Acquire_Load() == NULL) {
1722 t->state->counter[
id].Release_Store(reinterpret_cast<void*>(counter));
1724 int key = rnd.Uniform(kNumKeys);
1726 snprintf(keybuf,
sizeof(keybuf),
"%016d", key);
1731 snprintf(valbuf,
sizeof(valbuf),
"%d.%d.%-1000d",
1732 key,
id, static_cast<int>(counter));
1733 ASSERT_OK(db->Put(WriteOptions(), Slice(keybuf), Slice(valbuf)));
1736 Status s = db->Get(ReadOptions(), Slice(keybuf), &value);
1737 if (s.IsNotFound()) {
1743 ASSERT_EQ(3, sscanf(value.c_str(),
"%d.%d.%d", &k, &w, &c)) <<
value;
1747 ASSERT_LE(c, reinterpret_cast<uintptr_t>(
1748 t->state->counter[w].Acquire_Load()));
1753 t->state->thread_done[
id].Release_Store(t);
1754 fprintf(stderr,
"... stopping thread %d after %d ops\n",
id,
int(counter));
1764 mt.stop.Release_Store(0);
1765 for (
int id = 0;
id < kNumThreads;
id++) {
1766 mt.counter[
id].Release_Store(0);
1767 mt.thread_done[
id].Release_Store(0);
1771 MTThread thread[kNumThreads];
1772 for (
int id = 0;
id < kNumThreads;
id++) {
1773 thread[
id].state = &mt;
1779 DelayMilliseconds(kTestSeconds * 1000);
1782 mt.stop.Release_Store(&mt);
1783 for (
int id = 0;
id < kNumThreads;
id++) {
1784 while (mt.thread_done[
id].Acquire_Load() == NULL) {
1785 DelayMilliseconds(100);
1788 }
while (ChangeOptions());
1792 typedef std::map<std::string, std::string>
KVMap;
1811 const Slice& key, std::string* value) {
1821 const KVMap* snapshot_state =
1823 return new ModelIter(snapshot_state,
false);
1847 handler.map_ = &
map_;
1848 return batch->
Iterate(&handler);
1855 for (
int i = 0; i < n; i++) {
1874 if (
map_->empty()) {
1897 static std::string RandomKey(
Random* rnd) {
1898 int len = (rnd->
OneIn(3)
1904 static bool CompareIterators(
int step,
1907 const Snapshot* model_snap,
1908 const Snapshot* db_snap) {
1909 ReadOptions options;
1910 options.snapshot = model_snap;
1911 Iterator* miter = model->NewIterator(options);
1912 options.snapshot = db_snap;
1913 Iterator* dbiter = db->NewIterator(options);
1916 for (miter->SeekToFirst(), dbiter->SeekToFirst();
1917 ok && miter->Valid() && dbiter->Valid();
1918 miter->Next(), dbiter->Next()) {
1920 if (miter->key().compare(dbiter->key()) != 0) {
1921 fprintf(stderr,
"step %d: Key mismatch: '%s' vs. '%s'\n",
1929 if (miter->value().compare(dbiter->value()) != 0) {
1930 fprintf(stderr,
"step %d: Value mismatch for key '%s': '%s' vs. '%s'\n",
1940 if (miter->Valid() != dbiter->Valid()) {
1941 fprintf(stderr,
"step %d: Mismatch at end of iterators: %d vs. %d\n",
1942 step, miter->Valid(), dbiter->Valid());
1946 fprintf(stderr,
"%d entries compared: ok=%d\n", count, ok);
1955 ModelDB model(CurrentOptions());
1956 const int N = 10000;
1960 for (
int step = 0; step < N; step++) {
1961 if (step % 100 == 0) {
1962 fprintf(stderr,
"Step %d of %d\n", step, N);
1967 k = RandomKey(&rnd);
1968 v = RandomString(&rnd,
1975 }
else if (p < 90) {
1976 k = RandomKey(&rnd);
1983 const int num = rnd.
Uniform(8);
1984 for (
int i = 0; i < num; i++) {
1985 if (i == 0 || !rnd.
OneIn(10)) {
1986 k = RandomKey(&rnd);
1992 v = RandomString(&rnd, rnd.
Uniform(10));
2002 if ((step % 100) == 0) {
2004 ASSERT_TRUE(CompareIterators(step, &model,
db_, model_snap, db_snap));
2020 }
while (ChangeOptions());
2025 snprintf(buf,
sizeof(buf),
"%016u", num);
2026 return std::string(buf);
2030 std::string dbname =
test::TmpDir() +
"/leveldb_test_benchmark";
2050 VersionSet vset(dbname, &options, NULL, &cmp);
2054 for (
int i = 0; i < num_base_files; i++) {
2057 vbase.AddFile(2, fnum++, 1 , start, limit);
2063 for (
int i = 0; i < iters; i++) {
2068 vedit.
AddFile(2, fnum++, 1 , start, limit);
2072 unsigned int us = stop_micros - start_micros;
2074 snprintf(buf,
sizeof(buf),
"%d", num_base_files);
2076 "BM_LogAndApply/%-6s %8d iters : %9u us (%7.0f us / iter)\n",
2077 buf, iters, us, ((
float)us) / iters);
2083 if (argc > 1 && std::string(argv[1]) ==
"--benchmark") {
virtual void CompactRange(const Slice *begin, const Slice *end)=0
std::string IterStatus(Iterator *iter)
virtual Status Write(const WriteOptions &options, WriteBatch *updates)
virtual Status Read(uint64_t offset, size_t n, Slice *result, char *scratch) const =0
virtual void CompactRange(const Slice *begin, const Slice *end)
Status GetChildren(const std::string &dir, std::vector< std::string > *r)
bool ParseFileName(const std::string &fname, uint64_t *number, FileType *type)
void * Acquire_Load() const
std::string Get(const std::string &k, const Snapshot *snapshot=NULL)
virtual Status Append(const Slice &data)=0
std::string DumpSSTableList()
AtomicCounter sleep_time_counter_
std::string MakeKey(unsigned int num)
Status TEST_CompactMemTable()
AtomicCounter random_read_counter_
port::AtomicPointer delay_sstable_sync_
virtual Status status() const
virtual Status Write(const WriteOptions &options, WriteBatch *batch)
virtual Status NewRandomAccessFile(const std::string &fname, RandomAccessFile **result)=0
virtual void SleepForMicroseconds(int micros)
Status NewWritableFile(const std::string &f, WritableFile **r)
void AddFile(int level, uint64_t file, uint64_t file_size, const InternalKey &smallest, const InternalKey &largest)
const Snapshot * snapshot
Status TryReopen(Options *options)
std::map< std::string, std::string, STLLessThan > KVMap
virtual Status status() const =0
virtual const Snapshot * GetSnapshot()
virtual void FindShortSuccessor(std::string *key) const =0
void DumpFileCounts(const char *label)
ModelIter(const KVMap *map, bool owned)
virtual void SleepForMicroseconds(int micros)=0
void Release_Store(void *v)
virtual Iterator * NewIterator(const ReadOptions &options)=0
bool ParseInternalKey(const Slice &internal_key, ParsedInternalKey *result)
Status LogAndApply(VersionEdit *edit, port::Mutex *mu) EXCLUSIVE_LOCKS_REQUIRED(mu)
void Delete(const Slice &key)
virtual Slice value() const =0
void FillLevels(const std::string &smallest, const std::string &largest)
Iterator * TEST_NewInternalIterator()
Status DestroyDB(const std::string &dbname, const Options &options)
virtual void SeekToLast()=0
std::string TableFileName(const std::string &name, uint64_t number)
port::AtomicPointer manifest_sync_error_
uint64_t Size(const Slice &start, const Slice &limit)
virtual bool Valid() const
virtual Status Put(const WriteOptions &o, const Slice &k, const Slice &v)
void Reopen(Options *options=NULL)
virtual void ReleaseSnapshot(const Snapshot *snapshot)
virtual void GetApproximateSizes(const Range *range, int n, uint64_t *sizes)=0
unsigned long long uint64_t
static Status Open(const Options &options, const std::string &name, DB **dbptr)
TEST(CorruptionTest, Recovery)
virtual void Seek(const Slice &target)=0
std::string EscapeString(const Slice &value)
ModelDB(const Options &options)
const FilterPolicy * NewBloomFilterPolicy(int bits_per_key)
static Status NotFound(const Slice &msg, const Slice &msg2=Slice())
virtual void SeekToFirst()=0
Status DeleteFile(const std::string &f)
virtual void CompactRange(const Slice *start, const Slice *end)
std::string const dbname_
virtual bool GetProperty(const Slice &property, std::string *value)
std::string AllEntriesFor(const Slice &user_key)
virtual Status Get(const ReadOptions &options, const Slice &key, std::string *value)
virtual Status Delete(const WriteOptions &, const Slice &key)
virtual Status Delete(const WriteOptions &o, const Slice &key)
void BM_LogAndApply(int iters, int num_base_files)
Status NewRandomAccessFile(const std::string &f, RandomAccessFile **r)
uint32_t Skewed(int max_log)
Status Iterate(Handler *handler) const
virtual Status Put(const WriteOptions &, const Slice &key, const Slice &value)
virtual void Seek(const Slice &k)
virtual void ReleaseSnapshot(const Snapshot *snapshot)
const FilterPolicy * filter_policy
void DeleteFile(int level, uint64_t file)
Status Delete(const std::string &k)
virtual Iterator * NewIterator(const ReadOptions &)
Cache * NewLRUCache(size_t capacity)
const Comparator * BytewiseComparator()
CompressionType compression
virtual Status Get(const ReadOptions &options, const Slice &key, std::string *value)=0
virtual void FindShortestSeparator(std::string *start, const Slice &limit) const =0
virtual int Compare(const Slice &a, const Slice &b) const =0
Status Put(const std::string &k, const std::string &v)
virtual bool Valid() const =0
std::string FilesPerLevel()
port::AtomicPointer manifest_write_error_
virtual void SeekToLast()
void MakeTables(int n, const std::string &small, const std::string &large)
void DestroyAndReopen(Options *options=NULL)
virtual Slice key() const
KVMap::const_iterator iter_
port::AtomicPointer no_space_
virtual Iterator * NewIterator(const ReadOptions &options)
int NumTableFilesAtLevel(int level)
port::AtomicPointer non_writable_
virtual Slice key() const =0
virtual Status NewWritableFile(const std::string &fname, WritableFile **result)=0
std::string RandomKey(Random *rnd, int len)
Slice RandomString(Random *rnd, int len, std::string *dst)
virtual bool GetProperty(const Slice &property, std::string *value)=0
port::AtomicPointer thread_done[kNumThreads]
AtomicCounter sleep_counter_
virtual void GetApproximateSizes(const Range *r, int n, uint64_t *sizes)
int main(int argc, char **argv)
virtual void SeekToFirst()
port::AtomicPointer counter[kNumThreads]
std::string ToString() const
virtual void StartThread(void(*function)(void *arg), void *arg)=0
virtual const Snapshot * GetSnapshot()
virtual Status Delete(const WriteOptions &options, const Slice &key)=0
void Compact(const Slice &start, const Slice &limit)
void Put(const Slice &key, const Slice &value)
const FilterPolicy * filter_policy_
virtual Slice value() const
const Comparator * comparator
std::string NumberToString(uint64_t num)
int atoi(const std::string &str)
static Status IOError(const Slice &msg, const Slice &msg2=Slice())
virtual Status Put(const WriteOptions &options, const Slice &key, const Slice &value)=0
std::string ToString() const
virtual uint64_t NowMicros()=0