//
|
|
// Created by 马也驰 on 2024/12/29.
|
|
//
|
|
|
|
#ifndef LEVELDB_VLOG_GC_H
|
|
#define LEVELDB_VLOG_GC_H
|
|
|
|
|
|
#include <string>
|
|
#include <mutex>
|
|
#include <thread>
|
|
#include <chrono>
|
|
#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() {
|
|
while (true) {
|
|
curr_thread_nums_latch_.lock();
|
|
if (curr_thread_nums_) {
|
|
curr_thread_nums_latch_.unlock();
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
|
} else {
|
|
curr_thread_nums_latch_.unlock();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
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<size_t, bool> ovn_map_;
|
|
};
|
|
|
|
|
|
#endif // LEVELDB_VLOG_GC_H
|