diff --git a/db/db_impl.cc b/db/db_impl.cc index a6b09a2..93cda85 100644 --- a/db/db_impl.cc +++ b/db/db_impl.cc @@ -11,6 +11,10 @@ #include #include #include +#include +#include +#include +#include #include "db/builder.h" #include "db/db_iter.h" @@ -1184,6 +1188,7 @@ Status DBImpl::Get(const ReadOptions& options, const Slice& key, slot_page_->get_slot(slot_num, &sc); vlog_set_->get_value(sc.vlog_num, sc.value_offset, &vlog_value); *value = vlog_value; + std::cout << "value from value_log: " << vlog_value << std::endl; // TODO(end) return s; } @@ -1218,30 +1223,36 @@ void DBImpl::ReleaseSnapshot(const Snapshot* snapshot) { } // Convenience methods -Status DBImpl::Put(const WriteOptions& o, const Slice& key, const Slice& val) { +Status DBImpl::Put_Fields(const WriteOptions& opt, const Slice& key, + const FieldArray& fields) { // TODO(begin): allocate slot_num in slotpage and put value in vlog - + // 将字段数组序列化 + std::string serialized_value = SerializeValue(fields); + std::cout << "Put_Fields: " << key.ToString() << " " << serialized_value << std::endl; size_t slot_num = slot_page_->alloc_slot(); struct slot_content sc; - vlog_set_->put_value(&sc.vlog_num, &sc.value_offset, val); + vlog_set_->put_value(&sc.vlog_num, &sc.value_offset, serialized_value); slot_page_->set_slot(slot_num, &sc); char data[sizeof(size_t)]; memcpy(data, &slot_num, sizeof(size_t)); Slice slot_val(data, sizeof(data)); - return DB::Put(o, key, slot_val); + return DB::Put(opt, key, slot_val); // TODO(end) } +Status DBImpl::Put(const WriteOptions& o, const Slice& key, const Slice& val) { + return DB::Put(o, key, val); +} Status DBImpl::Delete(const WriteOptions& options, const Slice& key) { - // TODO(begin) // size_t slot_num = *(size_t *)value->c_str(); // struct slot_content sc; // std::string vlog_value; // slot_page_->get_slot(slot_num, &sc); // vlog_set_->get_value(sc.vlog_num, sc.value_offset, &vlog_value); // *value = vlog_value; + // TODO(begin) ReadOptions ro; ro.verify_checksums = true; ro.fill_cache = false; @@ -1537,7 +1548,32 @@ void DBImpl::GetApproximateSizes(const Range* range, int n, uint64_t* sizes) { v->Unref(); } - +std::string DBImpl::SerializeValue(const FieldArray& fields) { + // 创建并初始化一个字符串流 oss,用于逐步构建最终的序列化字符串 + std::ostringstream oss_temp; + std::string slot_num = "slot_num"; + oss_temp << std::setw(sizeof(size_t)) << std::setfill('0') << slot_num; + // 写入属性个数(定长,16比特),使用std::setw(16)设置宽度,使用std::setfull(0)设置填充字符,将字段数组的大小写入oss中 + oss_temp << std::setw(16) << std::setfill('0') << fields.size(); + for (const auto& field : fields) { + // 写入属性名长度(定长,16比特) + oss_temp << std::setw(16) << std::setfill('0') << field.name.size(); + // 写入属性名(变长) + oss_temp << field.name; + // 写入属性值长度(定长,16比特) + oss_temp << std::setw(16) << std::setfill('0') << field.value.size(); + // 写入属性值(变长) + oss_temp << field.value; + } + std::string temp_str = oss_temp.str(); + size_t value_length = temp_str.size(); + + std::ostringstream oss; + oss << std::setw(16) << std::setfill('0') << value_length; + oss << temp_str; + + return oss.str(); +} // Default implementations of convenience methods that subclasses of DB // can call if they wish Status DB::Put(const WriteOptions& opt, const Slice& key, const Slice& value) { diff --git a/db/db_impl.h b/db/db_impl.h index f6917e6..8eff8b9 100644 --- a/db/db_impl.h +++ b/db/db_impl.h @@ -37,10 +37,16 @@ class DBImpl : public DB { DBImpl& operator=(const DBImpl&) = delete; ~DBImpl() override; - + // Todo(begin) + using FieldArray = std::vector; + // Todo(end) // Implementations of the DB interface Status Put(const WriteOptions&, const Slice& key, const Slice& value) override; + // Todo(begin) + Status Put_Fields(const WriteOptions& opt, const Slice& key, + const FieldArray& fields) override; + // Todo(end) Status Delete(const WriteOptions&, const Slice& key) override; Status Write(const WriteOptions& options, WriteBatch* updates) override; Status Get(const ReadOptions& options, const Slice& key, @@ -81,6 +87,7 @@ class DBImpl : public DB { // TODO(begin) SlotPage *slot_page_; VlogSet *vlog_set_; + static std::string SerializeValue(const FieldArray& fields); // TODO(end) // Information for a manual compaction struct ManualCompaction { diff --git a/include/leveldb/db.h b/include/leveldb/db.h index a13d147..79512d4 100644 --- a/include/leveldb/db.h +++ b/include/leveldb/db.h @@ -7,6 +7,7 @@ #include #include +#include #include "leveldb/export.h" #include "leveldb/iterator.h" @@ -21,6 +22,13 @@ static const int kMinorVersion = 23; struct Options; struct ReadOptions; struct WriteOptions; +// Todo(begin) +struct Field { + std::string name; + std::string value; +}; +using FieldArray = std::vector; +// Todo(end) class WriteBatch; // Abstract handle to particular state of a DB. @@ -145,6 +153,10 @@ 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; + // 字段信息结构体 + // Todo(begin) + virtual Status Put_Fields(const leveldb::WriteOptions& opt, const leveldb::Slice& key, const FieldArray& fields) = 0; + // // Todo(end) }; // Destroy the contents of the specified database. diff --git a/test/db_test3.cc b/test/db_test3.cc index 9e584fa..8286c28 100644 --- a/test/db_test3.cc +++ b/test/db_test3.cc @@ -13,14 +13,6 @@ #include "gtest/gtest.h" using namespace leveldb; - -// 字段信息结构体 -struct Field { - std::string name; - std::string value; -}; -using FieldArray = std::vector; - // 序列化函数,将字段数组编码为字符串 std::string SerializeValue(const FieldArray& fields) { // 创建并初始化一个字符串流 oss,用于逐步构建最终的序列化字符串 @@ -206,13 +198,9 @@ TEST(TestSchema, Basic) { {"address", "ecnu"}, {"phone", "11111"} }; - // 序列化并插入 - std::string value1 = SerializeValue(fields1); - std::string value2 = SerializeValue(fields2); - std::string value3 = SerializeValue(fields3); - db->Put(leveldb::WriteOptions(), key1, value1); - db->Put(leveldb::WriteOptions(), key2, value2); - db->Put(leveldb::WriteOptions(), key3, value3); + db->Put_Fields(leveldb::WriteOptions(), key1, fields1); + db->Put_Fields(leveldb::WriteOptions(), key2, fields2); + db->Put_Fields(leveldb::WriteOptions(), key3, fields3); // 读取并反序列化 std::string value_ret;