diff --git a/report.md b/report.md index 5f18354..2a69641 100644 --- a/report.md +++ b/report.md @@ -201,7 +201,7 @@ std::vector FindKeysByField(leveldb::DB* db, const Field& field) { ##### 相关代码文件 - [`/db/db_impl.cc`](./db/db_impl.cc): 修改函数 DBImpl::Get, DBImpl::Put 和 DBImpl::Delete,添加函数 Put_fields, Get_fields, get_slot_num,SerializeValue, DeserializeValue -- [`/db/db_impl.h`](./db/db_impl.h): 添加两个结构体 SlotPage *slot_page_; VlogSet *vlog_set_ ,添加增加的相关函数的声明 +- [`/db/db_impl.h`](./db/db_impl.h): 添加相关结构体和函数声明 - [`/db/shared_lock.h`](./db/shared_lock.h): 定义了一个 SharedLock 类,用于实现读写锁机制。该类支持两种锁模式:软锁(soft_lock/soft_unlock)和硬锁(hard_lock/hard_unlock); - [`/db/slotpage.h`](./db/slotpage.h): 1. 定义了 slot_content 结构体: @@ -220,7 +220,7 @@ struct slot_content { 3. 定义了 BitMap 类,类中函数: dealloc_slot, alloc_slot, alloc_new_bitmap; 4. 定义了 Slot_page 类,类中函数: get_slot, set_slot, alloc_slot, dealloc_slot - [`/db/vlog.h`](./db/vlog.h) -1. 定义了 vlog_info 结构体: +1. 定义了 vlog_info 结构体(存放 value_log 的相关信息): ```` struct vlog_info { std::mutex vlog_info_latch_; // 保护对vlog_info本身的并发修改 @@ -269,7 +269,7 @@ struct vlog_handler { ```` - [`/db/vlog_gc.h`](./db/vlog_gc.h): -定义 VlogGC 类,声明类中函数:do_gc, exec_gc, gc_counter_increment, gc_counter_decrement, get_gc_num, vlog_in_gc, add_vlog_in_gc, del_vlog_in_gc +定义 VlogGC 类,声明类中函数 - [`/db/vlog_gc.cpp`](./db/vlog_gc.cpp): 1. 定义了 executor_param 结构体: ```` @@ -279,15 +279,15 @@ struct executor_param { size_t new_vlog_num; }; ```` -2. 定义函数:add_executor_params, get_executor_params, del_executor_params, add_vlog_gc, get_vlog_gc, del_vlog_gc, gc_counter_increment, gc_counter_decrement, do_gc, exec_gc -- [`/db/vlog_set.h`](./db/vlog_set.h): +2. 实现 vlog_gc 中声明的函数 +- [`/db/vlog_set.h`](./db/vlog_set.h)(用于管理 vlog): 定义 VlogSet 结构体 +- [`/db/vlog_set.cpp`](./db/vlog_set.cpp): + 实现 vlog_set 中的函数 - [`/db/vlog_cache.h`](./db/vlog_cache.h): 1. 定义结构体:frame_info, block_frame 2. 定义类 VlogCache -- [`/db/vlog_cache.cpp`](./db/vlog_cache.cpp):实现 VlogCache 类中的函数 -- [`/db/vlog_set.cpp`](./db/vlog_set.cpp): - 定义函数: get_value, get_writable_vlog_info, put_value, del_value, register_new_vlog, remove_old_vlog, vlog_need_gc, register_inconfig_file, remove_from_config_file, create_vlog, restore_vlog_inmaps, register_vlog_inmaps, remove_vlog_from_maps, read_vlog_value, write_vlog_value, mark_del_value +- [`/db/vlog_cache.cpp`](./db/vlog_cache.cpp):实现 vlog_cache 中的函数 - [`CMakeLists.txt`](CMakeLists.txt):添加可执行文件 **数据结构设计:** @@ -308,12 +308,11 @@ struct executor_param { 将传入的字段数组插入数据库中 **步骤:** -1. 为当前 KV 对分配一个 size_t 类型的 slot_num; -3. 调用 SerializeValue 函数将字段数组和 slot_num_str 序列化为字符串 serialized_value; -4. 实例化 slot_content 结构体 sc; -5. 调用 put_value 函数,以 sc 中的 vlog_num(vlog编号) 和 value_offset(在vlog中的偏移量) 为参数,将字符串 serialized_value 写入 vlog 中; -6. 调用 set_slot 函数,将 slot_content 中的内容赋值给 slot_num; -7. 将 slot_num 作为 value 写入数据库中。 +1. 在 bit_map 中分配一个空闲位置; +2. 调用 SerializeValue 函数将字段数组序列化为字符串 serialized_value; +3. 调用 put_value 函数,将字符串 serialized_value 写入 vlog 中; +4. 调用 set_slot 函数,将 sc 写入缓存中; +5. 将 slot_num 作为 value 写入数据库中。 **代码实现:** ```` @@ -322,15 +321,15 @@ const FieldArray& fields) { std::string serialized_value; // alloc_slot 函数作用:分配一个 slot_num size_t slot_num = slot_page_->alloc_slot(); -// SerializeValue 函数作用:将字段数组和 slot_num_str 序列化为字符串 serialized_value +// SerializeValue 函数作用:将字段数组序列化为字符串 serialized_value SerializeValue(fields, serialized_value, slot_num); // 实例化 slot_content 结构体 sc struct slot_content sc; // put_value函数作用:将序列化后的字符串 serialized_value 插入 value_log 中 vlog_set_->put_value(sc, slot_num, serialized_value); -// set_slot函数作用: 将 slot_num 写入到 缓冲块中 +// set_slot函数作用: 将 sc 写入内存中 slot_page_->set_slot(slot_num, &sc); -// 将 slot_num 作为 value 插入 memtable 中 +// 将 slot_num 作为 value 插入 sstable 中 char data[sizeof(size_t)]; memcpy(data, &slot_num, sizeof(size_t)); Slice slot_val(data, sizeof(data)); @@ -339,7 +338,7 @@ return DB::Put(opt, key, slot_val); ```` `size_t alloc_slot()` -**功能:** 分配一个 slot_num +**功能:** 在 bitmap 中分配一个空闲的槽位 **实现步骤:** 1. 获取互斥锁; @@ -386,7 +385,7 @@ size_t alloc_slot() { ```` `void set_slot(size_t slot_num, struct slot_content *sc)` -**功能:** 将一个槽位的内容设置到缓存块中 +**功能:** 将 sc 写入缓存块中,缓存块与 bitmap 有对应关系 **实现步骤:** 1. 计算块编号:通过 slotnum_hash2_blocknum 函数将槽位编号转换为块编号 @@ -420,9 +419,7 @@ void set_slot(size_t slot_num, struct slot_content *sc) { `void VlogSet::put_value(struct slot_content &sc, size_t slot_num, const leveldb::Slice &value)` -**功能:** 将序列化后的字符串 serialized_value 插入 value_log 中,位置由 slot_content 确定 - -**输入:** 待插入的字符串 value,slot_num,slot_content +**功能:** 做前期准备,并调用 write_vlog_value 将序列化后的字符串 serialized_value 插入 value_log 中 **实现步骤:** 1. 获取互斥锁; @@ -476,8 +473,6 @@ void VlogSet::put_value(struct slot_content &sc, size_t slot_num, const leveldb: **功能:** 将字符串 value 写入 vlog 中 -**输入:** slot_content,slot_num,字符串 value - **实现步骤:** 1. 获取 vlog 名称; 2. 打开 vlog 文件; @@ -519,7 +514,7 @@ void VlogSet::write_vlog_value(const struct slot_content &sc, size_t slot_num, c **实现步骤:** 1. 读取 key 对应的 slot_num 2. 调用 get_slot 函数,根据 slot_num 从 slot_page 中获取 slot_content -4. 调用 get_value 函数,根据 slot_content 中的 vlog_num(vlog编号) 和 value_offset(在vlog中的偏移量) 从 vlog 中读取字符串 +4. 调用 get_value 函数,从 vlog 中读取字符串 5. 将字符串解码得到 value **代码实现:** @@ -582,7 +577,7 @@ void get_slot(size_t slot_num, struct slot_content *sc) { `void VlogSet::get_value(const struct slot_content &sc, std::string *value)` -**功能:** 根据 slot_content 从 vlog 中读取字符串并存放到 value 中 +**功能:** 做准备工作,并调用 read_vlog_value 函数从 vlog 中读取字符串 **实现步骤:** 1. 根据 sc.vlog_num 获取 vinfo 和 vlog_handler; @@ -662,16 +657,17 @@ void VlogSet::read_vlog_value(const struct slot_content &sc, std::string *value) handler.close(); } ```` + `Status DBImpl::Delete(const WriteOptions& options, const Slice& key)` **功能:** 删除 key 对应的条目 **步骤:** -1. 从 sstable 中获取 key 对应的 slot_num; +1. 获取 key 对应的 slot_num; 2. 获取 slot_num 对应的 slot_content; 3. 删除 vlog 中 slot_content 对应的条目; -4. 释放 slot_num 中对应的 slot_content;? -5. 删除 sstable 中 key 对应的条目。 +4. 释放 slot_num 中对应的 slot_content; +5. 删除 k-v对。 **代码实现:** ```` @@ -686,9 +682,9 @@ return s; struct slot_content sc; // get_slot 函数作用: 获取 slot_num 对应的 slot_content slot_page_->get_slot(slot_num, &sc); -// del_value 函数作用:删除 vlog 中 slot_content 对应的条目 +// del_value 函数作用:删除 vlog 中 slot_content 对应的 value vlog_set_->del_value(sc); -// dealloc_slot 函数作用: 释放 slot_num 对应的 slot +// dealloc_slot 函数作用: 释放 slot_num slot_page_->dealloc_slot(slot_num); return DB::Delete(options, key); @@ -696,7 +692,7 @@ return DB::Delete(options, key); ```` `void VlogSet::del_value(const struct slot_content &sc)` -**功能:** 删除 vlog 中 slot_content 对应的条目 +**功能:** 做准备工作,调用 mark_del_value 删除 vlog 中的条目 **实现步骤:** 1. 加锁:使用互斥锁 mtx 确保线程安全。 @@ -704,7 +700,7 @@ return DB::Delete(options, key); 3. 检查状态:如果 vlog 无效或正在处理垃圾回收,则更新处理器为垃圾回收的 vlog。 4. 加锁并增加访问计数:对 vlog 处理器加锁,并增加访问线程数。 5. 解锁:释放互斥锁和 vlog 信息锁。 -6. 标记删除:调用 mark_del_value 标记删除操作。 +6. 标记删除:调用 mark_del_value 标记并进行删除操作。 7. 减少访问计数并解锁:减少访问线程数并解锁 vlog **具体实现如下:** @@ -730,7 +726,7 @@ void VlogSet::del_value(const struct slot_content &sc) { ```` `void VlogSet::mark_del_value(const struct slot_content &sc)` -**功能:** 标记 slot_content 对应的条目为删除并判断是否需要调用 GC +**功能:** 标记 slot_content 对应的条目为删除并判断是否需要调用 GC,如果需要,调用do_gc **实现步骤:** 1. 根据 sc.vlog_num 获取 vlog 文件信息; @@ -755,6 +751,7 @@ void VlogSet::mark_del_value(const struct slot_content &sc) { if (vlog_need_gc(sc.vlog_num) && !vinfo->processing_gc) { // create new vlog vinfo->processing_gc = true; + // 分配一个新的 vlog vinfo->vlog_num_for_gc = register_new_vlog(); // 启动垃圾回收过程 vlog_gc->do_gc(sc.vlog_num, vinfo->vlog_num_for_gc); @@ -764,7 +761,7 @@ void VlogSet::mark_del_value(const struct slot_content &sc) { `void VlogGC::do_gc(size_t old_vlog_num, size_t new_vlog_num)` -**功能:** 启动垃圾回收过程 +**功能:** 做 GC 的前期准备,并启动垃圾回收过程 **实现步骤:** @@ -778,7 +775,7 @@ void VlogSet::mark_del_value(const struct slot_content &sc) { **具体实现如下:** ```` void VlogGC::do_gc(size_t old_vlog_num, size_t new_vlog_num) { - // 判断old_vlog_num是否正在进行gc,如果是,直接返回 + // 判断旧的 vlog 是否正在进行gc,如果是,直接返回 if (vlog_in_gc(old_vlog_num)) { return ; } @@ -807,7 +804,7 @@ void VlogGC::do_gc(size_t old_vlog_num, size_t new_vlog_num) { `void VlogGC::exec_gc(size_t gc_num_)` -**功能:** 执行GC任务 +**功能:** GC 相关线程调度,并执行GC任务 **实现步骤:**