#ifndef LEVELDB_KV_SEPARATE_MANAGEMENT_H #define LEVELDB_KV_SEPARATE_MANAGEMENT_H #include #include #include #include "leveldb/slice.h" #include namespace leveldb { typedef struct ValueLogInfo { uint64_t last_sequence_; // VLog 中最后一个有效 kv 的序列号 size_t file_size_; // VLog 文件大小 uint64_t logfile_number_; // VLog 文件编号 int left_kv_numbers_; // VLog 中剩下的 kv 数量 uint64_t invalid_memory_; // VLog 中无效空间的大小 }ValueLogInfo; struct MapCmp{ bool operator ()(const ValueLogInfo* a, const ValueLogInfo* b) { return a->invalid_memory_ < b->invalid_memory_; } }; class SeparateManagement { public: SeparateManagement(uint64_t garbage_collection_threshold) : garbage_collection_threshold_(garbage_collection_threshold) {} ~SeparateManagement() {} /* 更新数据库的最后一个序列号,为需要 GC 的 VLog 分配新的序列号,返回是否触发 GC */ bool ConvertQueue(uint64_t& db_sequence); /* 更新指定 VLogInfo 的无效空间和剩余键值对数量 */ void UpdateMap(uint64_t fid, uint64_t abandon_memory); /* 选择无效空间最大的 VLog 加入到 need_updates_ 队列 */ void UpdateQueue(uint64_t fid); /* 从 garbage_collection_ 队列中取出一个需要 GC 的 VLog,返回最后(最新)序列号 */ bool GetGarbageCollectionQueue(uint64_t& fid, uint64_t& last_sequence); /* 在 map_file_info_ 中添加新创建的 VLog 的 ValueLogInfo */ void WriteFileMap(uint64_t fid, int kv_numbers, size_t log_memory); /* 检查是否有任何 VLog 需要 GC */ bool MayNeedGarbageCollection() { return !garbage_collection_.empty(); } /* 从 map_file_info_ 中移除指定编号的 VLog */ void RemoveFileFromMap(uint64_t fid) { map_file_info_.erase(fid); } /* 检查 map_file_info_ 是否为空 */ bool EmptyMap() { return map_file_info_.empty(); } /* 遍历 map_file_info_ 中的所有 VLog,更新 need_updates_ 以便后续 GC */ void CollectionMap(); private: // VLog 触发 GC 的阈值 uint64_t garbage_collection_threshold_; // 当前 version 的所有 VLog 索引 std::unordered_map map_file_info_; // 即将 GC 的 VLog std::deque garbage_collection_; // 需要 GC 但尚未更新 Sequence 的 VLog std::deque need_updates_; // 正在删除的 VLog 文件编号 std::unordered_set delete_files_; }; } // namespace leveldb #endif //LEVELDB_KV_SEPARATE_MANAGEMENT_H