@ -0,0 +1,88 @@ | |||||
#include "fielddb/field_db.h" | |||||
#include <cstdint> | |||||
#include <vector> | |||||
#include "leveldb/db.h" | |||||
#include "leveldb/env.h" | |||||
#include "leveldb/options.h" | |||||
#include "leveldb/status.h" | |||||
#include "util/serialize_value.h" | |||||
namespace leveldb { | |||||
//TODO:打开fieldDB | |||||
static Status OpenFieldDB(const Options& options,const std::string& name,DB** dbptr) { | |||||
// options.env->CreateDir("./abc") | |||||
return Status::OK(); | |||||
} | |||||
Status FieldDB::Put(const WriteOptions &options, const Slice &key, const Slice &value) { | |||||
return kvDB->Put(options, key, value); | |||||
} | |||||
// TODO:需要对是否进行index更新做处理 | |||||
Status FieldDB::PutFields(const WriteOptions &, const Slice &key, const FieldArray &fields) { | |||||
return Status::OK(); | |||||
} | |||||
Status FieldDB::Delete(const WriteOptions &options, const Slice &key) { | |||||
return kvDB->Delete(options, key); | |||||
} | |||||
// TODO:根据updates里面的东西,要对是否需要更新index进行分别处理 | |||||
Status FieldDB::Write(const WriteOptions &options, WriteBatch *updates) { | |||||
return Status::OK(); | |||||
} | |||||
Status FieldDB::Get(const ReadOptions &options, const Slice &key, std::string *value) { | |||||
return kvDB->Get(options, key, value); | |||||
} | |||||
Status FieldDB::GetFields(const ReadOptions &options, const Slice &key, FieldArray *fields) { | |||||
std::string value; | |||||
Status status; | |||||
status = kvDB->Get(options, key, &value); | |||||
if(status.ok() == false) return status; | |||||
fields = ParseValue(value); | |||||
return status; | |||||
} | |||||
std::vector<std::string> FieldDB::FindKeysByField(Field &field) { | |||||
std::vector<std::string> result; | |||||
auto iter = kvDB->NewIterator(ReadOptions()); | |||||
for(iter->SeekToFirst();iter->Valid();iter->Next()) { | |||||
InternalFieldArray fields(iter->value()); | |||||
if(fields.HasField(field)) { | |||||
result.push_back(iter->key().ToString()); | |||||
} | |||||
} | |||||
return result; | |||||
} | |||||
Iterator * FieldDB::NewIterator(const ReadOptions &options) { | |||||
return kvDB->NewIterator(options); | |||||
} | |||||
// TODO:使用统一seq进行snapshot管理 | |||||
const Snapshot * FieldDB::GetSnapshot() { | |||||
return kvDB->GetSnapshot(); | |||||
} | |||||
// TODO:同上 | |||||
void FieldDB::ReleaseSnapshot(const Snapshot *snapshot) { | |||||
kvDB->ReleaseSnapshot(snapshot); | |||||
} | |||||
bool FieldDB::GetProperty(const Slice &property, std::string *value) { | |||||
return kvDB->GetProperty(property, value) | indexDB->GetProperty(property, value); | |||||
} | |||||
void FieldDB::GetApproximateSizes(const Range *range, int n, uint64_t *sizes) { | |||||
uint64_t temp = 0; | |||||
kvDB->GetApproximateSizes(range, n, sizes); | |||||
indexDB->GetApproximateSizes(range, n, &temp); | |||||
*sizes += temp; | |||||
} | |||||
void FieldDB::CompactRange(const Slice *begin, const Slice *end) { | |||||
kvDB->CompactRange(begin, end); | |||||
} | |||||
} // end of namespace |
@ -0,0 +1,33 @@ | |||||
#include "db/db_impl.h" | |||||
#include "leveldb/db.h" | |||||
#include "leveldb/options.h" | |||||
#include "leveldb/status.h" | |||||
namespace leveldb{ | |||||
class FieldDB:leveldb::DB { | |||||
public: | |||||
/*lab1的要求*/ | |||||
Status Put(const WriteOptions &options, const Slice &key, const Slice &value) override; | |||||
Status PutFields(const WriteOptions &, const Slice &key, const FieldArray &fields) override; | |||||
Status Delete(const WriteOptions &options, const Slice &key) override; | |||||
Status Write(const WriteOptions &options, WriteBatch *updates) override; | |||||
Status Get(const ReadOptions &options, const Slice &key, std::string *value) override; | |||||
Status GetFields(const ReadOptions &options, const Slice &key, FieldArray *fields) override; | |||||
std::vector<std::string> FindKeysByField(Field &field) override; | |||||
Iterator * NewIterator(const ReadOptions &options) override; | |||||
const Snapshot * GetSnapshot() override; | |||||
void ReleaseSnapshot(const Snapshot *snapshot) override; | |||||
bool GetProperty(const Slice &property, std::string *value) override; | |||||
void GetApproximateSizes(const Range *range, int n, uint64_t *sizes) override; | |||||
void CompactRange(const Slice *begin, const Slice *end) override; | |||||
/*与索引相关*/ | |||||
bool CreateIndexOnField(const std::string& field_name); | |||||
bool DeleteIndex(std::string &field_name); | |||||
std::vector<std::string> QueryByIndex(Field &field); | |||||
private: | |||||
static Status OpenFieldDB(const Options& options,const std::string& name,DB** dbptr); | |||||
leveldb::DBImpl *indexDB; | |||||
leveldb::DBImpl *kvDB; | |||||
}; | |||||
} // end of namespace |
@ -1,13 +1,56 @@ | |||||
#ifndef STORAGE_LEVELDB_UTIL_SERIALIZE_VALUE_H_ | #ifndef STORAGE_LEVELDB_UTIL_SERIALIZE_VALUE_H_ | ||||
#define STORAGE_LEVELDB_UTIL_SERIALIZE_VALUE_H_ | #define STORAGE_LEVELDB_UTIL_SERIALIZE_VALUE_H_ | ||||
#include <iostream> | |||||
#include <string> | #include <string> | ||||
#include <vector> | #include <vector> | ||||
#include <map> | |||||
#include "leveldb/slice.h" | |||||
#include "util/coding.h" | |||||
namespace leveldb{ | namespace leveldb{ | ||||
using Field = std::pair<std::string, std::string>; // field_name:field_value | |||||
using FieldArray = std::vector<std::pair<std::string, std::string>>; | |||||
using Field = std::pair<std::string, std::string>; // field_name:field_value | |||||
using FieldArray = std::vector<std::pair<std::string, std::string>>; | |||||
std::string SerializeValue(const FieldArray& fields); | |||||
FieldArray *ParseValue(const std::string& value_str); | |||||
std::string SerializeValue(const FieldArray& fields); | |||||
FieldArray *ParseValue(const std::string& value_str); | |||||
class InternalFieldArray { | |||||
public: | |||||
using FieldMap = std::map<std::string,std::string>; | |||||
InternalFieldArray(const FieldArray &fields, bool to_map = false):fields(fields),isMapped(false) { | |||||
if(to_map) Map(); | |||||
} | |||||
InternalFieldArray(const std::string& value_str) { | |||||
Slice valueSlice(value_str); | |||||
Slice nameSlice,valSlice; | |||||
while(GetLengthPrefixedSlice(&valueSlice, &nameSlice)) { | |||||
if(GetLengthPrefixedSlice(&valueSlice, &valueSlice)) { | |||||
map[nameSlice.ToString()] = valueSlice.ToString(); | |||||
} else { | |||||
std::cout << "name and val not match!" << std::endl; | |||||
} | |||||
nameSlice.clear(); | |||||
valSlice.clear(); | |||||
} | |||||
} | |||||
InternalFieldArray(const Slice& slice):leveldb::InternalFieldArray(slice.ToString()) {} | |||||
//将vector变为用map存 | |||||
void Map(); | |||||
std::string Serialize(); | |||||
bool HasField(const Field& field); | |||||
private: | |||||
bool isMapped; | |||||
const FieldArray fields; | |||||
FieldMap map; | |||||
}; | |||||
} | } | ||||
#endif | #endif |