소스 검색

add api and corresponding implemetation based on FieldDB

main
kevinyao0901 1 개월 전
부모
커밋
d215f1602b
3개의 변경된 파일185개의 추가작업 그리고 5개의 파일을 삭제
  1. +113
    -1
      db/db_impl.cc
  2. +27
    -1
      db/db_impl.h
  3. +45
    -3
      include/leveldb/db.h

+ 113
- 1
db/db_impl.cc 파일 보기

@ -11,6 +11,7 @@
#include <set>
#include <string>
#include <vector>
#include <sstream>
#include "db/builder.h"
#include "db/db_iter.h"
@ -35,6 +36,7 @@
#include "util/logging.h"
#include "util/mutexlock.h"
namespace leveldb {
const int kNumNonTableCacheFiles = 10;
@ -123,8 +125,33 @@ static int TableCacheSize(const Options& sanitized_options) {
return sanitized_options.max_open_files - kNumNonTableCacheFiles;
}
//Secondary Index ToDo
FieldDb::FieldDb(DB* kv_db, DB* index_db)
: kvDb(kv_db), // 初始化 kvDb 成员变量
indexDb(index_db), // 初始化 indexDb 成员变量
fieldWithIndex(), // 初始化字段索引列表
taskQueue() { // 初始化任务队列
// 如果需要在构造函数中做额外的初始化操作,可以在这里进行
}
FieldDb::~FieldDb() {
// 清空 taskQueue 中的所有任务
while (!taskQueue.empty()) {
taskQueue.pop();
}
// 对于 kvDb 和 indexDb,如果它们需要手动释放资源,可以在这里进行处理
// 注意:通常 leveldb 会负责释放它们的资源,如果不需要手动释放,可以忽略这一步
// 如果 kvDb 和 indexDb 是由 FieldDb 管理的并且需要释放,可以在此释放
// delete kvDb; // 假设我们负责销毁 kvDb
// delete indexDb; // 假设我们负责销毁 indexDb
}
//ToDo end
DBImpl::DBImpl(const Options& raw_options, const std::string& dbname)
: env_(raw_options.env),
: /*Secondary Index ToDo*/ FieldDb(kvDb, indexDb), // 调用 FieldDb 构造函数初始化 kvDb 和 indexDb /*ToDo end */
env_(raw_options.env),
internal_comparator_(raw_options.comparator),
internal_filter_policy_(raw_options.filter_policy),
options_(SanitizeOptions(dbname, &internal_comparator_,
@ -596,6 +623,90 @@ void DBImpl::CompactRange(const Slice* begin, const Slice* end) {
}
}
//Secondary index ToDo
// 定义字段类型别名
Status DBImpl::CreateIndexOnField(const std::string& fieldName) {
// 首先检查字段是否已经创建了索引
for (const auto& field : fieldWithIndex) {
if (field == fieldName) {
return Status::InvalidArgument("Index already exists for this field");
}
}
// 将索引字段添加到 fieldWithIndex 列表中
fieldWithIndex.push_back(fieldName);
// 在索引数据库中为字段创建索引(这只是一个简单的例子,实际的索引创建可能会更复杂)
std::string key = "index:" + fieldName;
std::string value = "index_created";
Status s = indexDb->Put(WriteOptions(), Slice(key), Slice(value));
if (!s.ok()) {
return s;
}
return Status::OK();
}
Status DBImpl::DeleteIndex(const std::string& fieldName) {
auto it = std::find(fieldWithIndex.begin(), fieldWithIndex.end(), fieldName);
if (it == fieldWithIndex.end()) {
return Status::NotFound("Index not found for this field");
}
// 从列表中移除该字段
fieldWithIndex.erase(it);
// 删除索引数据库中的条目
std::string key = "index:" + fieldName;
Status s = indexDb->Delete(WriteOptions(), Slice(key));
if (!s.ok()) {
return s;
}
return Status::OK();
}
Status DBImpl::QueryByIndex(const std::string& fieldName, std::vector<std::string>* results) {
// 检查该字段是否有索引
auto it = std::find(fieldWithIndex.begin(), fieldWithIndex.end(), fieldName);
if (it == fieldWithIndex.end()) {
return Status::NotFound("No index found for this field");
}
// 执行查询操作(这是一个简单的查询方法,实际应用中可能会更复杂)
std::string key = "index:" + fieldName;
std::string value;
Status s = indexDb->Get(ReadOptions(), Slice(key), &value);
if (!s.ok()) {
return s;
}
// 假设我们通过值可以获取到索引的内容,添加到结果列表中
results->push_back(value); // 这里可以根据实际需求来处理查询结果
return Status::OK();
}
Status DBImpl::EncodeIndexKey(const std::string& fieldName, const std::string& key, std::string* encodedKey) {
// 简单的编码示例,可以根据需求修改
*encodedKey = fieldName + ":" + key;
return Status::OK();
}
Status DBImpl::DecodeIndexKey(const std::string& encodedKey, std::string* fieldName, std::string* originalKey) {
size_t pos = encodedKey.find(':');
if (pos == std::string::npos) {
return Status::InvalidArgument("Invalid encoded key");
}
*fieldName = encodedKey.substr(0, pos);
*originalKey = encodedKey.substr(pos + 1);
return Status::OK();
}
// ToDo end
void DBImpl::TEST_CompactRange(int level, const Slice* begin,
const Slice* end) {
assert(level >= 0);
@ -1542,6 +1653,7 @@ Status DB::Open(const Options& options, const std::string& dbname, DB** dbptr) {
return s;
}
Snapshot::~Snapshot() = default;
Status DestroyDB(const std::string& dbname, const Options& options) {

+ 27
- 1
db/db_impl.h 파일 보기

@ -9,6 +9,7 @@
#include <deque>
#include <set>
#include <string>
#include <utility>
#include "db/dbformat.h"
#include "db/log_writer.h"
@ -26,7 +27,7 @@ class Version;
class VersionEdit;
class VersionSet;
class DBImpl : public DB {
class DBImpl : /*Secondary Index ToDo*/ public DB , public FieldDb/*ToDo end*/{
public:
DBImpl(const Options& options, const std::string& dbname);
@ -51,6 +52,14 @@ class DBImpl : public DB {
// Extra methods (for testing) that are not in the public DB interface
//Secondary Index ToDo
// FieldDb
Status CreateIndexOnField(const std::string& fieldName) override;
Status DeleteIndex(const std::string& fieldName) override;
Status QueryByIndex(const std::string& fieldName, std::vector<std::string>* results) override;
//ToDo end
// Compact any files in the named level that overlap [*begin,*end]
void TEST_CompactRange(int level, const Slice* begin, const Slice* end);
@ -155,6 +164,14 @@ class DBImpl : public DB {
return internal_comparator_.user_comparator();
}
//Secondary Index ToDo
// FieldDb
DB* kvDb; //
DB* indexDb; //
std::vector<std::string> fieldWithIndex; //
std::queue<std::pair<bool, std::string>> taskQueue;
//ToDo end
// Constant after construction
Env* const env_;
const InternalKeyComparator internal_comparator_;
@ -203,8 +220,17 @@ class DBImpl : public DB {
Status bg_error_ GUARDED_BY(mutex_);
CompactionStats stats_[config::kNumLevels] GUARDED_BY(mutex_);
//Secondary Index ToDo
// Helper methods to interact with the underlying database
Status EncodeIndexKey(const std::string& fieldName, const std::string& key, std::string* encodedKey);
Status DecodeIndexKey(const std::string& encodedKey, std::string* fieldName, std::string* originalKey);
//ToDo end
};
// Sanitize db options. The caller should delete result.info_log if
// it is not equal to src.info_log.
Options SanitizeOptions(const std::string& db,

+ 45
- 3
include/leveldb/db.h 파일 보기

@ -7,6 +7,8 @@
#include <cstdint>
#include <cstdio>
#include <vector>
#include <queue>
#include "leveldb/export.h"
#include "leveldb/iterator.h"
@ -145,12 +147,52 @@ class LEVELDB_EXPORT DB {
// Therefore the following call will compact the entire database:
// db->CompactRange(nullptr, nullptr);
virtual void CompactRange(const Slice* begin, const Slice* end) = 0;
};
// Secondary index ToDo
// Definition of the FieldDb class to manage kvDb and indexDb
class LEVELDB_EXPORT FieldDb {
public:
FieldDb(DB* kv_db, DB* index_db);
virtual ~FieldDb();
// Open
static Status Open(const Options& options, const std::string& dbname, FieldDb** field_db);
// Add an index on the specified field
virtual Status CreateIndexOnField(const std::string& fieldName) = 0;
// Remove an index on the specified field
virtual Status DeleteIndex(const std::string& fieldName) = 0;
// Query the database using an index
virtual Status QueryByIndex(const std::string& fieldName, std::vector<std::string>* results) = 0;
// ----------------------------For TTL-----------------------------
// key设置ttl
virtual Status Put(const WriteOptions& options, const Slice& key,
const Slice& value, uint64_t ttl) = 0;
const Slice& value) = 0;
virtual Status Delete(const WriteOptions& options, const Slice& key) = 0;
virtual Status Write(const WriteOptions& options, WriteBatch* updates) = 0;
virtual Status Get(const ReadOptions& options, const Slice& key,
std::string* value) = 0;
virtual Iterator* NewIterator(const ReadOptions& options) = 0;
virtual const Snapshot* GetSnapshot() = 0;
virtual void ReleaseSnapshot(const Snapshot* snapshot) = 0;
virtual bool GetProperty(const Slice& property, std::string* value) = 0;
virtual void GetApproximateSizes(const Range* range, int n,
uint64_t* sizes) = 0;
virtual void CompactRange(const Slice* begin, const Slice* end) = 0;
private:
// Helper methods
virtual Status EncodeIndexKey(const std::string& fieldName, const std::string& key, std::string* encodedKey) = 0;
virtual Status DecodeIndexKey(const std::string& encodedKey, std::string* fieldName, std::string* originalKey) = 0;
DB* kvDb; // Original database (key-value store)
DB* indexDb; // Index database (secondary index)
std::vector<std::string> fieldWithIndex; // List of fields with indexes
std::queue<std::pair<bool, std::string>> taskQueue;
};
// ToDo end
// Destroy the contents of the specified database.
// Be very careful using this method.

불러오는 중...
취소
저장