@ -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_ | |||
#define STORAGE_LEVELDB_UTIL_SERIALIZE_VALUE_H_ | |||
#include <iostream> | |||
#include <string> | |||
#include <vector> | |||
#include <map> | |||
#include "leveldb/slice.h" | |||
#include "util/coding.h" | |||
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 |