|
|
@ -1,5 +1,6 @@ |
|
|
|
#include "table/vtable_manager.h"
|
|
|
|
|
|
|
|
#include "db/dbformat.h"
|
|
|
|
#include "db/filename.h"
|
|
|
|
#include <iostream>
|
|
|
|
#include <ostream>
|
|
|
@ -13,8 +14,9 @@ namespace leveldb { |
|
|
|
|
|
|
|
struct GCInfo { |
|
|
|
std::string dbname; |
|
|
|
std::vector<uint64_t> file_list; |
|
|
|
std::set<uint64_t>* file_list; |
|
|
|
Env* env = nullptr; |
|
|
|
VTableManager* vtable_manager = nullptr; |
|
|
|
}; |
|
|
|
|
|
|
|
void VTableMeta::Encode(std::string* target) const { |
|
|
@ -50,7 +52,7 @@ Status VTableManager::AddInvalid(uint64_t file_num) { |
|
|
|
|
|
|
|
vtables_[file_num].invalid_num += 1; |
|
|
|
if (vtables_[file_num].invalid_num >= vtables_[file_num].records_num) { |
|
|
|
invalid_.emplace_back(file_num); |
|
|
|
invalid_.insert(file_num); |
|
|
|
} |
|
|
|
|
|
|
|
MaybeScheduleGarbageCollect(); |
|
|
@ -127,7 +129,7 @@ Status VTableManager::LoadVTableMeta() { |
|
|
|
} |
|
|
|
AddVTable(vtable_meta); |
|
|
|
if (vtable_meta.invalid_num >= vtable_meta.records_num) { |
|
|
|
invalid_.emplace_back(vtable_meta.number); |
|
|
|
invalid_.insert(vtable_meta.number); |
|
|
|
} |
|
|
|
} else { |
|
|
|
return s; |
|
|
@ -139,31 +141,43 @@ Status VTableManager::LoadVTableMeta() { |
|
|
|
|
|
|
|
void VTableManager::MaybeScheduleGarbageCollect() { |
|
|
|
size_t size = 0; |
|
|
|
auto* delete_list = new std::set<uint64_t>(); |
|
|
|
for (auto & file_num : invalid_) { |
|
|
|
size += vtables_[file_num].table_size; |
|
|
|
} |
|
|
|
if (size >= gc_threshold_) { |
|
|
|
auto* gc_info = new GCInfo; |
|
|
|
gc_info->dbname = dbname_; |
|
|
|
gc_info->file_list = invalid_; |
|
|
|
gc_info->file_list = delete_list; |
|
|
|
gc_info->env = env_; |
|
|
|
gc_info->vtable_manager = this; |
|
|
|
env_->StartThread(&VTableManager::BackgroudGC, gc_info); |
|
|
|
for (auto & file_num : gc_info->file_list) { |
|
|
|
RemoveVTable(file_num); |
|
|
|
auto it = std::remove(invalid_.begin(), invalid_.end(), file_num); |
|
|
|
} |
|
|
|
// for (auto & file_num : gc_info->file_list) {
|
|
|
|
// RemoveVTable(file_num);
|
|
|
|
// auto it = std::remove(invalid_.begin(), invalid_.end(), file_num);
|
|
|
|
// }
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void VTableManager::BackgroudGC(void* gc_info) { |
|
|
|
auto info = reinterpret_cast<GCInfo*>(gc_info); |
|
|
|
for (auto & file_num : info->file_list) { |
|
|
|
for (auto & file_num : *info->file_list) { |
|
|
|
// if (file_num <= 0) {continue;}
|
|
|
|
auto fname = VTableFileName(info->dbname, file_num); |
|
|
|
info->env->RemoveFile(fname); |
|
|
|
|
|
|
|
if (info->vtable_manager->vtables_[file_num].ref <= 0) { |
|
|
|
info->env->RemoveFile(fname); |
|
|
|
info->vtable_manager->invalid_.erase(file_num); |
|
|
|
} |
|
|
|
} |
|
|
|
delete info; |
|
|
|
} |
|
|
|
|
|
|
|
void VTableManager::RefVTable(uint64_t file_num) { |
|
|
|
vtables_[file_num].ref += 1; |
|
|
|
} |
|
|
|
|
|
|
|
void VTableManager::UnrefVTable(uint64_t file_num) { |
|
|
|
vtables_[file_num].ref -= 1; |
|
|
|
} |
|
|
|
|
|
|
|
} // namespace leveldb
|