// // Created by 马也驰 on 2024/12/29. // #include "vlog_gc.h" #include "../db/vlog_set.h" void VlogGC::do_gc(size_t old_vlog_num, size_t new_vlog_num) { thread_pool_->enqueue([this, old_vlog_num, new_vlog_num]() { this->exec_gc(old_vlog_num, new_vlog_num); }); } void VlogGC::exec_gc(size_t old_vlog_num, size_t new_vlog_num) { auto old_vlog_name = vlog_set->get_vlog_name(old_vlog_num); auto new_vlog_name = vlog_set->get_vlog_name(new_vlog_num); auto old_vlog_info = vlog_set->get_vlog_info(old_vlog_num); auto new_vlog_info = vlog_set->get_vlog_info(new_vlog_num); auto old_vlog_handler = vlog_set->get_vlog_handler(old_vlog_num); auto new_vlog_handler = vlog_set->get_vlog_handler(new_vlog_num); old_vlog_handler->vlog_latch_.soft_lock(); new_vlog_info->vlog_info_latch_.lock(); new_vlog_handler->vlog_latch_.hard_lock(); auto old_vlog = std::fstream(old_vlog_name, std::ios::in | std::ios::out); auto new_vlog = std::fstream(new_vlog_name, std::ios::in | std::ios::out); char old_vlog_buff[VLOG_SIZE]; char new_vlog_buff[VLOG_SIZE]; old_vlog.seekp(0); old_vlog.read(old_vlog_buff, VLOG_SIZE); // memcpy(new_vlog_buff, &value_nums, sizeof(size_t)); size_t value_nums = old_vlog_info->value_nums; size_t ovb_off = 2 * sizeof(size_t); size_t nvb_off = 2 * sizeof(size_t); size_t new_vlog_value_nums = 0; for (auto i = 0; i < value_nums; i++) { char *value = &old_vlog_buff[ovb_off]; uint16_t value_len = get_value_len(value); size_t slot_num = get_value_slotnum(value); if (!value_deleted(value_len)) { memcpy(&new_vlog_buff[nvb_off], &old_vlog_buff[ovb_off], value_len); struct slot_content scn(new_vlog_info->vlog_num, nvb_off); slot_page_->set_slot(slot_num, &scn); nvb_off += value_len; new_vlog_value_nums ++; } ovb_off += value_len; } new_vlog_info->value_nums = value_nums; new_vlog_info->curr_size = nvb_off; memcpy(new_vlog_buff, &nvb_off, sizeof(size_t)); memcpy(&new_vlog_buff[sizeof(size_t)], &new_vlog_value_nums, sizeof(size_t)); new_vlog.write(new_vlog_buff, VLOG_SIZE); new_vlog.flush(); old_vlog.close(); new_vlog.close(); old_vlog_handler->vlog_latch_.soft_unlock(); new_vlog_info->vlog_info_latch_.unlock(); new_vlog_handler->vlog_latch_.hard_unlock(); vlog_set->remove_old_vlog(old_vlog_num); }