// // Created by 马也驰 on 2024/12/29. // #ifndef LEVELDB_VLOG_GC_H #define LEVELDB_VLOG_GC_H #include #include #include "../db/slotpage.h" #include "../db/vlog.h" #include "../db/gc_executor.h" // 前向声明 VlogSet class VlogSet; class VlogGC { #define THREAD_NUM 8 friend class gc_executor; public: VlogGC(SlotPage *s, VlogSet *vs) : slot_page_(s), vlog_set(vs),max_thread_nums_(THREAD_NUM), curr_thread_nums_(0), gc_num(0) {} ~VlogGC() {} void do_gc(size_t old_vlog_num, size_t new_vlog_num); private: void exec_gc(size_t gc_num_); void gc_counter_increment(); void gc_counter_decrement(); inline bool value_deleted(uint16_t value_len) { return !(value_len >> 15); } inline uint16_t get_value_len(char *value) { uint16_t value_len; memcpy(&value_len, value, sizeof(uint16_t)); return value_len; } inline size_t get_value_slotnum(char *value) { size_t slot_num; memcpy(&slot_num, &value[sizeof(uint16_t)], sizeof(size_t)); return slot_num; } inline size_t get_gc_num() { gc_num_latch_.lock(); size_t _gc_num_ = gc_num ++; gc_num_latch_.unlock(); return _gc_num_; } inline bool vlog_in_gc(size_t vlog_num) { ovn_map_latch_.lock(); bool flag = false; if (ovn_map_.find(vlog_num) != ovn_map_.end()) { flag = true; } ovn_map_latch_.unlock(); return flag; } inline void add_vlog_in_gc(size_t vlog_num) { ovn_map_latch_.lock(); ovn_map_[vlog_num] = true; ovn_map_latch_.unlock(); } inline void del_vlog_in_gc(size_t vlog_num) { ovn_map_latch_.lock(); ovn_map_.erase(vlog_num); ovn_map_latch_.unlock(); } SlotPage *slot_page_; VlogSet *vlog_set; // 仅声明为指针,具体定义放在 vlog_gc.cpp // NOTE: threadpool std::mutex full_latch_; // indicate thread pool is full when set as locked size_t max_thread_nums_; std::mutex curr_thread_nums_latch_; size_t curr_thread_nums_; std::mutex gc_num_latch_; size_t gc_num; std::mutex ovn_map_latch_; std::unordered_map ovn_map_; }; #endif // LEVELDB_VLOG_GC_H