小组成员:姚凯文(kevinyao0901),姜嘉琪
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

225 line
5.9 KiB

3 週之前
3 週之前
3 週之前
3 週之前
3 週之前
3 週之前
  1. #include "gtest/gtest.h"
  2. #include "leveldb/env.h"
  3. #include "leveldb/db.h"
  4. #include <unordered_set>
  5. using namespace leveldb;
  6. constexpr int value_size = 2048;
  7. constexpr int data_size = 128 << 20;
  8. //--------------------------------------------------------------
  9. void PrintAllKeys(DB *db) {
  10. // 创建一个读选项对象
  11. ReadOptions readOptions;
  12. int LeftKeyCount = 0;
  13. // 创建迭代器
  14. std::unique_ptr<Iterator> it(db->NewIterator(readOptions));
  15. int cnt = 20;
  16. // 遍历所有键
  17. for (it->SeekToFirst(); it->Valid()&&cnt; it->Next()) {
  18. std::string key = it->key().ToString();
  19. std::string value = it->value().ToString();
  20. std::cout << "Key: " << key << std::endl;
  21. LeftKeyCount++;
  22. cnt--;
  23. }
  24. // 检查迭代器的有效性
  25. if (!it->status().ok()) {
  26. std::cerr << "Error iterating through keys: " << it->status().ToString() << std::endl;
  27. }
  28. std::cerr << "Key hasn't been deleted: " << LeftKeyCount << std::endl;
  29. }
  30. //------------------------------------------------------------------
  31. Status OpenDB(std::string dbName, DB **db) {
  32. Options options;
  33. options.create_if_missing = true;
  34. return DB::Open(options, dbName, db);
  35. }
  36. void InsertData(DB *db, uint64_t ttl/* second */) {
  37. WriteOptions writeOptions;
  38. int key_num = data_size / value_size;
  39. srand(42);
  40. // 用于存储成功写入的唯一键
  41. std::unordered_set<std::string> unique_keys;
  42. for (int i = 0; i < key_num; i++) {
  43. std::string key;
  44. do {
  45. int key_ = rand() % key_num + 1;
  46. key = std::to_string(key_);
  47. } while (unique_keys.find(key) != unique_keys.end()); // 检查是否已存在
  48. std::string value(value_size, 'a');
  49. // 判断 key 是否在范围内
  50. if (key >= "-" && key < "A") {
  51. //std::cout << "Key: " << key << " is within the range (-, A)" << std::endl;
  52. } else {
  53. std::cout << "Key: " << key << " is outside the range (-, A)" << std::endl;
  54. return;
  55. }
  56. Status status = db->Put(writeOptions, key, value, ttl);
  57. if (!status.ok()) {
  58. // 输出失败的状态信息并退出循环
  59. std::cerr << "Failed to write key: " << key
  60. << ", Status: " << status.ToString() << std::endl;
  61. } else {
  62. unique_keys.insert(key); // 插入集合中,如果已经存在则不会重复插入
  63. }
  64. }
  65. Iterator* iter = db->NewIterator(ReadOptions());
  66. iter->SeekToFirst();
  67. std::cout << "Data base First key: " << iter->key().ToString() << std::endl;
  68. iter->SeekToLast();
  69. std::cout << "Data base last key: " << iter->key().ToString() << std::endl;
  70. delete iter;
  71. // 打印成功写入的唯一键的数量
  72. std::cout << "Total unique keys successfully written: " << unique_keys.size() << std::endl;
  73. }
  74. void GetData(DB *db, int size = (1 << 30)) {
  75. ReadOptions readOptions;
  76. int key_num = data_size / value_size;
  77. // 点查
  78. srand(42);
  79. for (int i = 0; i < 100; i++) {
  80. int key_ = rand() % key_num+1;
  81. std::string key = std::to_string(key_);
  82. std::string value;
  83. db->Get(readOptions, key, &value);
  84. }
  85. Iterator* iter = db->NewIterator(ReadOptions());
  86. iter->SeekToFirst();
  87. std::cout << "Data base First key: " << iter->key().ToString() << std::endl;
  88. int cnt = 0;
  89. while (iter->Valid())
  90. {
  91. cnt++;
  92. iter->Next();
  93. }
  94. std::cout << "Total key cnt: " << cnt << "\n";
  95. delete iter;
  96. }
  97. TEST(TestTTL, ReadTTL) {
  98. DB *db;
  99. if(OpenDB("testdb", &db).ok() == false) {
  100. std::cerr << "open db failed" << std::endl;
  101. abort();
  102. }
  103. uint64_t ttl = 20;
  104. InsertData(db, ttl);
  105. ReadOptions readOptions;
  106. Status status;
  107. int key_num = data_size / value_size;
  108. srand(42);
  109. for (int i = 0; i < 100; i++) {
  110. int key_ = rand() % key_num+1;
  111. std::string key = std::to_string(key_);
  112. std::string value;
  113. status = db->Get(readOptions, key, &value);
  114. // 检查 status 并打印出失败的状态信息
  115. if (!status.ok()) {
  116. std::cerr << "Key: " << key << ", Status: " << status.ToString() << std::endl;
  117. }
  118. ASSERT_TRUE(status.ok());
  119. }
  120. Env::Default()->SleepForMicroseconds(ttl * 1000000);
  121. srand(42);
  122. for (int i = 0; i < 100; i++) {
  123. int key_ = rand() % key_num+1;
  124. std::string key = std::to_string(key_);
  125. std::string value;
  126. status = db->Get(readOptions, key, &value);
  127. // 检查 status 并打印出失败的状态信息
  128. if (status.ok()) {
  129. std::cerr << "Key: " << key << ", Status: " << status.ToString() << std::endl;
  130. }
  131. ASSERT_FALSE(status.ok());
  132. }
  133. delete db;
  134. }
  135. TEST(TestTTL, CompactionTTL) {
  136. DB *db;
  137. leveldb::Options options;
  138. // options.write_buffer_size = 1024*1024*1024;
  139. // options.max_file_size = 1024*1024*1024;
  140. leveldb::DestroyDB("testdb", options);
  141. if(OpenDB("testdb", &db).ok() == false) {
  142. std::cerr << "open db failed" << std::endl;
  143. abort();
  144. }
  145. uint64_t ttl = 20;
  146. leveldb::Range ranges[1];
  147. ranges[0] = leveldb::Range("-", "A");
  148. uint64_t sizes[1];
  149. db->GetApproximateSizes(ranges, 1, sizes);
  150. ASSERT_EQ(sizes[0], 0);
  151. InsertData(db, ttl);
  152. //leveldb::Range ranges[1];
  153. ranges[0] = leveldb::Range("-", "A");
  154. //uint64_t sizes[1];
  155. db->GetApproximateSizes(ranges, 1, sizes);
  156. ASSERT_GT(sizes[0], 0);
  157. ttl += 10;
  158. Env::Default()->SleepForMicroseconds(ttl * 1000000);
  159. std::cout << "Start drop\n";
  160. db->CompactRange(nullptr, nullptr);
  161. ranges[0] = leveldb::Range("-", "A");
  162. db->GetApproximateSizes(ranges, 1, sizes);
  163. PrintAllKeys(db);
  164. ASSERT_EQ(sizes[0], 0);
  165. delete db;
  166. }
  167. int main(int argc, char** argv) {
  168. srand(42);
  169. // All tests currently run with the same read-only file limits.
  170. testing::InitGoogleTest(&argc, argv);
  171. return RUN_ALL_TESTS();
  172. }