未验证 提交 10c78caf 编写于 作者: 羽飞's avatar 羽飞 提交者: GitHub

重构buffer pool (#33)

重构disk buffer pool:
新增BufferPoolManager,管理所有的DiskBufferPool;
原有DiskBufferPool只处理一个文件,取消其中file_id的概念;
删除BPPageHandle,直接使用Frame;
BPManager更名BPFrameManager;
BPFileSubHeader改为BPFileHeader并直接放在DiskBufferPool中
上级 7ad72565
...@@ -36,6 +36,8 @@ See the Mulan PSL v2 for more details. */ ...@@ -36,6 +36,8 @@ See the Mulan PSL v2 for more details. */
#include "sql/query_cache/query_cache_stage.h" #include "sql/query_cache/query_cache_stage.h"
#include "storage/default/default_storage_stage.h" #include "storage/default/default_storage_stage.h"
#include "storage/mem/mem_storage_stage.h" #include "storage/mem/mem_storage_stage.h"
#include "storage/default/disk_buffer_pool.h"
#include "storage/default/default_handler.h"
using namespace common; using namespace common;
...@@ -156,6 +158,33 @@ int prepare_init_seda() ...@@ -156,6 +158,33 @@ int prepare_init_seda()
return 0; return 0;
} }
int init_global_objects()
{
BufferPoolManager *bpm = new BufferPoolManager();
BufferPoolManager::set_instance(bpm);
DefaultHandler *handler = new DefaultHandler();
DefaultHandler::set_default(handler);
return 0;
}
int uninit_global_objects()
{
DefaultHandler *default_handler = &DefaultHandler::get_default();
if (default_handler != nullptr) {
DefaultHandler::set_default(nullptr);
delete default_handler;
}
BufferPoolManager *bpm = &BufferPoolManager::instance();
if (bpm != nullptr) {
BufferPoolManager::set_instance(nullptr);
delete bpm;
}
return 0;
}
int init(ProcessParam *process_param) int init(ProcessParam *process_param)
{ {
...@@ -200,6 +229,12 @@ int init(ProcessParam *process_param) ...@@ -200,6 +229,12 @@ int init(ProcessParam *process_param)
get_properties()->to_string(conf_data); get_properties()->to_string(conf_data);
LOG_INFO("Output configuration \n%s", conf_data.c_str()); LOG_INFO("Output configuration \n%s", conf_data.c_str());
rc = init_global_objects();
if (rc != 0) {
LOG_ERROR("failed to init global objects");
return rc;
}
// seda is used for backend async event handler // seda is used for backend async event handler
// the latency of seda is slow, it isn't used for critical latency // the latency of seda is slow, it isn't used for critical latency
// environment. // environment.
...@@ -229,7 +264,8 @@ int init(ProcessParam *process_param) ...@@ -229,7 +264,8 @@ int init(ProcessParam *process_param)
void cleanup_util() void cleanup_util()
{ {
uninit_global_objects();
if (nullptr != get_properties()) { if (nullptr != get_properties()) {
delete get_properties(); delete get_properties();
get_properties() = nullptr; get_properties() = nullptr;
...@@ -245,4 +281,6 @@ void cleanup_util() ...@@ -245,4 +281,6 @@ void cleanup_util()
} }
void cleanup() void cleanup()
{} {
cleanup_util();
}
...@@ -16,10 +16,10 @@ See the Mulan PSL v2 for more details. */ ...@@ -16,10 +16,10 @@ See the Mulan PSL v2 for more details. */
#include <string> #include <string>
static const char *TABLE_META_SUFFIX = ".table"; static constexpr const char *TABLE_META_SUFFIX = ".table";
static const char *TABLE_META_FILE_PATTERN = ".*\\.table$"; static constexpr const char *TABLE_META_FILE_PATTERN = ".*\\.table$";
static const char *TABLE_DATA_SUFFIX = ".data"; static constexpr const char *TABLE_DATA_SUFFIX = ".data";
static const char *TABLE_INDEX_SUFFIX = ".index"; static constexpr const char *TABLE_INDEX_SUFFIX = ".index";
std::string table_meta_file(const char *base_dir, const char *table_name); std::string table_meta_file(const char *base_dir, const char *table_name);
std::string table_data_file(const char *base_dir, const char *table_name); std::string table_data_file(const char *base_dir, const char *table_name);
......
...@@ -47,66 +47,54 @@ int page_header_size(int record_capacity) ...@@ -47,66 +47,54 @@ int page_header_size(int record_capacity)
return align8(page_fix_size() + bitmap_size); return align8(page_fix_size() + bitmap_size);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
RecordPageHandler::RecordPageHandler()
: disk_buffer_pool_(nullptr), file_id_(-1), page_header_(nullptr), bitmap_(nullptr)
{
page_handle_.open = false;
page_handle_.frame = nullptr;
}
RecordPageHandler::~RecordPageHandler() RecordPageHandler::~RecordPageHandler()
{ {
cleanup(); cleanup();
} }
RC RecordPageHandler::init(DiskBufferPool &buffer_pool, int file_id, PageNum page_num) RC RecordPageHandler::init(DiskBufferPool &buffer_pool, PageNum page_num)
{ {
if (disk_buffer_pool_ != nullptr) { if (disk_buffer_pool_ != nullptr) {
LOG_WARN("Disk buffer pool has been opened for file_id:page_num %d:%d.", file_id, page_num); LOG_WARN("Disk buffer pool has been opened for page_num %d.", page_num);
return RC::RECORD_OPENNED; return RC::RECORD_OPENNED;
} }
RC ret = RC::SUCCESS; RC ret = RC::SUCCESS;
if ((ret = buffer_pool.get_this_page(file_id, page_num, &page_handle_)) != RC::SUCCESS) { if ((ret = buffer_pool.get_this_page(page_num, &frame_)) != RC::SUCCESS) {
LOG_ERROR("Failed to get page handle from disk buffer pool. file_id:%d, ret=%d:%s", file_id, ret, strrc(ret)); LOG_ERROR("Failed to get page handle from disk buffer pool. ret=%d:%s", ret, strrc(ret));
return ret; return ret;
} }
char *data; char *data = frame_->data();
ret = buffer_pool.get_data(&page_handle_, &data);
if (ret != RC::SUCCESS) {
LOG_ERROR("Failed to get page data. ret=%d:%s", ret, strrc(ret));
return ret;
}
disk_buffer_pool_ = &buffer_pool; disk_buffer_pool_ = &buffer_pool;
file_id_ = file_id;
page_header_ = (PageHeader *)(data); page_header_ = (PageHeader *)(data);
bitmap_ = data + page_fix_size(); bitmap_ = data + page_fix_size();
LOG_TRACE("Successfully init file_id:page_num %d:%d.", file_id, page_num); LOG_TRACE("Successfully init page_num %d.", page_num);
return ret; return ret;
} }
RC RecordPageHandler::init_empty_page(DiskBufferPool &buffer_pool, int file_id, PageNum page_num, int record_size) RC RecordPageHandler::init_empty_page(DiskBufferPool &buffer_pool, PageNum page_num, int record_size)
{ {
RC ret = init(buffer_pool, file_id, page_num); RC ret = init(buffer_pool, page_num);
if (ret != RC::SUCCESS) { if (ret != RC::SUCCESS) {
LOG_ERROR("Failed to init empty page file_id:page_num:record_size %d:%d:%d.", file_id, page_num, record_size); LOG_ERROR("Failed to init empty page page_num:record_size %d:%d.", page_num, record_size);
return ret; return ret;
} }
int page_size = sizeof(page_handle_.frame->page.data); int page_size = BP_PAGE_DATA_SIZE;
int record_phy_size = align8(record_size); int record_phy_size = align8(record_size);
page_header_->record_num = 0; page_header_->record_num = 0;
page_header_->record_capacity = page_record_capacity(page_size, record_phy_size); page_header_->record_capacity = page_record_capacity(page_size, record_phy_size);
page_header_->record_real_size = record_size; page_header_->record_real_size = record_size;
page_header_->record_size = record_phy_size; page_header_->record_size = record_phy_size;
page_header_->first_record_offset = page_header_size(page_header_->record_capacity); page_header_->first_record_offset = page_header_size(page_header_->record_capacity);
bitmap_ = page_handle_.frame->page.data + page_fix_size(); bitmap_ = frame_->data() + page_fix_size();
memset(bitmap_, 0, page_bitmap_size(page_header_->record_capacity)); memset(bitmap_, 0, page_bitmap_size(page_header_->record_capacity));
disk_buffer_pool_->mark_dirty(&page_handle_); frame_->mark_dirty();
return RC::SUCCESS; return RC::SUCCESS;
} }
...@@ -114,10 +102,8 @@ RC RecordPageHandler::init_empty_page(DiskBufferPool &buffer_pool, int file_id, ...@@ -114,10 +102,8 @@ RC RecordPageHandler::init_empty_page(DiskBufferPool &buffer_pool, int file_id,
RC RecordPageHandler::cleanup() RC RecordPageHandler::cleanup()
{ {
if (disk_buffer_pool_ != nullptr) { if (disk_buffer_pool_ != nullptr) {
disk_buffer_pool_->unpin_page(&page_handle_); disk_buffer_pool_->unpin_page(frame_);
disk_buffer_pool_ = nullptr; disk_buffer_pool_ = nullptr;
// skip purge page,
// skip reset page_header & bitmap
} }
return RC::SUCCESS; return RC::SUCCESS;
...@@ -125,9 +111,8 @@ RC RecordPageHandler::cleanup() ...@@ -125,9 +111,8 @@ RC RecordPageHandler::cleanup()
RC RecordPageHandler::insert_record(const char *data, RID *rid) RC RecordPageHandler::insert_record(const char *data, RID *rid)
{ {
if (page_header_->record_num == page_header_->record_capacity) { if (page_header_->record_num == page_header_->record_capacity) {
LOG_WARN("Page is full, file_id:page_num %d:%d.", file_id_, page_handle_.frame->page.page_num); LOG_WARN("Page is full, page_num %d:%d.", frame_->page_num());
return RC::RECORD_NOMEM; return RC::RECORD_NOMEM;
} }
...@@ -141,7 +126,7 @@ RC RecordPageHandler::insert_record(const char *data, RID *rid) ...@@ -141,7 +126,7 @@ RC RecordPageHandler::insert_record(const char *data, RID *rid)
char *record_data = get_record_data(index); char *record_data = get_record_data(index);
memcpy(record_data, data, page_header_->record_real_size); memcpy(record_data, data, page_header_->record_real_size);
disk_buffer_pool_->mark_dirty(&page_handle_); frame_->mark_dirty();
if (rid) { if (rid) {
rid->page_num = get_page_num(); rid->page_num = get_page_num();
...@@ -155,25 +140,21 @@ RC RecordPageHandler::insert_record(const char *data, RID *rid) ...@@ -155,25 +140,21 @@ RC RecordPageHandler::insert_record(const char *data, RID *rid)
RC RecordPageHandler::update_record(const Record *rec) RC RecordPageHandler::update_record(const Record *rec)
{ {
if (rec->rid.slot_num >= page_header_->record_capacity) { if (rec->rid.slot_num >= page_header_->record_capacity) {
LOG_ERROR("Invalid slot_num %d, exceed page's record capacity, file_id:page_num %d:%d.", LOG_ERROR("Invalid slot_num %d, exceed page's record capacity, page_num %d.",
rec->rid.slot_num, rec->rid.slot_num, frame_->page_num());
file_id_,
page_handle_.frame->page.page_num);
return RC::INVALID_ARGUMENT; return RC::INVALID_ARGUMENT;
} }
Bitmap bitmap(bitmap_, page_header_->record_capacity); Bitmap bitmap(bitmap_, page_header_->record_capacity);
if (!bitmap.get_bit(rec->rid.slot_num)) { if (!bitmap.get_bit(rec->rid.slot_num)) {
LOG_ERROR("Invalid slot_num %d, slot is empty, file_id:page_num %d:%d.", LOG_ERROR("Invalid slot_num %d, slot is empty, page_num %d.",
rec->rid.slot_num, rec->rid.slot_num, frame_->page_num());
file_id_,
page_handle_.frame->page.page_num);
return RC::RECORD_RECORD_NOT_EXIST; return RC::RECORD_RECORD_NOT_EXIST;
} else { } else {
char *record_data = get_record_data(rec->rid.slot_num); char *record_data = get_record_data(rec->rid.slot_num);
memcpy(record_data, rec->data, page_header_->record_real_size); memcpy(record_data, rec->data, page_header_->record_real_size);
bitmap.set_bit(rec->rid.slot_num); bitmap.set_bit(rec->rid.slot_num);
disk_buffer_pool_->mark_dirty(&page_handle_); frame_->mark_dirty();
// LOG_TRACE("Update record. file_id=%d, page num=%d,slot=%d", file_id_, rec->rid.page_num, rec->rid.slot_num); // LOG_TRACE("Update record. file_id=%d, page num=%d,slot=%d", file_id_, rec->rid.page_num, rec->rid.slot_num);
return RC::SUCCESS; return RC::SUCCESS;
} }
...@@ -182,10 +163,8 @@ RC RecordPageHandler::update_record(const Record *rec) ...@@ -182,10 +163,8 @@ RC RecordPageHandler::update_record(const Record *rec)
RC RecordPageHandler::delete_record(const RID *rid) RC RecordPageHandler::delete_record(const RID *rid)
{ {
if (rid->slot_num >= page_header_->record_capacity) { if (rid->slot_num >= page_header_->record_capacity) {
LOG_ERROR("Invalid slot_num %d, exceed page's record capacity, file_id:page_num %d:%d.", LOG_ERROR("Invalid slot_num %d, exceed page's record capacity, page_num %d.",
rid->slot_num, rid->slot_num, frame_->page_num());
file_id_,
page_handle_.frame->page.page_num);
return RC::INVALID_ARGUMENT; return RC::INVALID_ARGUMENT;
} }
...@@ -193,21 +172,18 @@ RC RecordPageHandler::delete_record(const RID *rid) ...@@ -193,21 +172,18 @@ RC RecordPageHandler::delete_record(const RID *rid)
if (bitmap.get_bit(rid->slot_num)) { if (bitmap.get_bit(rid->slot_num)) {
bitmap.clear_bit(rid->slot_num); bitmap.clear_bit(rid->slot_num);
page_header_->record_num--; page_header_->record_num--;
disk_buffer_pool_->mark_dirty(&page_handle_); frame_->mark_dirty();
if (page_header_->record_num == 0) { if (page_header_->record_num == 0) {
DiskBufferPool *disk_buffer_pool = disk_buffer_pool_; DiskBufferPool *disk_buffer_pool = disk_buffer_pool_;
int file_id = file_id_;
PageNum page_num = get_page_num(); PageNum page_num = get_page_num();
cleanup(); cleanup();
disk_buffer_pool->dispose_page(file_id, page_num); disk_buffer_pool->dispose_page(page_num);
} }
return RC::SUCCESS; return RC::SUCCESS;
} else { } else {
LOG_ERROR("Invalid slot_num %d, slot is empty, file_id:page_num %d:%d.", LOG_ERROR("Invalid slot_num %d, slot is empty, page_num %d.",
rid->slot_num, rid->slot_num, frame_->page_num());
file_id_,
page_handle_.frame->page.page_num);
return RC::RECORD_RECORD_NOT_EXIST; return RC::RECORD_RECORD_NOT_EXIST;
} }
} }
...@@ -215,19 +191,15 @@ RC RecordPageHandler::delete_record(const RID *rid) ...@@ -215,19 +191,15 @@ RC RecordPageHandler::delete_record(const RID *rid)
RC RecordPageHandler::get_record(const RID *rid, Record *rec) RC RecordPageHandler::get_record(const RID *rid, Record *rec)
{ {
if (rid->slot_num >= page_header_->record_capacity) { if (rid->slot_num >= page_header_->record_capacity) {
LOG_ERROR("Invalid slot_num:%d, exceed page's record capacity, file_id:page_num %d:%d.", LOG_ERROR("Invalid slot_num:%d, exceed page's record capacity, page_num %d.",
rid->slot_num, rid->slot_num, frame_->page_num());
file_id_,
page_handle_.frame->page.page_num);
return RC::RECORD_INVALIDRID; return RC::RECORD_INVALIDRID;
} }
Bitmap bitmap(bitmap_, page_header_->record_capacity); Bitmap bitmap(bitmap_, page_header_->record_capacity);
if (!bitmap.get_bit(rid->slot_num)) { if (!bitmap.get_bit(rid->slot_num)) {
LOG_ERROR("Invalid slot_num:%d, slot is empty, file_id:page_num %d:%d.", LOG_ERROR("Invalid slot_num:%d, slot is empty, page_num %d.",
rid->slot_num, rid->slot_num, frame_->page_num());
file_id_,
page_handle_.frame->page.page_num);
return RC::RECORD_RECORD_NOT_EXIST; return RC::RECORD_RECORD_NOT_EXIST;
} }
...@@ -245,10 +217,8 @@ RC RecordPageHandler::get_first_record(Record *rec) ...@@ -245,10 +217,8 @@ RC RecordPageHandler::get_first_record(Record *rec)
RC RecordPageHandler::get_next_record(Record *rec) RC RecordPageHandler::get_next_record(Record *rec)
{ {
if (rec->rid.slot_num >= page_header_->record_capacity - 1) { if (rec->rid.slot_num >= page_header_->record_capacity - 1) {
LOG_ERROR("Invalid slot_num:%d, exceed page's record capacity, file_id:page_num %d:%d.", LOG_ERROR("Invalid slot_num:%d, exceed page's record capacity, page_num %d.",
rec->rid.slot_num, rec->rid.slot_num, frame_->page_num());
file_id_,
page_handle_.frame->page.page_num);
return RC::RECORD_EOF; return RC::RECORD_EOF;
} }
...@@ -256,7 +226,7 @@ RC RecordPageHandler::get_next_record(Record *rec) ...@@ -256,7 +226,7 @@ RC RecordPageHandler::get_next_record(Record *rec)
int index = bitmap.next_setted_bit(rec->rid.slot_num + 1); int index = bitmap.next_setted_bit(rec->rid.slot_num + 1);
if (index < 0) { if (index < 0) {
LOG_WARN("There is no empty slot on page -- file_id:%d, page_num:%d.", file_id_, page_handle_.frame->page.page_num); LOG_WARN("There is no empty slot on page -- page_num:%d.", frame_->page_num());
return RC::RECORD_EOF; return RC::RECORD_EOF;
} }
...@@ -271,7 +241,7 @@ PageNum RecordPageHandler::get_page_num() const ...@@ -271,7 +241,7 @@ PageNum RecordPageHandler::get_page_num() const
if (nullptr == page_header_) { if (nullptr == page_header_) {
return (PageNum)(-1); return (PageNum)(-1);
} }
return page_handle_.frame->page.page_num; return frame_->page_num();
} }
bool RecordPageHandler::is_full() const bool RecordPageHandler::is_full() const
...@@ -281,21 +251,16 @@ bool RecordPageHandler::is_full() const ...@@ -281,21 +251,16 @@ bool RecordPageHandler::is_full() const
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
RecordFileHandler::RecordFileHandler() : disk_buffer_pool_(nullptr), file_id_(-1) RC RecordFileHandler::init(DiskBufferPool *buffer_pool)
{}
RC RecordFileHandler::init(DiskBufferPool *buffer_pool, int file_id)
{ {
if (disk_buffer_pool_ != nullptr) { if (disk_buffer_pool_ != nullptr) {
LOG_ERROR("%d has been openned.", file_id); LOG_ERROR("record file handler has been openned.");
return RC::RECORD_OPENNED; return RC::RECORD_OPENNED;
} }
disk_buffer_pool_ = buffer_pool; disk_buffer_pool_ = buffer_pool;
file_id_ = file_id;
LOG_INFO("Successfully open %d.", file_id); LOG_INFO("Successfully open record file handle");
return RC::SUCCESS; return RC::SUCCESS;
} }
...@@ -311,8 +276,8 @@ RC RecordFileHandler::insert_record(const char *data, int record_size, RID *rid) ...@@ -311,8 +276,8 @@ RC RecordFileHandler::insert_record(const char *data, int record_size, RID *rid)
RC ret = RC::SUCCESS; RC ret = RC::SUCCESS;
// 找到没有填满的页面 // 找到没有填满的页面
int page_count = 0; int page_count = 0;
if ((ret = disk_buffer_pool_->get_page_count(file_id_, &page_count)) != RC::SUCCESS) { if ((ret = disk_buffer_pool_->get_page_count(&page_count)) != RC::SUCCESS) {
LOG_ERROR("Failed to get page count while inserting record, file_id:%d", this->file_id_); LOG_ERROR("Failed to get page count while inserting record");
return ret; return ret;
} }
...@@ -321,8 +286,8 @@ RC RecordFileHandler::insert_record(const char *data, int record_size, RID *rid) ...@@ -321,8 +286,8 @@ RC RecordFileHandler::insert_record(const char *data, int record_size, RID *rid)
if (page_count >= 2) { if (page_count >= 2) {
// 当前buffer pool 有页面时才尝试加载第一页 // 当前buffer pool 有页面时才尝试加载第一页
// 参考diskBufferPool,有效page的pageNum从1开始 // 参考diskBufferPool,有效page的pageNum从1开始
if ((ret = record_page_handler_.init(*disk_buffer_pool_, file_id_, 1)) != RC::SUCCESS) { if ((ret = record_page_handler_.init(*disk_buffer_pool_, 1)) != RC::SUCCESS) {
LOG_ERROR("Failed to init record page handler, file_id:%d, ret=%d", file_id_, ret); LOG_ERROR("Failed to init record page handler, ret=%d", ret);
return ret; return ret;
} }
current_page_num = record_page_handler_.get_page_num(); current_page_num = record_page_handler_.get_page_num();
...@@ -339,10 +304,10 @@ RC RecordFileHandler::insert_record(const char *data, int record_size, RID *rid) ...@@ -339,10 +304,10 @@ RC RecordFileHandler::insert_record(const char *data, int record_size, RID *rid)
} }
if (current_page_num != record_page_handler_.get_page_num()) { if (current_page_num != record_page_handler_.get_page_num()) {
record_page_handler_.cleanup(); record_page_handler_.cleanup();
ret = record_page_handler_.init(*disk_buffer_pool_, file_id_, current_page_num); ret = record_page_handler_.init(*disk_buffer_pool_, current_page_num);
if (ret != RC::SUCCESS && ret != RC::BUFFERPOOL_INVALID_PAGE_NUM) { if (ret != RC::SUCCESS && ret != RC::BUFFERPOOL_INVALID_PAGE_NUM) {
LOG_ERROR( LOG_ERROR("Failed to init record page handler. page number is %d. ret=%d:%s",
"Failed to init record page handler. page number is %d. ret=%d:%s", current_page_num, ret, strrc(ret)); current_page_num, ret, strrc(ret));
return ret; return ret;
} }
} }
...@@ -355,27 +320,24 @@ RC RecordFileHandler::insert_record(const char *data, int record_size, RID *rid) ...@@ -355,27 +320,24 @@ RC RecordFileHandler::insert_record(const char *data, int record_size, RID *rid)
// 找不到就分配一个新的页面 // 找不到就分配一个新的页面
if (!page_found) { if (!page_found) {
BPPageHandle page_handle; Frame *frame = nullptr;
if ((ret = disk_buffer_pool_->allocate_page(file_id_, &page_handle)) != RC::SUCCESS) { if ((ret = disk_buffer_pool_->allocate_page(&frame)) != RC::SUCCESS) {
LOG_ERROR("Failed to allocate page while inserting record. file_it:%d, ret:%d", file_id_, ret); LOG_ERROR("Failed to allocate page while inserting record. ret:%d", ret);
return ret; return ret;
} }
current_page_num = page_handle.frame->page.page_num; current_page_num = frame->page_num();
record_page_handler_.cleanup(); record_page_handler_.cleanup();
ret = record_page_handler_.init_empty_page(*disk_buffer_pool_, file_id_, current_page_num, record_size); ret = record_page_handler_.init_empty_page(*disk_buffer_pool_, current_page_num, record_size);
if (ret != RC::SUCCESS) { if (ret != RC::SUCCESS) {
LOG_ERROR("Failed to init empty page. file_id:%d, ret:%d", file_id_, ret); LOG_ERROR("Failed to init empty page. ret:%d", ret);
if (RC::SUCCESS != disk_buffer_pool_->unpin_page(&page_handle)) { if (RC::SUCCESS != disk_buffer_pool_->unpin_page(frame)) {
LOG_ERROR("Failed to unpin page. file_id:%d", file_id_); LOG_ERROR("Failed to unpin page. ");
} }
return ret; return ret;
} }
//@@@ TODO, remove unpin page here disk_buffer_pool_->unpin_page(frame);
// if (RC::SUCCESS != disk_buffer_pool_->unpin_page(&page_handle)) {
// LOG_ERROR("Failed to unpin page. file_id:%d", file_id_);
// }
} }
// 找到空闲位置 // 找到空闲位置
...@@ -390,8 +352,8 @@ RC RecordFileHandler::update_record(const Record *rec) ...@@ -390,8 +352,8 @@ RC RecordFileHandler::update_record(const Record *rec)
} }
RC ret; RC ret;
RecordPageHandler page_handler; RecordPageHandler page_handler;
if ((ret = page_handler.init(*disk_buffer_pool_, file_id_, rec->rid.page_num)) != RC::SUCCESS) { if ((ret = page_handler.init(*disk_buffer_pool_, rec->rid.page_num)) != RC::SUCCESS) {
LOG_ERROR("Failed to init record page handler.page number=%d, file_id=%d", rec->rid.page_num, file_id_); LOG_ERROR("Failed to init record page handler.page number=%d", rec->rid.page_num);
return ret; return ret;
} }
...@@ -406,8 +368,8 @@ RC RecordFileHandler::delete_record(const RID *rid) ...@@ -406,8 +368,8 @@ RC RecordFileHandler::delete_record(const RID *rid)
RC ret = RC::SUCCESS; RC ret = RC::SUCCESS;
RecordPageHandler page_handler; RecordPageHandler page_handler;
if ((ret != page_handler.init(*disk_buffer_pool_, file_id_, rid->page_num)) != RC::SUCCESS) { if ((ret != page_handler.init(*disk_buffer_pool_, rid->page_num)) != RC::SUCCESS) {
LOG_ERROR("Failed to init record page handler.page number=%d, file_id:%d", rid->page_num, file_id_); LOG_ERROR("Failed to init record page handler.page number=%d", rid->page_num);
return ret; return ret;
} }
return page_handler.delete_record(rid); return page_handler.delete_record(rid);
...@@ -427,8 +389,8 @@ RC RecordFileHandler::get_record(const RID *rid, Record *rec) ...@@ -427,8 +389,8 @@ RC RecordFileHandler::get_record(const RID *rid, Record *rec)
} }
RecordPageHandler page_handler; RecordPageHandler page_handler;
if ((ret != page_handler.init(*disk_buffer_pool_, file_id_, rid->page_num)) != RC::SUCCESS) { if ((ret != page_handler.init(*disk_buffer_pool_, rid->page_num)) != RC::SUCCESS) {
LOG_ERROR("Failed to init record page handler.page number=%d, file_id:%d", rid->page_num, file_id_); LOG_ERROR("Failed to init record page handler.page number=%d", rid->page_num);
return ret; return ret;
} }
...@@ -437,15 +399,11 @@ RC RecordFileHandler::get_record(const RID *rid, Record *rec) ...@@ -437,15 +399,11 @@ RC RecordFileHandler::get_record(const RID *rid, Record *rec)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
RecordFileScanner::RecordFileScanner() : disk_buffer_pool_(nullptr), file_id_(-1), condition_filter_(nullptr) RC RecordFileScanner::open_scan(DiskBufferPool &buffer_pool, ConditionFilter *condition_filter)
{}
RC RecordFileScanner::open_scan(DiskBufferPool &buffer_pool, int file_id, ConditionFilter *condition_filter)
{ {
close_scan(); close_scan();
disk_buffer_pool_ = &buffer_pool; disk_buffer_pool_ = &buffer_pool;
file_id_ = file_id;
condition_filter_ = condition_filter; condition_filter_ = condition_filter;
return RC::SUCCESS; return RC::SUCCESS;
...@@ -483,8 +441,8 @@ RC RecordFileScanner::get_next_record(Record *rec) ...@@ -483,8 +441,8 @@ RC RecordFileScanner::get_next_record(Record *rec)
Record current_record = *rec; Record current_record = *rec;
int page_count = 0; int page_count = 0;
if ((ret = disk_buffer_pool_->get_page_count(file_id_, &page_count)) != RC::SUCCESS) { if ((ret = disk_buffer_pool_->get_page_count(&page_count)) != RC::SUCCESS) {
LOG_ERROR("Failed to get page count while getting next record. file id=%d", file_id_); LOG_ERROR("Failed to get page count while getting next record.");
return RC::RECORD_EOF; return RC::RECORD_EOF;
} }
...@@ -496,7 +454,7 @@ RC RecordFileScanner::get_next_record(Record *rec) ...@@ -496,7 +454,7 @@ RC RecordFileScanner::get_next_record(Record *rec)
if (current_record.rid.page_num != record_page_handler_.get_page_num()) { if (current_record.rid.page_num != record_page_handler_.get_page_num()) {
record_page_handler_.cleanup(); record_page_handler_.cleanup();
ret = record_page_handler_.init(*disk_buffer_pool_, file_id_, current_record.rid.page_num); ret = record_page_handler_.init(*disk_buffer_pool_, current_record.rid.page_num);
if (ret != RC::SUCCESS && ret != RC::BUFFERPOOL_INVALID_PAGE_NUM) { if (ret != RC::SUCCESS && ret != RC::BUFFERPOOL_INVALID_PAGE_NUM) {
LOG_ERROR("Failed to init record page handler. page num=%d", current_record.rid.page_num); LOG_ERROR("Failed to init record page handler. page num=%d", current_record.rid.page_num);
return ret; return ret;
......
...@@ -15,6 +15,7 @@ See the Mulan PSL v2 for more details. */ ...@@ -15,6 +15,7 @@ See the Mulan PSL v2 for more details. */
#define __OBSERVER_STORAGE_COMMON_RECORD_MANAGER_H_ #define __OBSERVER_STORAGE_COMMON_RECORD_MANAGER_H_
#include <sstream> #include <sstream>
#include <limits>
#include "storage/default/disk_buffer_pool.h" #include "storage/default/disk_buffer_pool.h"
typedef int32_t SlotNum; typedef int32_t SlotNum;
...@@ -96,10 +97,10 @@ struct Record { ...@@ -96,10 +97,10 @@ struct Record {
class RecordPageHandler { class RecordPageHandler {
public: public:
RecordPageHandler(); RecordPageHandler() = default;
~RecordPageHandler(); ~RecordPageHandler();
RC init(DiskBufferPool &buffer_pool, int file_id, PageNum page_num); RC init(DiskBufferPool &buffer_pool, PageNum page_num);
RC init_empty_page(DiskBufferPool &buffer_pool, int file_id, PageNum page_num, int record_size); RC init_empty_page(DiskBufferPool &buffer_pool, PageNum page_num, int record_size);
RC cleanup(); RC cleanup();
RC insert_record(const char *data, RID *rid); RC insert_record(const char *data, RID *rid);
...@@ -114,7 +115,7 @@ public: ...@@ -114,7 +115,7 @@ public:
return rc; return rc;
} }
rc = updater(record); rc = updater(record);
disk_buffer_pool_->mark_dirty(&page_handle_); frame_->mark_dirty();
return rc; return rc;
} }
...@@ -131,51 +132,40 @@ public: ...@@ -131,51 +132,40 @@ public:
protected: protected:
char *get_record_data(SlotNum slot_num) char *get_record_data(SlotNum slot_num)
{ {
return page_handle_.frame->page.data + page_header_->first_record_offset + (page_header_->record_size * slot_num); return frame_->data() + page_header_->first_record_offset + (page_header_->record_size * slot_num);
} }
protected: protected:
DiskBufferPool *disk_buffer_pool_; DiskBufferPool *disk_buffer_pool_ = nullptr;
int file_id_; Frame *frame_ = nullptr;
BPPageHandle page_handle_; PageHeader *page_header_ = nullptr;
PageHeader *page_header_; char *bitmap_ = nullptr;
char *bitmap_;
}; };
class RecordFileHandler { class RecordFileHandler {
public: public:
RecordFileHandler(); RecordFileHandler() = default;
RC init(DiskBufferPool *buffer_pool, int file_id); RC init(DiskBufferPool *buffer_pool);
void close(); void close();
/** /**
* 更新指定文件中的记录,rec指向的记录结构中的rid字段为要更新的记录的标识符, * 更新指定文件中的记录,rec指向的记录结构中的rid字段为要更新的记录的标识符,
* pData字段指向新的记录内容 * pData字段指向新的记录内容
* @param rec
* @return
*/ */
RC update_record(const Record *rec); RC update_record(const Record *rec);
/** /**
* 从指定文件中删除标识符为rid的记录 * 从指定文件中删除标识符为rid的记录
* @param rid
* @return
*/ */
RC delete_record(const RID *rid); RC delete_record(const RID *rid);
/** /**
* 插入一个新的记录到指定文件中,pData为指向新纪录内容的指针,返回该记录的标识符rid * 插入一个新的记录到指定文件中,pData为指向新纪录内容的指针,返回该记录的标识符rid
* @param data
* @param rid
* @return
*/ */
RC insert_record(const char *data, int record_size, RID *rid); RC insert_record(const char *data, int record_size, RID *rid);
/** /**
* 获取指定文件中标识符为rid的记录内容到rec指向的记录结构中 * 获取指定文件中标识符为rid的记录内容到rec指向的记录结构中
* @param rid
* @param rec
* @return
*/ */
RC get_record(const RID *rid, Record *rec); RC get_record(const RID *rid, Record *rec);
...@@ -185,7 +175,7 @@ public: ...@@ -185,7 +175,7 @@ public:
RC rc = RC::SUCCESS; RC rc = RC::SUCCESS;
RecordPageHandler page_handler; RecordPageHandler page_handler;
if ((rc != page_handler.init(*disk_buffer_pool_, file_id_, rid->page_num)) != RC::SUCCESS) { if ((rc != page_handler.init(*disk_buffer_pool_, rid->page_num)) != RC::SUCCESS) {
return rc; return rc;
} }
...@@ -193,15 +183,13 @@ public: ...@@ -193,15 +183,13 @@ public:
} }
private: private:
DiskBufferPool *disk_buffer_pool_; DiskBufferPool *disk_buffer_pool_ = nullptr;
int file_id_; // 参考DiskBufferPool中的fileId
RecordPageHandler record_page_handler_; // 目前只有insert record使用 RecordPageHandler record_page_handler_; // 目前只有insert record使用
}; };
class RecordFileScanner { class RecordFileScanner {
public: public:
RecordFileScanner(); RecordFileScanner() = default;
/** /**
* 打开一个文件扫描。 * 打开一个文件扫描。
...@@ -210,13 +198,8 @@ public: ...@@ -210,13 +198,8 @@ public:
* 然后再调用GetNextRec函数来逐个返回文件中满足条件的记录。 * 然后再调用GetNextRec函数来逐个返回文件中满足条件的记录。
* 如果条件数量conNum为0,则意味着检索文件中的所有记录。 * 如果条件数量conNum为0,则意味着检索文件中的所有记录。
* 如果条件不为空,则要对每条记录进行条件比较,只有满足所有条件的记录才被返回 * 如果条件不为空,则要对每条记录进行条件比较,只有满足所有条件的记录才被返回
* @param buffer_pool
* @param file_id
* @param condition_num
* @param conditions
* @return
*/ */
RC open_scan(DiskBufferPool &buffer_pool, int file_id, ConditionFilter *condition_filter); RC open_scan(DiskBufferPool &buffer_pool, ConditionFilter *condition_filter);
/** /**
* 关闭一个文件扫描,释放相应的资源 * 关闭一个文件扫描,释放相应的资源
...@@ -236,10 +219,9 @@ public: ...@@ -236,10 +219,9 @@ public:
RC get_next_record(Record *rec); RC get_next_record(Record *rec);
private: private:
DiskBufferPool *disk_buffer_pool_; DiskBufferPool *disk_buffer_pool_ = nullptr;
int file_id_; // 参考DiskBufferPool中的fileId
ConditionFilter *condition_filter_; ConditionFilter *condition_filter_ = nullptr;
RecordPageHandler record_page_handler_; RecordPageHandler record_page_handler_;
}; };
......
...@@ -29,9 +29,6 @@ See the Mulan PSL v2 for more details. */ ...@@ -29,9 +29,6 @@ See the Mulan PSL v2 for more details. */
#include "storage/index/bplus_tree_index.h" #include "storage/index/bplus_tree_index.h"
#include "storage/trx/trx.h" #include "storage/trx/trx.h"
Table::Table() : data_buffer_pool_(nullptr), file_id_(-1), record_handler_(nullptr)
{}
Table::~Table() Table::~Table()
{ {
if (record_handler_ != nullptr) { if (record_handler_ != nullptr) {
...@@ -39,8 +36,8 @@ Table::~Table() ...@@ -39,8 +36,8 @@ Table::~Table()
record_handler_ = nullptr; record_handler_ = nullptr;
} }
if (data_buffer_pool_ != nullptr && file_id_ >= 0) { if (data_buffer_pool_ != nullptr) {
data_buffer_pool_->close_file(file_id_); data_buffer_pool_->close_file();
data_buffer_pool_ = nullptr; data_buffer_pool_ = nullptr;
} }
...@@ -102,8 +99,8 @@ RC Table::create( ...@@ -102,8 +99,8 @@ RC Table::create(
fs.close(); fs.close();
std::string data_file = table_data_file(base_dir, name); std::string data_file = table_data_file(base_dir, name);
data_buffer_pool_ = theGlobalDiskBufferPool(); BufferPoolManager &bpm = BufferPoolManager::instance();
rc = data_buffer_pool_->create_file(data_file.c_str()); rc = bpm.create_file(data_file.c_str());
if (rc != RC::SUCCESS) { if (rc != RC::SUCCESS) {
LOG_ERROR("Failed to create disk buffer pool of data file. file name=%s", data_file.c_str()); LOG_ERROR("Failed to create disk buffer pool of data file. file name=%s", data_file.c_str());
return rc; return rc;
...@@ -339,28 +336,24 @@ RC Table::make_record(int value_num, const Value *values, char *&record_out) ...@@ -339,28 +336,24 @@ RC Table::make_record(int value_num, const Value *values, char *&record_out)
RC Table::init_record_handler(const char *base_dir) RC Table::init_record_handler(const char *base_dir)
{ {
std::string data_file = table_data_file(base_dir, table_meta_.name()); std::string data_file = table_data_file(base_dir, table_meta_.name());
if (nullptr == data_buffer_pool_) {
data_buffer_pool_ = theGlobalDiskBufferPool();
}
int data_buffer_pool_file_id; RC rc = BufferPoolManager::instance().open_file(data_file.c_str(), data_buffer_pool_);
RC rc = data_buffer_pool_->open_file(data_file.c_str(), &data_buffer_pool_file_id);
if (rc != RC::SUCCESS) { if (rc != RC::SUCCESS) {
LOG_ERROR("Failed to open disk buffer pool for file:%s. rc=%d:%s", data_file.c_str(), rc, strrc(rc)); LOG_ERROR("Failed to open disk buffer pool for file:%s. rc=%d:%s", data_file.c_str(), rc, strrc(rc));
return rc; return rc;
} }
record_handler_ = new RecordFileHandler(); record_handler_ = new RecordFileHandler();
rc = record_handler_->init(data_buffer_pool_, data_buffer_pool_file_id); rc = record_handler_->init(data_buffer_pool_);
if (rc != RC::SUCCESS) { if (rc != RC::SUCCESS) {
LOG_ERROR("Failed to init record handler. rc=%d:%s", rc, strrc(rc)); LOG_ERROR("Failed to init record handler. rc=%d:%s", rc, strrc(rc));
data_buffer_pool_->close_file(data_buffer_pool_file_id); data_buffer_pool_->close_file();
data_buffer_pool_ = nullptr;
delete record_handler_; delete record_handler_;
record_handler_ = nullptr; record_handler_ = nullptr;
return rc; return rc;
} }
file_id_ = data_buffer_pool_file_id;
return rc; return rc;
} }
...@@ -419,9 +412,9 @@ RC Table::scan_record( ...@@ -419,9 +412,9 @@ RC Table::scan_record(
RC rc = RC::SUCCESS; RC rc = RC::SUCCESS;
RecordFileScanner scanner; RecordFileScanner scanner;
rc = scanner.open_scan(*data_buffer_pool_, file_id_, filter); rc = scanner.open_scan(*data_buffer_pool_, filter);
if (rc != RC::SUCCESS) { if (rc != RC::SUCCESS) {
LOG_ERROR("failed to open scanner. file id=%d. rc=%d:%s", file_id_, rc, strrc(rc)); LOG_ERROR("failed to open scanner. rc=%d:%s", rc, strrc(rc));
return rc; return rc;
} }
...@@ -441,7 +434,7 @@ RC Table::scan_record( ...@@ -441,7 +434,7 @@ RC Table::scan_record(
if (RC::RECORD_EOF == rc) { if (RC::RECORD_EOF == rc) {
rc = RC::SUCCESS; rc = RC::SUCCESS;
} else { } else {
LOG_ERROR("failed to scan record. file id=%d, rc=%d:%s", file_id_, rc, strrc(rc)); LOG_ERROR("failed to scan record. rc=%d:%s", rc, strrc(rc));
} }
scanner.close_scan(); scanner.close_scan();
return rc; return rc;
...@@ -834,7 +827,7 @@ IndexScanner *Table::find_index_for_scan(const ConditionFilter *filter) ...@@ -834,7 +827,7 @@ IndexScanner *Table::find_index_for_scan(const ConditionFilter *filter)
RC Table::sync() RC Table::sync()
{ {
RC rc = data_buffer_pool_->purge_all_pages(file_id_); RC rc = data_buffer_pool_->purge_all_pages();
if (rc != RC::SUCCESS) { if (rc != RC::SUCCESS) {
LOG_ERROR("Failed to flush table's data pages. table=%s, rc=%d:%s", name(), rc, strrc(rc)); LOG_ERROR("Failed to flush table's data pages. table=%s, rc=%d:%s", name(), rc, strrc(rc));
return rc; return rc;
......
...@@ -30,7 +30,7 @@ class Trx; ...@@ -30,7 +30,7 @@ class Trx;
class Table { class Table {
public: public:
Table(); Table() = default;
~Table(); ~Table();
/** /**
...@@ -101,10 +101,9 @@ private: ...@@ -101,10 +101,9 @@ private:
private: private:
std::string base_dir_; std::string base_dir_;
TableMeta table_meta_; TableMeta table_meta_;
DiskBufferPool *data_buffer_pool_; /// 数据文件关联的buffer pool DiskBufferPool *data_buffer_pool_ = nullptr; /// 数据文件关联的buffer pool
int file_id_; RecordFileHandler *record_handler_ = nullptr; /// 记录操作
RecordFileHandler *record_handler_; /// 记录操作
std::vector<Index *> indexes_; std::vector<Index *> indexes_;
}; };
#endif // __OBSERVER_STORAGE_COMMON_TABLE_H__ #endif // __OBSERVER_STORAGE_COMMON_TABLE_H__
\ No newline at end of file
...@@ -24,10 +24,20 @@ See the Mulan PSL v2 for more details. */ ...@@ -24,10 +24,20 @@ See the Mulan PSL v2 for more details. */
#include "storage/common/table.h" #include "storage/common/table.h"
#include "storage/common/condition_filter.h" #include "storage/common/condition_filter.h"
static DefaultHandler *default_handler = nullptr;
void DefaultHandler::set_default(DefaultHandler *handler)
{
if (default_handler != nullptr && handler != nullptr) {
LOG_ERROR("default handler is setted");
abort();
}
default_handler = handler;
}
DefaultHandler &DefaultHandler::get_default() DefaultHandler &DefaultHandler::get_default()
{ {
static DefaultHandler handler; return *default_handler;
return handler;
} }
DefaultHandler::DefaultHandler() DefaultHandler::DefaultHandler()
......
...@@ -159,6 +159,7 @@ public: ...@@ -159,6 +159,7 @@ public:
RC sync(); RC sync();
public: public:
static void set_default(DefaultHandler *handler);
static DefaultHandler &get_default(); static DefaultHandler &get_default();
private: private:
...@@ -167,4 +168,4 @@ private: ...@@ -167,4 +168,4 @@ private:
std::map<std::string, Db *> opened_dbs_; std::map<std::string, Db *> opened_dbs_;
}; // class Handler }; // class Handler
#endif // __OBSERVER_STORAGE_DEFAULT_ENGINE_H__ #endif // __OBSERVER_STORAGE_DEFAULT_ENGINE_H__
\ No newline at end of file
...@@ -14,19 +14,23 @@ See the Mulan PSL v2 for more details. */ ...@@ -14,19 +14,23 @@ See the Mulan PSL v2 for more details. */
#ifndef __OBSERVER_STORAGE_COMMON_PAGE_MANAGER_H_ #ifndef __OBSERVER_STORAGE_COMMON_PAGE_MANAGER_H_
#define __OBSERVER_STORAGE_COMMON_PAGE_MANAGER_H_ #define __OBSERVER_STORAGE_COMMON_PAGE_MANAGER_H_
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <sys/types.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/stat.h>
#include <time.h> #include <time.h>
#include <string>
#include <unordered_map>
#include "rc.h" #include "rc.h"
#include "common/mm/mem_pool.h" #include "common/mm/mem_pool.h"
typedef int PageNum; typedef int32_t PageNum;
class BufferPoolManager;
class DiskBufferPool;
// //
#define BP_INVALID_PAGE_NUM (-1) #define BP_INVALID_PAGE_NUM (-1)
...@@ -34,73 +38,82 @@ typedef int PageNum; ...@@ -34,73 +38,82 @@ typedef int PageNum;
#define BP_PAGE_DATA_SIZE (BP_PAGE_SIZE - sizeof(PageNum)) #define BP_PAGE_DATA_SIZE (BP_PAGE_SIZE - sizeof(PageNum))
#define BP_FILE_SUB_HDR_SIZE (sizeof(BPFileSubHeader)) #define BP_FILE_SUB_HDR_SIZE (sizeof(BPFileSubHeader))
#define BP_BUFFER_SIZE 256 #define BP_BUFFER_SIZE 256
#define MAX_OPEN_FILE 1024
typedef struct { struct Page {
PageNum page_num; PageNum page_num;
char data[BP_PAGE_DATA_SIZE]; char data[BP_PAGE_DATA_SIZE];
} Page; };
// sizeof(Page) should be equal to BP_PAGE_SIZE // sizeof(Page) should be equal to BP_PAGE_SIZE
typedef struct { /**
PageNum page_count; * BufferPool的文件第一个页面,存放一些元数据信息,包括了后面每页的分配信息。
int allocated_pages; * TODO 1. 当前的做法,只能分配比较少的页面,你可以扩展一下,支持更多的页面或无限多的页面吗?
} BPFileSubHeader; * 可以参考Linux ext(n)和Windows NTFS等文件系统
* 2. 当前使用bitmap存放页面分配情况,但是这种方法在页面非常多的时候,查找空闲页面的
typedef struct { * 效率非常低,你有办法优化吗?
int file_id; */
std::set<PageNum> pages; struct BPFileHeader {
} BPDisposedPages; int32_t page_count; //! 当前文件一共有多少个页面
int32_t allocated_pages; //! 已经分配了多少个页面
typedef struct Frame_ { char bitmap[0]; //! 页面分配位图, 第0个页面(就是当前页面),总是1
bool dirty; };
unsigned int pin_count;
unsigned long acc_time;
int file_desc;
Page page;
bool can_purge() class Frame
{
public:
void clear_page()
{ {
return pin_count <= 0; memset(&page_, 0, sizeof(page_));
} }
} Frame;
typedef struct BPPageHandle { PageNum page_num() const
BPPageHandle() : open(false), frame(nullptr) {
{} return page_.page_num;
}
PageNum page_num() const { void set_page_num(PageNum page_num)
return frame->page.page_num; {
page_.page_num = page_num;
} }
/**
* 标记指定页面为“脏”页。如果修改了页面的内容,则应调用此函数,
* 以便该页面被淘汰出缓冲区时系统将新的页面数据写入磁盘文件
*/
void mark_dirty() { void mark_dirty() {
this->frame->dirty = true; dirty_ = true;
} }
char *data() { char *data() {
return this->frame->page.data; return page_.data;
} }
bool open;
Frame *frame;
} BPPageHandle;
class BPFileHandle { int file_desc() const
public: {
BPFileHandle(); return file_desc_;
~BPFileHandle(); }
public: void set_file_desc(int fd)
bool bopen; {
const char *file_name; file_desc_ = fd;
int file_desc; }
Frame *hdr_frame; bool can_purge()
Page *hdr_page; {
char *bitmap; return pin_count_ <= 0;
BPFileSubHeader *file_sub_header; }
private:
friend class DiskBufferPool;
bool dirty_ = false;
unsigned int pin_count_ = 0;
unsigned long acc_time_ = 0;
int file_desc_ = -1;
Page page_;
}; };
class BPManager : public common::MemPoolSimple<Frame> { class BPFrameManager : public common::MemPoolSimple<Frame> {
public: public:
BPManager(const char *tag); BPFrameManager(const char *tag);
Frame *get(int file_desc, PageNum page_num); Frame *get(int file_desc, PageNum page_num);
...@@ -111,26 +124,7 @@ public: ...@@ -111,26 +124,7 @@ public:
class DiskBufferPool { class DiskBufferPool {
public: public:
static DiskBufferPool *mk_instance() DiskBufferPool(BufferPoolManager &bp_manager, BPFrameManager &frame_manager);
{
return new DiskBufferPool();
}
static void set_pool_num(int pool_num)
{
if (pool_num > 0) {
POOL_NUM = pool_num;
LOG_INFO("Successfully set POOL_NUM as %d", pool_num);
} else {
LOG_INFO("Invalid input argument pool_num:%d", pool_num);
}
}
static const int get_pool_num()
{
return POOL_NUM;
}
~DiskBufferPool(); ~DiskBufferPool();
/** /**
...@@ -142,53 +136,36 @@ public: ...@@ -142,53 +136,36 @@ public:
* 根据文件名打开一个分页文件,返回文件ID * 根据文件名打开一个分页文件,返回文件ID
* @return * @return
*/ */
RC open_file(const char *file_name, int *file_id); RC open_file(const char *file_name);
/** /**
* 关闭fileID对应的分页文件 * 关闭分页文件
*/ */
RC close_file(int file_id); RC close_file();
/** /**
* 根据文件ID和页号获取指定页面到缓冲区,返回页面句柄指针。 * 根据文件ID和页号获取指定页面到缓冲区,返回页面句柄指针。
* @return * @return
*/ */
RC get_this_page(int file_id, PageNum page_num, BPPageHandle *page_handle); RC get_this_page(PageNum page_num, Frame **frame);
/** /**
* 在指定文件中分配一个新的页面,并将其放入缓冲区,返回页面句柄指针。 * 在指定文件中分配一个新的页面,并将其放入缓冲区,返回页面句柄指针。
* 分配页面时,如果文件中有空闲页,就直接分配一个空闲页; * 分配页面时,如果文件中有空闲页,就直接分配一个空闲页;
* 如果文件中没有空闲页,则扩展文件规模来增加新的空闲页。 * 如果文件中没有空闲页,则扩展文件规模来增加新的空闲页。
*/ */
RC allocate_page(int file_id, BPPageHandle *page_handle); RC allocate_page(Frame **frame);
/**
* 根据页面句柄指针返回对应的页面号
*/
RC get_page_num(BPPageHandle *page_handle, PageNum *page_num);
/**
* 根据页面句柄指针返回对应的数据区指针
*/
RC get_data(BPPageHandle *page_handle, char **data);
/** /**
* 比purge_page多一个动作, 在磁盘上将对应的页数据删掉。 * 比purge_page多一个动作, 在磁盘上将对应的页数据删掉。
*/ */
RC dispose_page(int file_id, PageNum page_num); RC dispose_page(PageNum page_num);
/** /**
* 释放指定文件关联的页的内存, 如果已经脏, 则刷到磁盘,除了pinned page * 释放指定文件关联的页的内存, 如果已经脏, 则刷到磁盘,除了pinned page
* @param file_handle
* @param page_num 如果不指定page_num 将刷新所有页
*/ */
RC purge_page(int file_id, PageNum page_num); RC purge_page(PageNum page_num);
RC purge_all_pages();
/**
* 标记指定页面为“脏”页。如果修改了页面的内容,则应调用此函数,
* 以便该页面被淘汰出缓冲区时系统将新的页面数据写入磁盘文件
*/
RC mark_dirty(BPPageHandle *page_handle);
/** /**
* 此函数用于解除pageHandle对应页面的驻留缓冲区限制。 * 此函数用于解除pageHandle对应页面的驻留缓冲区限制。
...@@ -196,44 +173,66 @@ public: ...@@ -196,44 +173,66 @@ public:
* 该页面被设置为驻留缓冲区状态,以防止其在处理过程中被置换出去, * 该页面被设置为驻留缓冲区状态,以防止其在处理过程中被置换出去,
* 因此在该页面使用完之后应调用此函数解除该限制,使得该页面此后可以正常地被淘汰出缓冲区 * 因此在该页面使用完之后应调用此函数解除该限制,使得该页面此后可以正常地被淘汰出缓冲区
*/ */
RC unpin_page(BPPageHandle *page_handle); RC unpin_page(Frame *frame);
/** /**
* 获取文件的总页数 * 获取文件的总页数
*/ */
RC get_page_count(int file_id, int *page_count); RC get_page_count(int *page_count);
RC check_all_pages_unpinned();
RC purge_all_pages(int file_id); int file_desc() const;
RC check_all_pages_unpinned(int file_id); /**
* 如果页面是脏的,就将数据刷新到磁盘
*/
RC flush_page(Frame &frame);
protected: protected:
RC allocate_page(Frame **buf); RC allocate_frame(Frame **buf);
/** /**
* 刷新指定文件关联的所有脏页到磁盘,除了pinned page * 刷新指定页面到磁盘(flush),并且释放关联的Frame
* @param file_handle
* @param page_num 如果不指定page_num 将刷新所有页
*/ */
RC purge_page(BPFileHandle *file_handle, PageNum page_num); RC purge_frame(Frame *used_frame);
RC purge_page(Frame *used_frame); RC check_page_num(PageNum page_num);
RC purge_all_pages(BPFileHandle *file_handle);
RC check_file_id(int file_id);
RC check_page_num(PageNum page_num, BPFileHandle *file_handle);
RC load_page(PageNum page_num, BPFileHandle *file_handle, Frame *frame);
RC flush_page(Frame *frame);
private: /**
DiskBufferPool(); * 加载指定页面的数据到内存中
*/
RC load_page(PageNum page_num, Frame *frame);
private: private:
BPManager bp_manager_; BufferPoolManager &bp_manager_;
BPFileHandle *open_list_[MAX_OPEN_FILE] = {nullptr}; BPFrameManager & frame_manager_;
std::map<int, BPDisposedPages> disposed_pages; std::string file_name_;
int file_desc_ = -1;
static int POOL_NUM; Frame * hdr_frame_ = nullptr;
BPFileHeader * file_header_ = nullptr;
std::set<PageNum> disposed_pages;
}; };
DiskBufferPool *theGlobalDiskBufferPool(); class BufferPoolManager
{
public:
BufferPoolManager();
~BufferPoolManager();
RC create_file(const char *file_name);
RC open_file(const char *file_name, DiskBufferPool *&bp);
RC close_file(const char *file_name);
RC flush_page(Frame &frame);
public:
static void set_instance(BufferPoolManager *bpm);
static BufferPoolManager &instance();
private:
BPFrameManager frame_manager_{"BufPool"};
std::unordered_map<std::string, DiskBufferPool *> buffer_pools_;
std::unordered_map<int, DiskBufferPool *> fd_buffer_pools_;
};
#endif //__OBSERVER_STORAGE_COMMON_PAGE_MANAGER_H_ #endif //__OBSERVER_STORAGE_COMMON_PAGE_MANAGER_H_
...@@ -19,6 +19,7 @@ See the Mulan PSL v2 for more details. */ ...@@ -19,6 +19,7 @@ See the Mulan PSL v2 for more details. */
#include <string.h> #include <string.h>
#include <sstream> #include <sstream>
#include <functional>
#include "storage/common/record_manager.h" #include "storage/common/record_manager.h"
#include "storage/default/disk_buffer_pool.h" #include "storage/default/disk_buffer_pool.h"
...@@ -244,17 +245,17 @@ struct InternalIndexNode : public IndexNode { ...@@ -244,17 +245,17 @@ struct InternalIndexNode : public IndexNode {
class IndexNodeHandler { class IndexNodeHandler {
public: public:
IndexNodeHandler(const IndexFileHeader &header, BPPageHandle &page_handle); IndexNodeHandler(const IndexFileHeader &header, Frame *frame);
void init_empty(bool leaf); void init_empty(bool leaf);
bool is_leaf() const; bool is_leaf() const;
int key_size() const; int key_size() const;
int value_size() const; int value_size() const;
int item_size() const; int item_size() const;
void increase_size(int n); void increase_size(int n);
int size() const; int size() const;
void set_parent_page_num(PageNum page_num); void set_parent_page_num(PageNum page_num);
PageNum parent_page_num() const; PageNum parent_page_num() const;
...@@ -272,7 +273,7 @@ protected: ...@@ -272,7 +273,7 @@ protected:
class LeafIndexNodeHandler : public IndexNodeHandler { class LeafIndexNodeHandler : public IndexNodeHandler {
public: public:
LeafIndexNodeHandler(const IndexFileHeader &header, BPPageHandle &page_handle); LeafIndexNodeHandler(const IndexFileHeader &header, Frame *frame);
void init_empty(); void init_empty();
void set_next_page(PageNum page_num); void set_next_page(PageNum page_num);
...@@ -293,18 +294,18 @@ public: ...@@ -293,18 +294,18 @@ public:
void insert(int index, const char *key, const char *value); void insert(int index, const char *key, const char *value);
void remove(int index); void remove(int index);
int remove(const char *key, const KeyComparator &comparator); int remove(const char *key, const KeyComparator &comparator);
RC move_half_to(LeafIndexNodeHandler &other, DiskBufferPool *bp, int file_id); RC move_half_to(LeafIndexNodeHandler &other, DiskBufferPool *bp);
RC move_first_to_end(LeafIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool, int file_id); RC move_first_to_end(LeafIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool);
RC move_last_to_front(LeafIndexNodeHandler &other, DiskBufferPool *bp, int file_id); RC move_last_to_front(LeafIndexNodeHandler &other, DiskBufferPool *bp);
/** /**
* move all items to left page * move all items to left page
*/ */
RC move_to(LeafIndexNodeHandler &other, DiskBufferPool *bp, int file_id); RC move_to(LeafIndexNodeHandler &other, DiskBufferPool *bp);
int max_size() const; int max_size() const;
int min_size() const; int min_size() const;
bool validate(const KeyComparator &comparator, DiskBufferPool *bp, int file_id) const; bool validate(const KeyComparator &comparator, DiskBufferPool *bp) const;
friend std::string to_string(const LeafIndexNodeHandler &handler, const KeyPrinter &printer); friend std::string to_string(const LeafIndexNodeHandler &handler, const KeyPrinter &printer);
private: private:
...@@ -321,20 +322,20 @@ private: ...@@ -321,20 +322,20 @@ private:
class InternalIndexNodeHandler : public IndexNodeHandler { class InternalIndexNodeHandler : public IndexNodeHandler {
public: public:
InternalIndexNodeHandler(const IndexFileHeader &header, BPPageHandle &page_handle); InternalIndexNodeHandler(const IndexFileHeader &header, Frame *frame);
void init_empty(); void init_empty();
void create_new_root(PageNum first_page_num, const char *key, PageNum page_num); void create_new_root(PageNum first_page_num, const char *key, PageNum page_num);
void insert(const char *key, PageNum page_num, const KeyComparator &comparator); void insert(const char *key, PageNum page_num, const KeyComparator &comparator);
RC move_half_to(LeafIndexNodeHandler &other, DiskBufferPool *bp, int file_id); RC move_half_to(LeafIndexNodeHandler &other, DiskBufferPool *bp);
char *key_at(int index); char *key_at(int index);
PageNum value_at(int index); PageNum value_at(int index);
/** /**
* 返回指定子节点在当前节点中的索引 * 返回指定子节点在当前节点中的索引
*/ */
int value_index(PageNum page_num); int value_index(PageNum page_num);
void set_key_at(int index, const char *key); void set_key_at(int index, const char *key);
void remove(int index); void remove(int index);
...@@ -349,18 +350,18 @@ public: ...@@ -349,18 +350,18 @@ public:
int max_size() const; int max_size() const;
int min_size() const; int min_size() const;
RC move_to(InternalIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool, int file_id); RC move_to(InternalIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool);
RC move_first_to_end(InternalIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool, int file_id); RC move_first_to_end(InternalIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool);
RC move_last_to_front(InternalIndexNodeHandler &other, DiskBufferPool *bp, int file_id); RC move_last_to_front(InternalIndexNodeHandler &other, DiskBufferPool *bp);
RC move_half_to(InternalIndexNodeHandler &other, DiskBufferPool *bp, int file_id); RC move_half_to(InternalIndexNodeHandler &other, DiskBufferPool *bp);
bool validate(const KeyComparator &comparator, DiskBufferPool *bp, int file_id) const; bool validate(const KeyComparator &comparator, DiskBufferPool *bp) const;
friend std::string to_string(const InternalIndexNodeHandler &handler, const KeyPrinter &printer); friend std::string to_string(const InternalIndexNodeHandler &handler, const KeyPrinter &printer);
private: private:
RC copy_from(const char *items, int num, DiskBufferPool *disk_buffer_pool, int file_id); RC copy_from(const char *items, int num, DiskBufferPool *disk_buffer_pool);
RC append(const char *item, DiskBufferPool *bp, int file_id); RC append(const char *item, DiskBufferPool *bp);
RC preappend(const char *item, DiskBufferPool *bp, int file_id); RC preappend(const char *item, DiskBufferPool *bp);
private: private:
char *__item_at(int index) const; char *__item_at(int index) const;
...@@ -418,11 +419,6 @@ public: ...@@ -418,11 +419,6 @@ public:
RC sync(); RC sync();
const int get_file_id()
{
return file_id_;
}
/** /**
* Check whether current B+ tree is invalid or not. * Check whether current B+ tree is invalid or not.
* return true means current tree is valid, return false means current tree is invalid. * return true means current tree is valid, return false means current tree is invalid.
...@@ -435,52 +431,48 @@ public: ...@@ -435,52 +431,48 @@ public:
RC print_leafs(); RC print_leafs();
private: private:
RC print_leaf(BPPageHandle &page_handle); RC print_leaf(Frame *frame);
RC print_internal_node_recursive(BPPageHandle &page_handle); RC print_internal_node_recursive(Frame *frame);
bool validate_node(IndexNode *node); bool validate_node(IndexNode *node);
bool validate_leaf_link(); bool validate_leaf_link();
bool validate_node_recursive(BPPageHandle &page_handle); bool validate_node_recursive(Frame *frame);
protected: protected:
RC find_leaf(const char *key, BPPageHandle &page_handle); RC find_leaf(const char *key, Frame *&frame);
RC left_most_page(BPPageHandle &page_handle); RC left_most_page(Frame *&frame);
RC right_most_page(BPPageHandle &page_handle); RC right_most_page(Frame *&frame);
RC find_leaf_internal(const std::function<PageNum(InternalIndexNodeHandler &)> &child_page_getter, RC find_leaf_internal(const std::function<PageNum(InternalIndexNodeHandler &)> &child_page_getter,
BPPageHandle &page_handle); Frame *&frame);
RC insert_into_parent( RC insert_into_parent(
PageNum parent_page, BPPageHandle &left_page_handle, const char *pkey, BPPageHandle &right_page_handle); PageNum parent_page, Frame *left_frame, const char *pkey, Frame &right_frame);
RC split_leaf(BPPageHandle &leaf_page_handle);
RC delete_entry_internal(BPPageHandle &leaf_page_handle, const char *key); RC delete_entry_internal(Frame *leaf_frame, const char *key);
RC insert_into_new_root(BPPageHandle &left_page_handle, const char *pkey, BPPageHandle &right_page_handle); RC insert_into_new_root(Frame *left_frame, const char *pkey, Frame &right_frame);
template <typename IndexNodeHandlerType> template <typename IndexNodeHandlerType>
RC split(BPPageHandle &page_handle, BPPageHandle &new_page_handle); RC split(Frame *frame, Frame *&new_frame);
template <typename IndexNodeHandlerType> template <typename IndexNodeHandlerType>
RC coalesce_or_redistribute(BPPageHandle &page_handle); RC coalesce_or_redistribute(Frame *frame);
template <typename IndexNodeHandlerType> template <typename IndexNodeHandlerType>
RC coalesce(BPPageHandle &neighbor_page_handle, BPPageHandle &page_handle, RC coalesce(Frame *neighbor_frame, Frame *frame, Frame *parent_frame, int index);
BPPageHandle &parent_page_handle, int index);
template <typename IndexNodeHandlerType> template <typename IndexNodeHandlerType>
RC redistribute(BPPageHandle &neighbor_page_handle, BPPageHandle &page_handle, RC redistribute(Frame *neighbor_frame, Frame *frame, Frame *parent_frame, int index);
BPPageHandle &parent_page_handle, int index);
RC insert_entry_into_parent(BPPageHandle &page_handle, BPPageHandle &new_page_handle, const char *key); RC insert_entry_into_parent(Frame *frame, Frame *new_frame, const char *key);
RC insert_entry_into_leaf_node(BPPageHandle &page_handle, const char *pkey, const RID *rid); RC insert_entry_into_leaf_node(Frame *frame, const char *pkey, const RID *rid);
RC update_root_page_num(); RC update_root_page_num();
RC create_new_tree(const char *key, const RID *rid); RC create_new_tree(const char *key, const RID *rid);
RC adjust_root(BPPageHandle &root_page_handle); RC adjust_root(Frame *root_frame);
private: private:
char *make_key(const char *user_key, const RID &rid); char *make_key(const char *user_key, const RID &rid);
void free_key(char *key); void free_key(char *key);
protected: protected:
DiskBufferPool *disk_buffer_pool_ = nullptr; DiskBufferPool *disk_buffer_pool_ = nullptr;
int file_id_ = -1;
bool header_dirty_ = false; bool header_dirty_ = false;
IndexFileHeader file_header_; IndexFileHeader file_header_;
...@@ -519,10 +511,10 @@ private: ...@@ -519,10 +511,10 @@ private:
/// 使用左右叶子节点和位置来表示扫描的起始位置和终止位置 /// 使用左右叶子节点和位置来表示扫描的起始位置和终止位置
/// 起始位置和终止位置都是有效的数据 /// 起始位置和终止位置都是有效的数据
BPPageHandle left_page_handle_; Frame * left_frame_ = nullptr;
BPPageHandle right_page_handle_; Frame * right_frame_ = nullptr;
int iter_index_ = -1; int iter_index_ = -1;
int end_index_ = -1; // use -1 for end of scan int end_index_ = -1; // use -1 for end of scan
}; };
#endif //__OBSERVER_STORAGE_COMMON_INDEX_MANAGER_H_ #endif //__OBSERVER_STORAGE_COMMON_INDEX_MANAGER_H_
...@@ -79,10 +79,8 @@ RC BplusTreeIndex::open(const char *file_name, const IndexMeta &index_meta, cons ...@@ -79,10 +79,8 @@ RC BplusTreeIndex::open(const char *file_name, const IndexMeta &index_meta, cons
RC BplusTreeIndex::close() RC BplusTreeIndex::close()
{ {
if (inited_) { if (inited_) {
LOG_INFO("Begin to close index, file_id:%d, index:%s, field:%s", LOG_INFO("Begin to close index, index:%s, field:%s",
index_handler_.get_file_id(), index_meta_.name(), index_meta_.field());
index_meta_.name(),
index_meta_.field());
index_handler_.close(); index_handler_.close();
inited_ = false; inited_ = false;
} }
......
...@@ -15,68 +15,68 @@ See the Mulan PSL v2 for more details. */ ...@@ -15,68 +15,68 @@ See the Mulan PSL v2 for more details. */
#include "storage/default/disk_buffer_pool.h" #include "storage/default/disk_buffer_pool.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
void test_get(BPManager &bp_manager) void test_get(BPFrameManager &frame_manager)
{ {
Frame *frame1 = bp_manager.alloc(); Frame *frame1 = frame_manager.alloc();
ASSERT_NE(frame1, nullptr); ASSERT_NE(frame1, nullptr);
frame1->file_desc = 0; frame1->set_file_desc(0);
frame1->page.page_num = 1; frame1->set_page_num(1);
ASSERT_EQ(frame1, bp_manager.get(0, 1)); ASSERT_EQ(frame1, frame_manager.get(0, 1));
Frame *frame2 = bp_manager.alloc(); Frame *frame2 = frame_manager.alloc();
ASSERT_NE(frame2, nullptr); ASSERT_NE(frame2, nullptr);
frame2->file_desc = 0; frame2->set_file_desc(0);
frame2->page.page_num = 2; frame2->set_page_num(2);
ASSERT_EQ(frame1, bp_manager.get(0, 1)); ASSERT_EQ(frame1, frame_manager.get(0, 1));
Frame *frame3 = bp_manager.alloc(); Frame *frame3 = frame_manager.alloc();
ASSERT_NE(frame3, nullptr); ASSERT_NE(frame3, nullptr);
frame3->file_desc = 0; frame3->set_file_desc(0);
frame3->page.page_num = 3; frame3->set_page_num(3);
frame2 = bp_manager.get(0, 2); frame2 = frame_manager.get(0, 2);
ASSERT_NE(frame2, nullptr); ASSERT_NE(frame2, nullptr);
Frame *frame4 = bp_manager.alloc(); Frame *frame4 = frame_manager.alloc();
frame4->file_desc = 0; frame4->set_file_desc(0);
frame4->page.page_num = 4; frame4->set_page_num(4);
bp_manager.free(frame1); frame_manager.free(frame1);
frame1 = bp_manager.get(0, 1); frame1 = frame_manager.get(0, 1);
ASSERT_EQ(frame1, nullptr); ASSERT_EQ(frame1, nullptr);
ASSERT_EQ(frame3, bp_manager.get(0, 3)); ASSERT_EQ(frame3, frame_manager.get(0, 3));
ASSERT_EQ(frame4, bp_manager.get(0, 4)); ASSERT_EQ(frame4, frame_manager.get(0, 4));
bp_manager.free(frame2); frame_manager.free(frame2);
bp_manager.free(frame3); frame_manager.free(frame3);
bp_manager.free(frame4); frame_manager.free(frame4);
ASSERT_EQ(nullptr, bp_manager.get(0, 2)); ASSERT_EQ(nullptr, frame_manager.get(0, 2));
ASSERT_EQ(nullptr, bp_manager.get(0, 3)); ASSERT_EQ(nullptr, frame_manager.get(0, 3));
ASSERT_EQ(nullptr, bp_manager.get(0, 4)); ASSERT_EQ(nullptr, frame_manager.get(0, 4));
} }
void test_alloc(BPManager &bp_manager) void test_alloc(BPFrameManager &frame_manager)
{ {
int size = bp_manager.get_size(); int size = frame_manager.get_size();
std::list<Frame *> used_list; std::list<Frame *> used_list;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
Frame *item = bp_manager.alloc(); Frame *item = frame_manager.alloc();
ASSERT_NE(item, nullptr); ASSERT_NE(item, nullptr);
used_list.push_back(item); used_list.push_back(item);
} }
ASSERT_EQ(used_list.size(), bp_manager.get_used_num()); ASSERT_EQ(used_list.size(), frame_manager.get_used_num());
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
Frame *item = bp_manager.alloc(); Frame *item = frame_manager.alloc();
ASSERT_EQ(item, nullptr); ASSERT_EQ(item, nullptr);
} }
...@@ -86,26 +86,26 @@ void test_alloc(BPManager &bp_manager) ...@@ -86,26 +86,26 @@ void test_alloc(BPManager &bp_manager)
Frame *item = used_list.front(); Frame *item = used_list.front();
used_list.pop_front(); used_list.pop_front();
bp_manager.free(item); frame_manager.free(item);
} else { } else {
Frame *item = bp_manager.alloc(); Frame *item = frame_manager.alloc();
used_list.push_back(item); used_list.push_back(item);
} }
ASSERT_EQ(used_list.size(), bp_manager.get_used_num()); ASSERT_EQ(used_list.size(), frame_manager.get_used_num());
} }
} }
TEST(test_bp_manager, test_bp_manager_simple_lru) TEST(test_frame_manager, test_frame_manager_simple_lru)
{ {
BPManager bp_manager("Test"); BPFrameManager frame_manager("Test");
bp_manager.init(false, 2); frame_manager.init(false, 2);
test_get(bp_manager); test_get(frame_manager);
test_alloc(bp_manager); test_alloc(frame_manager);
bp_manager.cleanup(); frame_manager.cleanup();
} }
int main(int argc, char **argv) int main(int argc, char **argv)
...@@ -117,4 +117,4 @@ int main(int argc, char **argv) ...@@ -117,4 +117,4 @@ int main(int argc, char **argv)
// 调用RUN_ALL_TESTS()运行所有测试用例 // 调用RUN_ALL_TESTS()运行所有测试用例
// main函数返回RUN_ALL_TESTS()的运行结果 // main函数返回RUN_ALL_TESTS()的运行结果
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }
\ No newline at end of file
...@@ -321,20 +321,11 @@ TEST(test_bplus_tree, test_leaf_index_node_handle) ...@@ -321,20 +321,11 @@ TEST(test_bplus_tree, test_leaf_index_node_handle)
index_file_header.attr_type = INTS; index_file_header.attr_type = INTS;
Frame frame; Frame frame;
frame.dirty = false;
frame.pin_count = 0;
frame.acc_time = 0;
frame.file_desc = 0;
frame.page.page_num = 100;
BPPageHandle page_handle;
page_handle.open = true;
page_handle.frame = &frame;
KeyComparator key_comparator; KeyComparator key_comparator;
key_comparator.init(INTS, 4); key_comparator.init(INTS, 4);
LeafIndexNodeHandler leaf_node(index_file_header, page_handle); LeafIndexNodeHandler leaf_node(index_file_header, &frame);
leaf_node.init_empty(); leaf_node.init_empty();
ASSERT_EQ(0, leaf_node.size()); ASSERT_EQ(0, leaf_node.size());
...@@ -389,20 +380,11 @@ TEST(test_bplus_tree, test_internal_index_node_handle) ...@@ -389,20 +380,11 @@ TEST(test_bplus_tree, test_internal_index_node_handle)
index_file_header.attr_type = INTS; index_file_header.attr_type = INTS;
Frame frame; Frame frame;
frame.dirty = false;
frame.pin_count = 0;
frame.acc_time = 0;
frame.file_desc = 0;
frame.page.page_num = 100;
BPPageHandle page_handle;
page_handle.open = true;
page_handle.frame = &frame;
KeyComparator key_comparator; KeyComparator key_comparator;
key_comparator.init(INTS, 4); key_comparator.init(INTS, 4);
InternalIndexNodeHandler internal_node(index_file_header, page_handle); InternalIndexNodeHandler internal_node(index_file_header, &frame);
internal_node.init_empty(); internal_node.init_empty();
ASSERT_EQ(0, internal_node.size()); ASSERT_EQ(0, internal_node.size());
...@@ -480,8 +462,6 @@ TEST(test_bplus_tree, test_scanner) ...@@ -480,8 +462,6 @@ TEST(test_bplus_tree, test_scanner)
{ {
LoggerFactory::init_default("test.log"); LoggerFactory::init_default("test.log");
DiskBufferPool::set_pool_num(POOL_NUM);
const char *index_name = "scanner.btree"; const char *index_name = "scanner.btree";
::remove(index_name); ::remove(index_name);
handler = new BplusTreeHandler(); handler = new BplusTreeHandler();
...@@ -689,10 +669,7 @@ TEST(test_bplus_tree, test_scanner) ...@@ -689,10 +669,7 @@ TEST(test_bplus_tree, test_scanner)
TEST(test_bplus_tree, test_bplus_tree_insert) TEST(test_bplus_tree, test_bplus_tree_insert)
{ {
LoggerFactory::init_default("test.log"); LoggerFactory::init_default("test.log");
// set the disk buffer pool's number to make it is easy to test
DiskBufferPool::set_pool_num(POOL_NUM);
::remove(index_name); ::remove(index_name);
handler = new BplusTreeHandler(); handler = new BplusTreeHandler();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册