LevelDB二级索引实现 姚凯文(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.

155 lines
4.8 KiB

  1. #include "leveldb/db.h"
  2. #include <iostream>
  3. #include <sstream>
  4. #include <vector>
  5. #include <string>
  6. #include <cassert>
  7. using namespace std;
  8. using namespace leveldb;
  9. // 定义字段类型别名
  10. using Field = std::pair<std::string, std::string>;
  11. using FieldArray = std::vector<Field>;
  12. // 二进制序列化函数
  13. std::string SerializeValue(const FieldArray& fields) {
  14. std::ostringstream oss;
  15. uint32_t num_fields = fields.size();
  16. // 写入字段数量
  17. oss.write(reinterpret_cast<const char*>(&num_fields), sizeof(num_fields));
  18. // 写入每个字段的长度和内容
  19. for (const auto& field : fields) {
  20. uint32_t name_length = field.first.size();
  21. uint32_t value_length = field.second.size();
  22. // 写入字段名长度和字段名
  23. oss.write(reinterpret_cast<const char*>(&name_length), sizeof(name_length));
  24. oss.write(field.first.data(), name_length);
  25. // 写入字段值长度和字段值
  26. oss.write(reinterpret_cast<const char*>(&value_length), sizeof(value_length));
  27. oss.write(field.second.data(), value_length);
  28. }
  29. return oss.str();
  30. }
  31. // 二进制反序列化函数
  32. FieldArray ParseValue(const std::string& value_str) {
  33. FieldArray fields;
  34. std::istringstream iss(value_str);
  35. uint32_t num_fields = 0;
  36. iss.read(reinterpret_cast<char*>(&num_fields), sizeof(num_fields)); // 读取字段数量
  37. for (uint32_t i = 0; i < num_fields; ++i) {
  38. uint32_t name_length = 0, value_length = 0;
  39. // 读取字段名长度和字段名
  40. iss.read(reinterpret_cast<char*>(&name_length), sizeof(name_length));
  41. std::string field_name(name_length, '\0');
  42. iss.read(&field_name[0], name_length);
  43. // 读取字段值长度和字段值
  44. iss.read(reinterpret_cast<char*>(&value_length), sizeof(value_length));
  45. std::string field_value(value_length, '\0');
  46. iss.read(&field_value[0], value_length);
  47. fields.emplace_back(field_name, field_value);
  48. }
  49. return fields;
  50. }
  51. // 查询函数:根据字段查找所有包含该字段的 Key
  52. std::vector<std::string> FindKeysByField(leveldb::DB* db, const Field& field) {
  53. std::vector<std::string> keys;
  54. Iterator* it = db->NewIterator(ReadOptions());
  55. for (it->SeekToFirst(); it->Valid(); it->Next()) {
  56. std::string key = it->key().ToString();
  57. std::string value = it->value().ToString();
  58. FieldArray fields = ParseValue(value);
  59. // 查找是否有匹配的字段
  60. for (const auto& f : fields) {
  61. if (f.first == field.first && f.second == field.second) {
  62. keys.push_back(key);
  63. break;
  64. }
  65. }
  66. }
  67. delete it;
  68. return keys;
  69. }
  70. int main() {
  71. // 创建 LevelDB 数据库
  72. DB* db = nullptr;
  73. Options op;
  74. op.create_if_missing = true;
  75. Status status = DB::Open(op, "testdb", &db);
  76. assert(status.ok());
  77. // 插入两条数据,包含多个字段
  78. FieldArray fields1 = {
  79. {"name", "Customer#000000001"},
  80. {"address", "IVhzIApeRb"},
  81. {"phone", "25-989-741-2988"}
  82. };
  83. db->Put(WriteOptions(), "k_1", SerializeValue(fields1));
  84. FieldArray fields2 = {
  85. {"name", "Customer#000000002"},
  86. {"address", "N3qjPOETGc"},
  87. {"phone", "12-345-678-9012"}
  88. };
  89. db->Put(WriteOptions(), "k_2", SerializeValue(fields2));
  90. // 插入带有特殊字符的字段
  91. FieldArray fields3 = {
  92. {"name", "Customer=000000003"},
  93. {"address", "N3qj;POETGc"},
  94. {"phone", "12-345-678-9012"}
  95. };
  96. db->Put(WriteOptions(), "k_3", SerializeValue(fields3));
  97. // 读取并反序列化数据
  98. string value_ret1, value_ret2, value_ret3;
  99. db->Get(ReadOptions(), "k_1", &value_ret1);
  100. db->Get(ReadOptions(), "k_2", &value_ret2);
  101. db->Get(ReadOptions(), "k_3", &value_ret3);
  102. cout << "Deserialized fields for key k_1:" << endl;
  103. for (const auto& field : ParseValue(value_ret1)) {
  104. cout << field.first << ": " << field.second << endl;
  105. }
  106. cout << "\nDeserialized fields for key k_2:" << endl;
  107. for (const auto& field : ParseValue(value_ret2)) {
  108. cout << field.first << ": " << field.second << endl;
  109. }
  110. cout << "\nDeserialized fields for key k_3:" << endl;
  111. for (const auto& field : ParseValue(value_ret3)) {
  112. cout << field.first << ": " << field.second << endl;
  113. }
  114. // 查询功能测试:查找所有 name = "Customer#000000001" 的 key
  115. Field search_field = {"name", "Customer#000000001"};
  116. auto keys = FindKeysByField(db, search_field);
  117. // 输出查询结果
  118. cout << "\nFound keys for field " << search_field.first << " = " << search_field.second << ":" << endl;
  119. for (const auto& key : keys) {
  120. cout << key << endl;
  121. }
  122. delete db;
  123. return 0;
  124. }