xref: /aosp_15_r20/external/leveldb/db/autocompact_test.cc (revision 9507f98c5f32dee4b5f9e4a38cd499f3ff5c4490)
1 // Copyright (c) 2013 The LevelDB Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. See the AUTHORS file for names of contributors.
4 
5 #include "gtest/gtest.h"
6 #include "db/db_impl.h"
7 #include "leveldb/cache.h"
8 #include "leveldb/db.h"
9 #include "util/testutil.h"
10 
11 namespace leveldb {
12 
13 class AutoCompactTest : public testing::Test {
14  public:
AutoCompactTest()15   AutoCompactTest() {
16     dbname_ = testing::TempDir() + "autocompact_test";
17     tiny_cache_ = NewLRUCache(100);
18     options_.block_cache = tiny_cache_;
19     DestroyDB(dbname_, options_);
20     options_.create_if_missing = true;
21     options_.compression = kNoCompression;
22     EXPECT_LEVELDB_OK(DB::Open(options_, dbname_, &db_));
23   }
24 
~AutoCompactTest()25   ~AutoCompactTest() {
26     delete db_;
27     DestroyDB(dbname_, Options());
28     delete tiny_cache_;
29   }
30 
Key(int i)31   std::string Key(int i) {
32     char buf[100];
33     std::snprintf(buf, sizeof(buf), "key%06d", i);
34     return std::string(buf);
35   }
36 
Size(const Slice & start,const Slice & limit)37   uint64_t Size(const Slice& start, const Slice& limit) {
38     Range r(start, limit);
39     uint64_t size;
40     db_->GetApproximateSizes(&r, 1, &size);
41     return size;
42   }
43 
44   void DoReads(int n);
45 
46  private:
47   std::string dbname_;
48   Cache* tiny_cache_;
49   Options options_;
50   DB* db_;
51 };
52 
53 static const int kValueSize = 200 * 1024;
54 static const int kTotalSize = 100 * 1024 * 1024;
55 static const int kCount = kTotalSize / kValueSize;
56 
57 // Read through the first n keys repeatedly and check that they get
58 // compacted (verified by checking the size of the key space).
DoReads(int n)59 void AutoCompactTest::DoReads(int n) {
60   std::string value(kValueSize, 'x');
61   DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
62 
63   // Fill database
64   for (int i = 0; i < kCount; i++) {
65     ASSERT_LEVELDB_OK(db_->Put(WriteOptions(), Key(i), value));
66   }
67   ASSERT_LEVELDB_OK(dbi->TEST_CompactMemTable());
68 
69   // Delete everything
70   for (int i = 0; i < kCount; i++) {
71     ASSERT_LEVELDB_OK(db_->Delete(WriteOptions(), Key(i)));
72   }
73   ASSERT_LEVELDB_OK(dbi->TEST_CompactMemTable());
74 
75   // Get initial measurement of the space we will be reading.
76   const int64_t initial_size = Size(Key(0), Key(n));
77   const int64_t initial_other_size = Size(Key(n), Key(kCount));
78 
79   // Read until size drops significantly.
80   std::string limit_key = Key(n);
81   for (int read = 0; true; read++) {
82     ASSERT_LT(read, 100) << "Taking too long to compact";
83     Iterator* iter = db_->NewIterator(ReadOptions());
84     for (iter->SeekToFirst();
85          iter->Valid() && iter->key().ToString() < limit_key; iter->Next()) {
86       // Drop data
87     }
88     delete iter;
89     // Wait a little bit to allow any triggered compactions to complete.
90     Env::Default()->SleepForMicroseconds(1000000);
91     uint64_t size = Size(Key(0), Key(n));
92     std::fprintf(stderr, "iter %3d => %7.3f MB [other %7.3f MB]\n", read + 1,
93                  size / 1048576.0, Size(Key(n), Key(kCount)) / 1048576.0);
94     if (size <= initial_size / 10) {
95       break;
96     }
97   }
98 
99   // Verify that the size of the key space not touched by the reads
100   // is pretty much unchanged.
101   const int64_t final_other_size = Size(Key(n), Key(kCount));
102   ASSERT_LE(final_other_size, initial_other_size + 1048576);
103   ASSERT_GE(final_other_size, initial_other_size / 5 - 1048576);
104 }
105 
TEST_F(AutoCompactTest,ReadAll)106 TEST_F(AutoCompactTest, ReadAll) { DoReads(kCount); }
107 
TEST_F(AutoCompactTest,ReadHalf)108 TEST_F(AutoCompactTest, ReadHalf) { DoReads(kCount / 2); }
109 
110 }  // namespace leveldb
111 
main(int argc,char ** argv)112 int main(int argc, char** argv) {
113   testing::InitGoogleTest(&argc, argv);
114   return RUN_ALL_TESTS();
115 }
116