diff --git a/README.md b/README.md index ee9e43d..05ee763 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # 实验报告 仓库地址 https://gitea.shuishan.net.cn/10225501448/leveldb_proj2 + +新建文件时 cmakelist 120行下面记得加进去 \ No newline at end of file diff --git a/db/db_impl.cc b/db/db_impl.cc index f96d245..f423733 100644 --- a/db/db_impl.cc +++ b/db/db_impl.cc @@ -34,6 +34,7 @@ #include "util/coding.h" #include "util/logging.h" #include "util/mutexlock.h" +#include "util/serialize_value.h" namespace leveldb { @@ -1164,6 +1165,18 @@ Status DBImpl::Get(const ReadOptions& options, const Slice& key, return s; } +Status DBImpl::GetFields(const ReadOptions& options, const Slice& key, + FieldArray* fields) { + std::string value; + Status s = DBImpl::Get(options, key, &value); + fields = ParseValue(value); + return s; +} + +std::vector DBImpl::FindKeysByField(Field &field){//todo + return std::vector(); +} + Iterator* DBImpl::NewIterator(const ReadOptions& options) { SequenceNumber latest_snapshot; uint32_t seed; @@ -1198,6 +1211,10 @@ Status DBImpl::Put(const WriteOptions& o, const Slice& key, const Slice& val) { return DB::Put(o, key, val); } +Status DBImpl::PutFields(const WriteOptions& o, const Slice& key, const FieldArray& fields) { + return DB::PutFields(o, key, fields); +} + Status DBImpl::Delete(const WriteOptions& options, const Slice& key) { return DB::Delete(options, key); } @@ -1491,6 +1508,11 @@ Status DB::Put(const WriteOptions& opt, const Slice& key, const Slice& value) { return Write(opt, &batch); } +Status DB::PutFields(const WriteOptions& opt, const Slice& key, const FieldArray& fields) { + std::string value = SerializeValue(fields); + DB::Put(opt, key, value); +} + Status DB::Delete(const WriteOptions& opt, const Slice& key) { WriteBatch batch; batch.Delete(key); diff --git a/db/db_impl.h b/db/db_impl.h index c7b0172..6848077 100644 --- a/db/db_impl.h +++ b/db/db_impl.h @@ -17,6 +17,7 @@ #include "leveldb/env.h" #include "port/port.h" #include "port/thread_annotations.h" +#include "util/serialize_value.h" namespace leveldb { @@ -38,10 +39,16 @@ class DBImpl : public DB { // Implementations of the DB interface Status Put(const WriteOptions&, const Slice& key, const Slice& value) override; + Status PutFields(const WriteOptions&, const Slice& key, + const FieldArray& fields) override; + Status Delete(const WriteOptions&, 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 FindKeysByField(Field &field) override; Iterator* NewIterator(const ReadOptions&) override; const Snapshot* GetSnapshot() override; void ReleaseSnapshot(const Snapshot* snapshot) override; diff --git a/db/db_test.cc b/db/db_test.cc index a4a84cd..2a5668f 100644 --- a/db/db_test.cc +++ b/db/db_test.cc @@ -2117,6 +2117,9 @@ class ModelDB : public DB { Status Put(const WriteOptions& o, const Slice& k, const Slice& v) override { return DB::Put(o, k, v); } + Status PutFields(const WriteOptions& o, const Slice& k, const FieldArray& v) override { + return DB::PutFields(o, k, v); + } Status Delete(const WriteOptions& o, const Slice& key) override { return DB::Delete(o, key); } @@ -2125,6 +2128,15 @@ class ModelDB : public DB { assert(false); // Not implemented return Status::NotFound(key); } + Status GetFields(const ReadOptions& options, const Slice& key, + FieldArray* value) override { + assert(false); // Not implemented + return Status::NotFound(key); + } + std::vector FindKeysByField(Field &field) override { + assert(false); // Not implemented + return std::vector(); + } Iterator* NewIterator(const ReadOptions& options) override { if (options.snapshot == nullptr) { KVMap* saved = new KVMap; diff --git a/include/leveldb/db.h b/include/leveldb/db.h index a13d147..cbe69a7 100644 --- a/include/leveldb/db.h +++ b/include/leveldb/db.h @@ -11,6 +11,7 @@ #include "leveldb/export.h" #include "leveldb/iterator.h" #include "leveldb/options.h" +#include "util/serialize_value.h" namespace leveldb { @@ -66,6 +67,9 @@ class LEVELDB_EXPORT DB { virtual Status Put(const WriteOptions& options, const Slice& key, const Slice& value) = 0; + virtual Status PutFields(const WriteOptions&, const Slice& key, + const FieldArray& fields) = 0; + // Remove the database entry (if any) for "key". Returns OK on // success, and a non-OK status on error. It is not an error if "key" // did not exist in the database. @@ -86,7 +90,11 @@ class LEVELDB_EXPORT DB { // May return some other Status on an error. virtual Status Get(const ReadOptions& options, const Slice& key, std::string* value) = 0; + + virtual Status GetFields(const ReadOptions& options, const Slice& key, + FieldArray* fields) = 0; + virtual std::vector FindKeysByField(Field &field) = 0; // Return a heap-allocated iterator over the contents of the database. // The result of NewIterator() is initially invalid (caller must // call one of the Seek methods on the iterator before using it). diff --git a/test/lab1_test.cc b/test/lab1_test.cc new file mode 100644 index 0000000..d12239b --- /dev/null +++ b/test/lab1_test.cc @@ -0,0 +1,46 @@ +#include "gtest/gtest.h" +#include "leveldb/env.h" +#include "leveldb/db.h" +using namespace leveldb; +using Field = std::pair; // field_name:field_value +using FieldArray = std::vector>; + +Status OpenDB(std::string dbName, DB **db) { + Options options; + options.create_if_missing = true; + return DB::Open(options, dbName, db); +} + +TEST(TestLab1, Basic) { + DestroyDB("testdb",Options()); + DB *db; + + if(OpenDB("testdb", &db).ok() == false) { + std::cerr << "open db failed" << std::endl; + abort(); + } + std::string key = "k_1"; + + FieldArray fields = { + {"name", "Customer#000000001"}, + {"address", "IVhzIApeRb"}, + {"phone", "25-989-741-2988"} + }; + + // 序列化并插入 + db->PutFields(WriteOptions(), key, fields); + + // 读取并反序列化 + FieldArray fields_ret; + db->GetFields(ReadOptions(), key, &fields_ret); + + Field field = {"name", "Customer#000000001"}; + std::vector resKeys = db->FindKeysByField(field); +} + + +int main(int argc, char** argv) { + // All tests currently run with the same read-only file limits. + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/util/serialize_value.cc b/util/serialize_value.cc new file mode 100644 index 0000000..6a30e27 --- /dev/null +++ b/util/serialize_value.cc @@ -0,0 +1,10 @@ +#include "util/serialize_value.h" + +namespace leveldb{ + std::string SerializeValue(const FieldArray& fields){ + return ""; + } + FieldArray *ParseValue(const std::string& value_str){ + return new FieldArray; + } +} \ No newline at end of file diff --git a/util/serialize_value.h b/util/serialize_value.h new file mode 100644 index 0000000..6f9fb2c --- /dev/null +++ b/util/serialize_value.h @@ -0,0 +1,13 @@ +#ifndef STORAGE_LEVELDB_UTIL_SERIALIZE_VALUE_H_ +#define STORAGE_LEVELDB_UTIL_SERIALIZE_VALUE_H_ + +#include +#include +namespace leveldb{ + using Field = std::pair; // field_name:field_value + using FieldArray = std::vector>; + + std::string SerializeValue(const FieldArray& fields); + FieldArray *ParseValue(const std::string& value_str); +} +#endif \ No newline at end of file