diff --git a/src/observer/init.cpp b/src/observer/init.cpp index 788e8f59cb60864676e726a432150d52f0b4c954..23e5b0860fa3465a06f089da4862a097ee978cbb 100644 --- a/src/observer/init.cpp +++ b/src/observer/init.cpp @@ -36,6 +36,8 @@ See the Mulan PSL v2 for more details. */ #include "sql/query_cache/query_cache_stage.h" #include "storage/default/default_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; @@ -156,6 +158,33 @@ int prepare_init_seda() 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) { @@ -200,6 +229,12 @@ int init(ProcessParam *process_param) get_properties()->to_string(conf_data); 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 // the latency of seda is slow, it isn't used for critical latency // environment. @@ -229,7 +264,8 @@ int init(ProcessParam *process_param) void cleanup_util() { - + uninit_global_objects(); + if (nullptr != get_properties()) { delete get_properties(); get_properties() = nullptr; @@ -245,4 +281,6 @@ void cleanup_util() } void cleanup() -{} +{ + cleanup_util(); +} diff --git a/src/observer/storage/common/meta_util.h b/src/observer/storage/common/meta_util.h index 1c4173da905f4986c53306ff47e21fdb5ecc184c..7acfefedeac5864e684603309e20b95b4fcbc8c8 100644 --- a/src/observer/storage/common/meta_util.h +++ b/src/observer/storage/common/meta_util.h @@ -16,10 +16,10 @@ See the Mulan PSL v2 for more details. */ #include -static const char *TABLE_META_SUFFIX = ".table"; -static const char *TABLE_META_FILE_PATTERN = ".*\\.table$"; -static const char *TABLE_DATA_SUFFIX = ".data"; -static const char *TABLE_INDEX_SUFFIX = ".index"; +static constexpr const char *TABLE_META_SUFFIX = ".table"; +static constexpr const char *TABLE_META_FILE_PATTERN = ".*\\.table$"; +static constexpr const char *TABLE_DATA_SUFFIX = ".data"; +static constexpr const char *TABLE_INDEX_SUFFIX = ".index"; 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); diff --git a/src/observer/storage/common/record_manager.cpp b/src/observer/storage/common/record_manager.cpp index aaeab9153d6137bcfe5a83c8c0b7a1ccb3c1e826..1acd7bdab2833aef61e57d908c339c1ef3965af5 100644 --- a/src/observer/storage/common/record_manager.cpp +++ b/src/observer/storage/common/record_manager.cpp @@ -47,66 +47,54 @@ int page_header_size(int record_capacity) 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() { 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) { - 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; } RC ret = RC::SUCCESS; - if ((ret = buffer_pool.get_this_page(file_id, page_num, &page_handle_)) != RC::SUCCESS) { - LOG_ERROR("Failed to get page handle from disk buffer pool. file_id:%d, ret=%d:%s", file_id, ret, strrc(ret)); + if ((ret = buffer_pool.get_this_page(page_num, &frame_)) != RC::SUCCESS) { + LOG_ERROR("Failed to get page handle from disk buffer pool. ret=%d:%s", ret, strrc(ret)); return ret; } - char *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; - } + char *data = frame_->data(); disk_buffer_pool_ = &buffer_pool; - file_id_ = file_id; page_header_ = (PageHeader *)(data); 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; } -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) { - 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; } - int page_size = sizeof(page_handle_.frame->page.data); + int page_size = BP_PAGE_DATA_SIZE; int record_phy_size = align8(record_size); page_header_->record_num = 0; page_header_->record_capacity = page_record_capacity(page_size, record_phy_size); page_header_->record_real_size = record_size; page_header_->record_size = record_phy_size; 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)); - disk_buffer_pool_->mark_dirty(&page_handle_); + frame_->mark_dirty(); return RC::SUCCESS; } @@ -114,10 +102,8 @@ RC RecordPageHandler::init_empty_page(DiskBufferPool &buffer_pool, int file_id, RC RecordPageHandler::cleanup() { if (disk_buffer_pool_ != nullptr) { - disk_buffer_pool_->unpin_page(&page_handle_); + disk_buffer_pool_->unpin_page(frame_); disk_buffer_pool_ = nullptr; - // skip purge page, - // skip reset page_header & bitmap } return RC::SUCCESS; @@ -125,9 +111,8 @@ RC RecordPageHandler::cleanup() RC RecordPageHandler::insert_record(const char *data, RID *rid) { - 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; } @@ -141,7 +126,7 @@ RC RecordPageHandler::insert_record(const char *data, RID *rid) char *record_data = get_record_data(index); memcpy(record_data, data, page_header_->record_real_size); - disk_buffer_pool_->mark_dirty(&page_handle_); + frame_->mark_dirty(); if (rid) { rid->page_num = get_page_num(); @@ -155,25 +140,21 @@ RC RecordPageHandler::insert_record(const char *data, RID *rid) RC RecordPageHandler::update_record(const Record *rec) { 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.", - rec->rid.slot_num, - file_id_, - page_handle_.frame->page.page_num); + LOG_ERROR("Invalid slot_num %d, exceed page's record capacity, page_num %d.", + rec->rid.slot_num, frame_->page_num()); return RC::INVALID_ARGUMENT; } Bitmap bitmap(bitmap_, page_header_->record_capacity); if (!bitmap.get_bit(rec->rid.slot_num)) { - LOG_ERROR("Invalid slot_num %d, slot is empty, file_id:page_num %d:%d.", - rec->rid.slot_num, - file_id_, - page_handle_.frame->page.page_num); + LOG_ERROR("Invalid slot_num %d, slot is empty, page_num %d.", + rec->rid.slot_num, frame_->page_num()); return RC::RECORD_RECORD_NOT_EXIST; } else { char *record_data = get_record_data(rec->rid.slot_num); memcpy(record_data, rec->data, page_header_->record_real_size); 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); return RC::SUCCESS; } @@ -182,10 +163,8 @@ RC RecordPageHandler::update_record(const Record *rec) RC RecordPageHandler::delete_record(const RID *rid) { 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.", - rid->slot_num, - file_id_, - page_handle_.frame->page.page_num); + LOG_ERROR("Invalid slot_num %d, exceed page's record capacity, page_num %d.", + rid->slot_num, frame_->page_num()); return RC::INVALID_ARGUMENT; } @@ -193,21 +172,18 @@ RC RecordPageHandler::delete_record(const RID *rid) if (bitmap.get_bit(rid->slot_num)) { bitmap.clear_bit(rid->slot_num); page_header_->record_num--; - disk_buffer_pool_->mark_dirty(&page_handle_); + frame_->mark_dirty(); if (page_header_->record_num == 0) { DiskBufferPool *disk_buffer_pool = disk_buffer_pool_; - int file_id = file_id_; PageNum page_num = get_page_num(); cleanup(); - disk_buffer_pool->dispose_page(file_id, page_num); + disk_buffer_pool->dispose_page(page_num); } return RC::SUCCESS; } else { - LOG_ERROR("Invalid slot_num %d, slot is empty, file_id:page_num %d:%d.", - rid->slot_num, - file_id_, - page_handle_.frame->page.page_num); + LOG_ERROR("Invalid slot_num %d, slot is empty, page_num %d.", + rid->slot_num, frame_->page_num()); return RC::RECORD_RECORD_NOT_EXIST; } } @@ -215,19 +191,15 @@ RC RecordPageHandler::delete_record(const RID *rid) RC RecordPageHandler::get_record(const RID *rid, Record *rec) { 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.", - rid->slot_num, - file_id_, - page_handle_.frame->page.page_num); + LOG_ERROR("Invalid slot_num:%d, exceed page's record capacity, page_num %d.", + rid->slot_num, frame_->page_num()); return RC::RECORD_INVALIDRID; } Bitmap bitmap(bitmap_, page_header_->record_capacity); if (!bitmap.get_bit(rid->slot_num)) { - LOG_ERROR("Invalid slot_num:%d, slot is empty, file_id:page_num %d:%d.", - rid->slot_num, - file_id_, - page_handle_.frame->page.page_num); + LOG_ERROR("Invalid slot_num:%d, slot is empty, page_num %d.", + rid->slot_num, frame_->page_num()); return RC::RECORD_RECORD_NOT_EXIST; } @@ -245,10 +217,8 @@ RC RecordPageHandler::get_first_record(Record *rec) RC RecordPageHandler::get_next_record(Record *rec) { 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.", - rec->rid.slot_num, - file_id_, - page_handle_.frame->page.page_num); + LOG_ERROR("Invalid slot_num:%d, exceed page's record capacity, page_num %d.", + rec->rid.slot_num, frame_->page_num()); return RC::RECORD_EOF; } @@ -256,7 +226,7 @@ RC RecordPageHandler::get_next_record(Record *rec) int index = bitmap.next_setted_bit(rec->rid.slot_num + 1); 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; } @@ -271,7 +241,7 @@ PageNum RecordPageHandler::get_page_num() const if (nullptr == page_header_) { return (PageNum)(-1); } - return page_handle_.frame->page.page_num; + return frame_->page_num(); } 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, int file_id) +RC RecordFileHandler::init(DiskBufferPool *buffer_pool) { - 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; } 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; } @@ -311,8 +276,8 @@ RC RecordFileHandler::insert_record(const char *data, int record_size, RID *rid) RC ret = RC::SUCCESS; // 找到没有填满的页面 int page_count = 0; - if ((ret = disk_buffer_pool_->get_page_count(file_id_, &page_count)) != RC::SUCCESS) { - LOG_ERROR("Failed to get page count while inserting record, file_id:%d", this->file_id_); + if ((ret = disk_buffer_pool_->get_page_count(&page_count)) != RC::SUCCESS) { + LOG_ERROR("Failed to get page count while inserting record"); return ret; } @@ -321,8 +286,8 @@ RC RecordFileHandler::insert_record(const char *data, int record_size, RID *rid) if (page_count >= 2) { // 当前buffer pool 有页面时才尝试加载第一页 // 参考diskBufferPool,有效page的pageNum从1开始 - if ((ret = record_page_handler_.init(*disk_buffer_pool_, file_id_, 1)) != RC::SUCCESS) { - LOG_ERROR("Failed to init record page handler, file_id:%d, ret=%d", file_id_, ret); + if ((ret = record_page_handler_.init(*disk_buffer_pool_, 1)) != RC::SUCCESS) { + LOG_ERROR("Failed to init record page handler, ret=%d", ret); return ret; } 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) } if (current_page_num != record_page_handler_.get_page_num()) { 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) { - LOG_ERROR( - "Failed to init record page handler. page number is %d. ret=%d:%s", current_page_num, ret, strrc(ret)); + LOG_ERROR("Failed to init record page handler. page number is %d. ret=%d:%s", + current_page_num, ret, strrc(ret)); return ret; } } @@ -355,27 +320,24 @@ RC RecordFileHandler::insert_record(const char *data, int record_size, RID *rid) // 找不到就分配一个新的页面 if (!page_found) { - BPPageHandle page_handle; - if ((ret = disk_buffer_pool_->allocate_page(file_id_, &page_handle)) != RC::SUCCESS) { - LOG_ERROR("Failed to allocate page while inserting record. file_it:%d, ret:%d", file_id_, ret); + Frame *frame = nullptr; + if ((ret = disk_buffer_pool_->allocate_page(&frame)) != RC::SUCCESS) { + LOG_ERROR("Failed to allocate page while inserting record. ret:%d", ret); return ret; } - current_page_num = page_handle.frame->page.page_num; + current_page_num = frame->page_num(); 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) { - LOG_ERROR("Failed to init empty page. file_id:%d, ret:%d", file_id_, ret); - if (RC::SUCCESS != disk_buffer_pool_->unpin_page(&page_handle)) { - LOG_ERROR("Failed to unpin page. file_id:%d", file_id_); + LOG_ERROR("Failed to init empty page. ret:%d", ret); + if (RC::SUCCESS != disk_buffer_pool_->unpin_page(frame)) { + LOG_ERROR("Failed to unpin page. "); } return ret; } - //@@@ TODO, remove unpin page here - // if (RC::SUCCESS != disk_buffer_pool_->unpin_page(&page_handle)) { - // LOG_ERROR("Failed to unpin page. file_id:%d", file_id_); - // } + disk_buffer_pool_->unpin_page(frame); } // 找到空闲位置 @@ -390,8 +352,8 @@ RC RecordFileHandler::update_record(const Record *rec) } RC ret; RecordPageHandler page_handler; - if ((ret = page_handler.init(*disk_buffer_pool_, file_id_, 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_); + 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", rec->rid.page_num); return ret; } @@ -406,8 +368,8 @@ RC RecordFileHandler::delete_record(const RID *rid) RC ret = RC::SUCCESS; RecordPageHandler page_handler; - if ((ret != page_handler.init(*disk_buffer_pool_, file_id_, rid->page_num)) != RC::SUCCESS) { - LOG_ERROR("Failed to init record page handler.page number=%d, file_id:%d", rid->page_num, file_id_); + if ((ret != page_handler.init(*disk_buffer_pool_, rid->page_num)) != RC::SUCCESS) { + LOG_ERROR("Failed to init record page handler.page number=%d", rid->page_num); return ret; } return page_handler.delete_record(rid); @@ -427,8 +389,8 @@ RC RecordFileHandler::get_record(const RID *rid, Record *rec) } RecordPageHandler page_handler; - if ((ret != page_handler.init(*disk_buffer_pool_, file_id_, rid->page_num)) != RC::SUCCESS) { - LOG_ERROR("Failed to init record page handler.page number=%d, file_id:%d", rid->page_num, file_id_); + if ((ret != page_handler.init(*disk_buffer_pool_, rid->page_num)) != RC::SUCCESS) { + LOG_ERROR("Failed to init record page handler.page number=%d", rid->page_num); return ret; } @@ -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, int file_id, ConditionFilter *condition_filter) +RC RecordFileScanner::open_scan(DiskBufferPool &buffer_pool, ConditionFilter *condition_filter) { close_scan(); disk_buffer_pool_ = &buffer_pool; - file_id_ = file_id; condition_filter_ = condition_filter; return RC::SUCCESS; @@ -483,8 +441,8 @@ RC RecordFileScanner::get_next_record(Record *rec) Record current_record = *rec; int page_count = 0; - if ((ret = disk_buffer_pool_->get_page_count(file_id_, &page_count)) != RC::SUCCESS) { - LOG_ERROR("Failed to get page count while getting next record. file id=%d", file_id_); + if ((ret = disk_buffer_pool_->get_page_count(&page_count)) != RC::SUCCESS) { + LOG_ERROR("Failed to get page count while getting next record."); return RC::RECORD_EOF; } @@ -496,7 +454,7 @@ RC RecordFileScanner::get_next_record(Record *rec) if (current_record.rid.page_num != record_page_handler_.get_page_num()) { 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) { LOG_ERROR("Failed to init record page handler. page num=%d", current_record.rid.page_num); return ret; diff --git a/src/observer/storage/common/record_manager.h b/src/observer/storage/common/record_manager.h index 1552129b43350a6a19d450222064e968117fc2cb..e56ad7efbbfefaed13dd533efb0ab63a8a3d33fc 100644 --- a/src/observer/storage/common/record_manager.h +++ b/src/observer/storage/common/record_manager.h @@ -15,6 +15,7 @@ See the Mulan PSL v2 for more details. */ #define __OBSERVER_STORAGE_COMMON_RECORD_MANAGER_H_ #include +#include #include "storage/default/disk_buffer_pool.h" typedef int32_t SlotNum; @@ -96,10 +97,10 @@ struct Record { class RecordPageHandler { public: - RecordPageHandler(); + RecordPageHandler() = default; ~RecordPageHandler(); - RC init(DiskBufferPool &buffer_pool, int file_id, PageNum page_num); - RC init_empty_page(DiskBufferPool &buffer_pool, int file_id, PageNum page_num, int record_size); + RC init(DiskBufferPool &buffer_pool, PageNum page_num); + RC init_empty_page(DiskBufferPool &buffer_pool, PageNum page_num, int record_size); RC cleanup(); RC insert_record(const char *data, RID *rid); @@ -114,7 +115,7 @@ public: return rc; } rc = updater(record); - disk_buffer_pool_->mark_dirty(&page_handle_); + frame_->mark_dirty(); return rc; } @@ -131,51 +132,40 @@ public: protected: 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: - DiskBufferPool *disk_buffer_pool_; - int file_id_; - BPPageHandle page_handle_; - PageHeader *page_header_; - char *bitmap_; + DiskBufferPool *disk_buffer_pool_ = nullptr; + Frame *frame_ = nullptr; + PageHeader *page_header_ = nullptr; + char *bitmap_ = nullptr; }; class RecordFileHandler { public: - RecordFileHandler(); - RC init(DiskBufferPool *buffer_pool, int file_id); + RecordFileHandler() = default; + RC init(DiskBufferPool *buffer_pool); void close(); /** * 更新指定文件中的记录,rec指向的记录结构中的rid字段为要更新的记录的标识符, * pData字段指向新的记录内容 - * @param rec - * @return */ RC update_record(const Record *rec); /** * 从指定文件中删除标识符为rid的记录 - * @param rid - * @return */ RC delete_record(const RID *rid); /** * 插入一个新的记录到指定文件中,pData为指向新纪录内容的指针,返回该记录的标识符rid - * @param data - * @param rid - * @return */ RC insert_record(const char *data, int record_size, RID *rid); /** * 获取指定文件中标识符为rid的记录内容到rec指向的记录结构中 - * @param rid - * @param rec - * @return */ RC get_record(const RID *rid, Record *rec); @@ -185,7 +175,7 @@ public: RC rc = RC::SUCCESS; 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; } @@ -193,15 +183,13 @@ public: } private: - DiskBufferPool *disk_buffer_pool_; - int file_id_; // 参考DiskBufferPool中的fileId - + DiskBufferPool *disk_buffer_pool_ = nullptr; RecordPageHandler record_page_handler_; // 目前只有insert record使用 }; class RecordFileScanner { public: - RecordFileScanner(); + RecordFileScanner() = default; /** * 打开一个文件扫描。 @@ -210,13 +198,8 @@ public: * 然后再调用GetNextRec函数来逐个返回文件中满足条件的记录。 * 如果条件数量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: RC get_next_record(Record *rec); private: - DiskBufferPool *disk_buffer_pool_; - int file_id_; // 参考DiskBufferPool中的fileId + DiskBufferPool *disk_buffer_pool_ = nullptr; - ConditionFilter *condition_filter_; + ConditionFilter *condition_filter_ = nullptr; RecordPageHandler record_page_handler_; }; diff --git a/src/observer/storage/common/table.cpp b/src/observer/storage/common/table.cpp index 8b7ac695a21b28ae75237c8b3a9d8c16386ffef1..d12ef46c219951da7afa9db320059be39a195015 100644 --- a/src/observer/storage/common/table.cpp +++ b/src/observer/storage/common/table.cpp @@ -29,9 +29,6 @@ See the Mulan PSL v2 for more details. */ #include "storage/index/bplus_tree_index.h" #include "storage/trx/trx.h" -Table::Table() : data_buffer_pool_(nullptr), file_id_(-1), record_handler_(nullptr) -{} - Table::~Table() { if (record_handler_ != nullptr) { @@ -39,8 +36,8 @@ Table::~Table() record_handler_ = nullptr; } - if (data_buffer_pool_ != nullptr && file_id_ >= 0) { - data_buffer_pool_->close_file(file_id_); + if (data_buffer_pool_ != nullptr) { + data_buffer_pool_->close_file(); data_buffer_pool_ = nullptr; } @@ -102,8 +99,8 @@ RC Table::create( fs.close(); std::string data_file = table_data_file(base_dir, name); - data_buffer_pool_ = theGlobalDiskBufferPool(); - rc = data_buffer_pool_->create_file(data_file.c_str()); + BufferPoolManager &bpm = BufferPoolManager::instance(); + rc = bpm.create_file(data_file.c_str()); if (rc != RC::SUCCESS) { LOG_ERROR("Failed to create disk buffer pool of data file. file name=%s", data_file.c_str()); return rc; @@ -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) { 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 = data_buffer_pool_->open_file(data_file.c_str(), &data_buffer_pool_file_id); + RC rc = BufferPoolManager::instance().open_file(data_file.c_str(), data_buffer_pool_); 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)); return rc; } 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) { 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_; record_handler_ = nullptr; return rc; } - file_id_ = data_buffer_pool_file_id; return rc; } @@ -419,9 +412,9 @@ RC Table::scan_record( RC rc = RC::SUCCESS; RecordFileScanner scanner; - rc = scanner.open_scan(*data_buffer_pool_, file_id_, filter); + rc = scanner.open_scan(*data_buffer_pool_, filter); 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; } @@ -441,7 +434,7 @@ RC Table::scan_record( if (RC::RECORD_EOF == rc) { rc = RC::SUCCESS; } 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(); return rc; @@ -834,7 +827,7 @@ IndexScanner *Table::find_index_for_scan(const ConditionFilter *filter) 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) { LOG_ERROR("Failed to flush table's data pages. table=%s, rc=%d:%s", name(), rc, strrc(rc)); return rc; diff --git a/src/observer/storage/common/table.h b/src/observer/storage/common/table.h index e416be855e4b8f573e2ffa000afdbde3ab426296..c0cfb0e32e70fdac446d675b2abe0797eaa0d1f1 100644 --- a/src/observer/storage/common/table.h +++ b/src/observer/storage/common/table.h @@ -30,7 +30,7 @@ class Trx; class Table { public: - Table(); + Table() = default; ~Table(); /** @@ -101,10 +101,9 @@ private: private: std::string base_dir_; TableMeta table_meta_; - DiskBufferPool *data_buffer_pool_; /// 数据文件关联的buffer pool - int file_id_; - RecordFileHandler *record_handler_; /// 记录操作 + DiskBufferPool *data_buffer_pool_ = nullptr; /// 数据文件关联的buffer pool + RecordFileHandler *record_handler_ = nullptr; /// 记录操作 std::vector indexes_; }; -#endif // __OBSERVER_STORAGE_COMMON_TABLE_H__ \ No newline at end of file +#endif // __OBSERVER_STORAGE_COMMON_TABLE_H__ diff --git a/src/observer/storage/default/default_handler.cpp b/src/observer/storage/default/default_handler.cpp index 87f5824bd9ac26f6aab954c23948de5ade863d86..f06e07608ec6f0b6d32ab860889d734d18ec9e88 100644 --- a/src/observer/storage/default/default_handler.cpp +++ b/src/observer/storage/default/default_handler.cpp @@ -24,10 +24,20 @@ See the Mulan PSL v2 for more details. */ #include "storage/common/table.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() { - static DefaultHandler handler; - return handler; + return *default_handler; } DefaultHandler::DefaultHandler() diff --git a/src/observer/storage/default/default_handler.h b/src/observer/storage/default/default_handler.h index cac9ff1ea92f4c191f7b21ae46eda9c8edba0a2c..e4fb243ccda23aa73a74ef05cc793560b5c25b18 100644 --- a/src/observer/storage/default/default_handler.h +++ b/src/observer/storage/default/default_handler.h @@ -159,6 +159,7 @@ public: RC sync(); public: + static void set_default(DefaultHandler *handler); static DefaultHandler &get_default(); private: @@ -167,4 +168,4 @@ private: std::map opened_dbs_; }; // class Handler -#endif // __OBSERVER_STORAGE_DEFAULT_ENGINE_H__ \ No newline at end of file +#endif // __OBSERVER_STORAGE_DEFAULT_ENGINE_H__ diff --git a/src/observer/storage/default/disk_buffer_pool.cpp b/src/observer/storage/default/disk_buffer_pool.cpp index 6bbc66357bc3b941868cfa91164ffe75ed2802e8..4f840e5f3bd525f973857c28dc441e92e2541722 100644 --- a/src/observer/storage/default/disk_buffer_pool.cpp +++ b/src/observer/storage/default/disk_buffer_pool.cpp @@ -21,7 +21,8 @@ See the Mulan PSL v2 for more details. */ using namespace common; -int DiskBufferPool::POOL_NUM = MAX_OPEN_FILE / 4; +static const PageNum BP_HEADER_PAGE = 0; +static const int MEM_POOL_ITEM_NUM = 50; unsigned long current_time() { @@ -30,20 +31,7 @@ unsigned long current_time() return tp.tv_sec * 1000 * 1000 * 1000UL + tp.tv_nsec; } -BPFileHandle::BPFileHandle() -{ - memset((void *)this, 0, sizeof(*this)); -} - -BPFileHandle::~BPFileHandle() -{ - if (file_name != nullptr) { - ::free((void *)file_name); - file_name = nullptr; - } -} - -BPManager::BPManager(const char *name) : MemPoolSimple(name) +BPFrameManager::BPFrameManager(const char *name) : MemPoolSimple(name) {} static bool match_purge(void *item, void *arg) @@ -52,7 +40,7 @@ static bool match_purge(void *item, void *arg) return frame->can_purge(); } -Frame *BPManager::begin_purge() +Frame *BPFrameManager::begin_purge() { return MemPoolSimple::find(match_purge, nullptr); } @@ -72,13 +60,13 @@ static bool match_file_page(void *item, void *arg) Frame *frame = (Frame *)item; MatchFilePage *file_page = (MatchFilePage *)arg; - if (frame->file_desc == file_page->file_desc && frame->page.page_num == file_page->page_num) + if (frame->file_desc() == file_page->file_desc && frame->page_num() == file_page->page_num) return true; return false; } -Frame *BPManager::get(int file_desc, PageNum page_num) +Frame *BPFrameManager::get(int file_desc, PageNum page_num) { MatchFilePage file_page(file_desc, page_num); return MemPoolSimple::find(match_file_page, &file_page); @@ -89,328 +77,194 @@ static bool match_file(void *item, void *arg) Frame *frame = (Frame *)item; int *file_desc = (int *)arg; - if (frame->file_desc == *file_desc) + if (frame->file_desc() == *file_desc) return true; return false; } -std::list BPManager::find_list(int file_desc) +std::list BPFrameManager::find_list(int file_desc) { return find_all(match_file, &file_desc); } -DiskBufferPool *theGlobalDiskBufferPool() +DiskBufferPool::DiskBufferPool(BufferPoolManager &bp_manager, BPFrameManager &frame_manager) + : bp_manager_(bp_manager), frame_manager_(frame_manager) { - static DiskBufferPool *instance = DiskBufferPool::mk_instance(); - - return instance; } -DiskBufferPool::DiskBufferPool() : bp_manager_("BPManager") -{ - bp_manager_.init(false, DiskBufferPool::POOL_NUM, BP_BUFFER_SIZE); -}; - DiskBufferPool::~DiskBufferPool() { - for (int i = 0; i < MAX_OPEN_FILE; i++) { - BPFileHandle *file_handle = open_list_[i]; - if (file_handle == nullptr) { - continue; - } - - close_file(i); - open_list_[i] = nullptr; - } - - bp_manager_.cleanup(); + close_file(); LOG_INFO("Exit"); } -RC DiskBufferPool::create_file(const char *file_name) +RC DiskBufferPool::open_file(const char *file_name) { - int fd = open(file_name, O_RDWR | O_CREAT | O_EXCL, S_IREAD | S_IWRITE); - if (fd < 0) { - LOG_ERROR("Failed to create %s, due to %s.", file_name, strerror(errno)); - return RC::SCHEMA_DB_EXIST; - } - - close(fd); - - /** - * Here don't care about the failure - */ - fd = open(file_name, O_RDWR); - if (fd < 0) { - LOG_ERROR("Failed to open for readwrite %s, due to %s.", file_name, strerror(errno)); - return RC::IOERR_ACCESS; - } - - Page page; - memset(&page, 0, sizeof(Page)); - - BPFileSubHeader *fileSubHeader; - fileSubHeader = (BPFileSubHeader *)page.data; - fileSubHeader->allocated_pages = 1; - fileSubHeader->page_count = 1; - - char *bitmap = page.data + (int)BP_FILE_SUB_HDR_SIZE; - bitmap[0] |= 0x01; - if (lseek(fd, 0, SEEK_SET) == -1) { - LOG_ERROR("Failed to seek file %s to position 0, due to %s .", file_name, strerror(errno)); - close(fd); - return RC::IOERR_SEEK; - } - - if (write(fd, (char *)&page, sizeof(Page)) != sizeof(Page)) { - LOG_ERROR("Failed to write header to file %s, due to %s.", file_name, strerror(errno)); - close(fd); - return RC::IOERR_WRITE; - } - - close(fd); - LOG_INFO("Successfully create %s.", file_name); - return RC::SUCCESS; -} - -RC DiskBufferPool::open_file(const char *file_name, int *file_id) -{ - int fd, i, size = 0, empty_id = -1; - // This part isn't gentle, the better method is using LRU queue. - for (i = 0; i < MAX_OPEN_FILE; i++) { - if (open_list_[i]) { - size++; - if (!strcmp(open_list_[i]->file_name, file_name)) { - *file_id = i; - LOG_INFO("%s has already been opened.", file_name); - return RC::SUCCESS; - } - } else if (empty_id == -1) { - empty_id = i; - } - } - - i = size; - if (i >= MAX_OPEN_FILE && open_list_[i - 1]) { - LOG_ERROR("Failed to open file %s, because too much files have been opened.", file_name); - return RC::BUFFERPOOL_OPEN_TOO_MANY_FILES; - } - + int fd; if ((fd = open(file_name, O_RDWR)) < 0) { LOG_ERROR("Failed to open file %s, because %s.", file_name, strerror(errno)); return RC::IOERR_ACCESS; } LOG_INFO("Successfully open file %s.", file_name); - BPFileHandle *file_handle = new (std::nothrow) BPFileHandle(); - if (file_handle == nullptr) { - LOG_ERROR("Failed to alloc memory of BPFileHandle for %s.", file_name); - close(fd); - return RC::NOMEM; - } + file_name_ = file_name; + file_desc_ = fd; - RC tmp = RC::SUCCESS; - file_handle->bopen = true; - file_handle->file_name = strdup(file_name); - file_handle->file_desc = fd; - if ((tmp = allocate_page(&file_handle->hdr_frame)) != RC::SUCCESS) { - LOG_ERROR("Failed to allocate block for %s's BPFileHandle.", file_name); - delete file_handle; + RC rc = RC::SUCCESS; + rc = allocate_frame(&hdr_frame_); + if (rc != RC::SUCCESS) { + LOG_ERROR("failed to allocate frame for header. file name %s", file_name_.c_str()); close(fd); - return tmp; + file_desc_ = -1; + return rc; } - file_handle->hdr_frame->dirty = false; - file_handle->hdr_frame->file_desc = fd; - file_handle->hdr_frame->pin_count = 1; - file_handle->hdr_frame->acc_time = current_time(); - if ((tmp = load_page(0, file_handle, file_handle->hdr_frame)) != RC::SUCCESS) { + + hdr_frame_->dirty_ = false; + hdr_frame_->file_desc_ = fd; + hdr_frame_->pin_count_ = 1; + hdr_frame_->acc_time_ = current_time(); + if ((rc = load_page(BP_HEADER_PAGE, hdr_frame_)) != RC::SUCCESS) { LOG_ERROR("Failed to load first page of %s, due to %s.", file_name, strerror(errno)); - file_handle->hdr_frame->pin_count = 0; - purge_page(file_handle->hdr_frame); + hdr_frame_->pin_count_ = 0; + purge_frame(hdr_frame_); close(fd); - delete file_handle; - return tmp; + file_desc_ = -1; + return rc; } - file_handle->hdr_page = &(file_handle->hdr_frame->page); - file_handle->bitmap = file_handle->hdr_page->data + BP_FILE_SUB_HDR_SIZE; - file_handle->file_sub_header = (BPFileSubHeader *)file_handle->hdr_page->data; - open_list_[empty_id] = file_handle; - *file_id = empty_id; + file_header_ = (BPFileHeader *)hdr_frame_->data(); - LOG_INFO("Successfully open %s. file_id=%d, hdr_frame=%p", file_name, *file_id, file_handle->hdr_frame); + LOG_INFO("Successfully open %s. file_desc=%d, hdr_frame=%p", file_name, file_desc_, hdr_frame_); return RC::SUCCESS; } -RC DiskBufferPool::close_file(int file_id) +RC DiskBufferPool::close_file() { - RC tmp; - if ((tmp = check_file_id(file_id)) != RC::SUCCESS) { - LOG_ERROR("Failed to close file, due to invalid fileId %d", file_id); - return tmp; + RC rc = RC::SUCCESS; + if (file_desc_ < 0) { + return rc; } - BPFileHandle *file_handle = open_list_[file_id]; - file_handle->hdr_frame->pin_count--; - if ((tmp = purge_all_pages(file_handle)) != RC::SUCCESS) { - file_handle->hdr_frame->pin_count++; - LOG_ERROR("Failed to close file %d:%s, due to failed to purge all pages.", file_id, file_handle->file_name); - return tmp; + hdr_frame_->pin_count_--; + if ((rc = purge_all_pages()) != RC::SUCCESS) { + hdr_frame_->pin_count_++; + LOG_ERROR("Failed to close %s, due to failed to purge all pages.", file_name_.c_str()); + return rc; } - disposed_pages.erase(file_handle->file_desc); + disposed_pages.clear(); - if (close(file_handle->file_desc) < 0) { - LOG_ERROR("Failed to close fileId:%d, fileName:%s, error:%s", file_id, file_handle->file_name, strerror(errno)); + if (close(file_desc_) < 0) { + LOG_ERROR("Failed to close fileId:%d, fileName:%s, error:%s", file_desc_, file_name_.c_str(), strerror(errno)); return RC::IOERR_CLOSE; } - open_list_[file_id] = nullptr; - LOG_INFO("Successfully close file %d:%s.", file_id, file_handle->file_name); - delete file_handle; + LOG_INFO("Successfully close file %d:%s.", file_desc_, file_name_.c_str()); + file_desc_ = -1; + + bp_manager_.close_file(file_name_.c_str()); return RC::SUCCESS; } -RC DiskBufferPool::get_this_page(int file_id, PageNum page_num, BPPageHandle *page_handle) +RC DiskBufferPool::get_this_page(PageNum page_num, Frame **frame) { - RC tmp; - if ((tmp = check_file_id(file_id)) != RC::SUCCESS) { - LOG_ERROR("Failed to load page %d, due to invalid fileId %d", page_num, file_id); - return tmp; - } - - BPFileHandle *file_handle = open_list_[file_id]; - if ((tmp = check_page_num(page_num, file_handle)) != RC::SUCCESS) { - LOG_ERROR("Failed to load page %s:%d, due to invalid pageNum.", file_handle->file_name, page_num); - return tmp; - } + RC rc = RC::SUCCESS; - Frame *used_match_frame = bp_manager_.get(file_handle->file_desc, page_num); + Frame *used_match_frame = frame_manager_.get(file_desc_, page_num); if (used_match_frame != nullptr) { - page_handle->frame = used_match_frame; - page_handle->frame->pin_count++; - page_handle->frame->acc_time = current_time(); - page_handle->open = true; + used_match_frame->pin_count_++; + used_match_frame->acc_time_ = current_time(); - bp_manager_.mark_modified(used_match_frame); + frame_manager_.mark_modified(used_match_frame); + *frame = used_match_frame; return RC::SUCCESS; } // Allocate one page and load the data into this page - if ((tmp = allocate_page(&(page_handle->frame))) != RC::SUCCESS) { - LOG_ERROR("Failed to load page %s:%d, due to failed to alloc page.", file_handle->file_name, page_num); - return tmp; - } - page_handle->frame->dirty = false; - page_handle->frame->file_desc = file_handle->file_desc; - page_handle->frame->pin_count = 1; - page_handle->frame->acc_time = current_time(); - if ((tmp = load_page(page_num, file_handle, page_handle->frame)) != RC::SUCCESS) { - LOG_ERROR("Failed to load page %s:%d", file_handle->file_name, page_num); - page_handle->frame->pin_count = 0; - purge_page(page_handle->frame); - return tmp; - } - - page_handle->open = true; + Frame *allocated_frame = nullptr; + if ((rc = allocate_frame(&allocated_frame)) != RC::SUCCESS) { + LOG_ERROR("Failed to alloc frame %s:%d, due to failed to alloc page.", file_name_.c_str(), page_num); + return rc; + } + + allocated_frame->dirty_ = false; + allocated_frame->file_desc_ = file_desc_; + allocated_frame->pin_count_ = 1; + allocated_frame->acc_time_ = current_time(); + if ((rc = load_page(page_num, allocated_frame)) != RC::SUCCESS) { + LOG_ERROR("Failed to load page %s:%d", file_name_.c_str(), page_num); + allocated_frame->pin_count_ = 0; + purge_frame(allocated_frame); + return rc; + } + + *frame = allocated_frame; return RC::SUCCESS; } -RC DiskBufferPool::allocate_page(int file_id, BPPageHandle *page_handle) +RC DiskBufferPool::allocate_page(Frame **frame) { - RC tmp; - if ((tmp = check_file_id(file_id)) != RC::SUCCESS) { - LOG_ERROR("Failed to alloc page, due to invalid fileId %d", file_id); - return tmp; - } - - BPFileHandle *file_handle = open_list_[file_id]; + RC rc = RC::SUCCESS; int byte = 0, bit = 0; - if ((file_handle->file_sub_header->allocated_pages) < (file_handle->file_sub_header->page_count)) { + if ((file_header_->allocated_pages) < (file_header_->page_count)) { // There is one free page - for (int i = 0; i < file_handle->file_sub_header->page_count; i++) { + for (int i = 0; i < file_header_->page_count; i++) { byte = i / 8; bit = i % 8; - if (((file_handle->bitmap[byte]) & (1 << bit)) == 0) { - (file_handle->file_sub_header->allocated_pages)++; - file_handle->bitmap[byte] |= (1 << bit); + if (((file_header_->bitmap[byte]) & (1 << bit)) == 0) { + (file_header_->allocated_pages)++; + file_header_->bitmap[byte] |= (1 << bit); // TODO, do we need clean the loaded page's data? - return get_this_page(file_id, i, page_handle); + hdr_frame_->mark_dirty(); + return get_this_page(i, frame); } } } - if ((tmp = allocate_page(&(page_handle->frame))) != RC::SUCCESS) { - LOG_ERROR("Failed to allocate page %s, due to no free page.", file_handle->file_name); - return tmp; + Frame *allocated_frame = nullptr; + if ((rc = allocate_frame(&allocated_frame)) != RC::SUCCESS) { + LOG_ERROR("Failed to allocate frame %s, due to no free page.", file_name_.c_str()); + return rc; } - PageNum page_num = file_handle->file_sub_header->page_count; - file_handle->file_sub_header->allocated_pages++; - file_handle->file_sub_header->page_count++; + PageNum page_num = file_header_->page_count; + file_header_->allocated_pages++; + file_header_->page_count++; byte = page_num / 8; bit = page_num % 8; - file_handle->bitmap[byte] |= (1 << bit); - file_handle->hdr_frame->dirty = true; + file_header_->bitmap[byte] |= (1 << bit); + hdr_frame_->mark_dirty(); - page_handle->frame->dirty = false; - page_handle->frame->file_desc = file_handle->file_desc; - page_handle->frame->pin_count = 1; - page_handle->frame->acc_time = current_time(); - memset(&(page_handle->frame->page), 0, sizeof(Page)); - page_handle->frame->page.page_num = file_handle->file_sub_header->page_count - 1; + allocated_frame->dirty_ = false; + allocated_frame->file_desc_ = file_desc_; + allocated_frame->pin_count_ = 1; + allocated_frame->acc_time_ = current_time(); + allocated_frame->clear_page(); + allocated_frame->page_.page_num = file_header_->page_count - 1; // Use flush operation to extension file - if ((tmp = flush_page(page_handle->frame)) != RC::SUCCESS) { - LOG_WARN("Failed to alloc page %s , due to failed to extend one page.", file_handle->file_name); + if ((rc = flush_page(*allocated_frame)) != RC::SUCCESS) { + LOG_WARN("Failed to alloc page %s , due to failed to extend one page.", file_name_.c_str()); // skip return false, delay flush the extended page // return tmp; } - page_handle->open = true; + *frame = allocated_frame; return RC::SUCCESS; } -RC DiskBufferPool::get_page_num(BPPageHandle *page_handle, PageNum *page_num) +RC DiskBufferPool::unpin_page(Frame *frame) { - if (!page_handle->open) - return RC::BUFFERPOOL_CLOSED; - *page_num = page_handle->frame->page.page_num; - return RC::SUCCESS; -} - -RC DiskBufferPool::get_data(BPPageHandle *page_handle, char **data) -{ - if (!page_handle->open) - return RC::BUFFERPOOL_CLOSED; - *data = page_handle->frame->page.data; - return RC::SUCCESS; -} - -RC DiskBufferPool::mark_dirty(BPPageHandle *page_handle) -{ - page_handle->frame->dirty = true; - return RC::SUCCESS; -} - -RC DiskBufferPool::unpin_page(BPPageHandle *page_handle) -{ - page_handle->open = false; - if (--page_handle->frame->pin_count == 0) { - int file_desc = page_handle->frame->file_desc; - auto it = disposed_pages.find(file_desc); - if (it != disposed_pages.end()) { - BPDisposedPages &disposed_page = it->second; - PageNum page_num = page_handle->frame->page.page_num; - auto pages_it = disposed_page.pages.find(page_num); - if (pages_it != disposed_page.pages.end()) { - LOG_INFO("Dispose file_id:%d, page:%d", disposed_page.file_id, page_num); - dispose_page(disposed_page.file_id, page_num); - disposed_page.pages.erase(pages_it); - } + if (--frame->pin_count_ == 0) { + PageNum page_num = frame->page_num(); + auto pages_it = disposed_pages.find(page_num); + if (pages_it != disposed_pages.end()) { + LOG_INFO("Dispose file_desc:%d, page:%d", file_desc_, page_num); + dispose_page(page_num); + disposed_pages.erase(pages_it); } } @@ -420,256 +274,314 @@ RC DiskBufferPool::unpin_page(BPPageHandle *page_handle) /** * dispose_page will delete the data of the page of pageNum, free the page both from buffer pool and data file. * purge_page will purge the page of pageNum, free the page from buffer pool - * @param fileID - * @param pageNum * @return */ -RC DiskBufferPool::dispose_page(int file_id, PageNum page_num) +RC DiskBufferPool::dispose_page(PageNum page_num) { - RC rc; - if ((rc = check_file_id(file_id)) != RC::SUCCESS) { - LOG_ERROR("Failed to alloc page, due to invalid fileId %d", file_id); - return rc; - } - - BPFileHandle *file_handle = open_list_[file_id]; - if ((rc = check_page_num(page_num, file_handle)) != RC::SUCCESS) { - LOG_ERROR("Failed to dispose page %s:%d, due to invalid pageNum", file_handle->file_name, page_num); - return rc; - } - - rc = purge_page(file_handle, page_num); + RC rc = purge_page(page_num); if (rc != RC::SUCCESS) { - LOG_INFO("Dispose page %s:%d later, due to this page is being used", file_handle->file_name, page_num); - - auto it = disposed_pages.find(file_handle->file_desc); - if (it == disposed_pages.end()) { - BPDisposedPages disposed_page; - disposed_page.file_id = file_id; - disposed_page.pages.insert(page_num); - disposed_pages.insert(std::pair(file_handle->file_desc, disposed_page)); - } else { - BPDisposedPages &disposed_page = it->second; - disposed_page.pages.insert(page_num); - } + LOG_INFO("Dispose page %s:%d later, due to this page is being used", file_name_.c_str(), page_num); + disposed_pages.insert(page_num); return rc; } - file_handle->hdr_frame->dirty = true; - file_handle->file_sub_header->allocated_pages--; - // file_handle->pFileSubHeader->pageCount--; + hdr_frame_->dirty_ = true; + file_header_->allocated_pages--; char tmp = 1 << (page_num % 8); - file_handle->bitmap[page_num / 8] &= ~tmp; + file_header_->bitmap[page_num / 8] &= ~tmp; return RC::SUCCESS; } -RC DiskBufferPool::purge_page(int file_id, PageNum page_num) +RC DiskBufferPool::purge_frame(Frame *buf) { - RC rc; - if ((rc = check_file_id(file_id)) != RC::SUCCESS) { - LOG_ERROR("Failed to alloc page, due to invalid fileId %d", file_id); - return rc; - } - BPFileHandle *file_handle = open_list_[file_id]; - return purge_page(file_handle, page_num); -} - -RC DiskBufferPool::purge_page(Frame *buf) -{ - if (buf->pin_count > 0) { + if (buf->pin_count_ > 0) { LOG_INFO("Begin to free page %d of %d(file id), but it's pinned, pin_count:%d.", - buf->page.page_num, - buf->file_desc, - buf->pin_count); + buf->page_num(), buf->file_desc_, buf->pin_count_); return RC::LOCKED_UNLOCK; } - if (buf->dirty) { - RC rc = flush_page(buf); + if (buf->dirty_) { + RC rc = flush_page(*buf); if (rc != RC::SUCCESS) { - LOG_WARN("Failed to flush page %d of %d(file desc) during purge page.", buf->page.page_num, buf->file_desc); + LOG_WARN("Failed to flush page %d of %d(file desc) during purge page.", buf->page_num(), buf->file_desc_); return rc; } } - LOG_DEBUG("Successfully purge frame =%p, page %d of %d(file desc)", buf, buf->page.page_num, buf->file_desc); - bp_manager_.free(buf); + LOG_DEBUG("Successfully purge frame =%p, page %d of %d(file desc)", buf, buf->page_num(), buf->file_desc_); + frame_manager_.free(buf); return RC::SUCCESS; } /** * dispose_page will delete the data of the page of pageNum * force_page will flush the page of pageNum - * @param fileHandle * @param pageNum * @return */ -RC DiskBufferPool::purge_page(BPFileHandle *file_handle, PageNum page_num) +RC DiskBufferPool::purge_page(PageNum page_num) { - Frame *used_frame = bp_manager_.get(file_handle->file_desc, page_num); + Frame *used_frame = frame_manager_.get(file_desc_, page_num); if (used_frame != nullptr) { - return purge_page(used_frame); + return purge_frame(used_frame); } return RC::SUCCESS; } -RC DiskBufferPool::purge_all_pages(int file_id) -{ - RC rc = check_file_id(file_id); - if (rc != RC::SUCCESS) { - LOG_ERROR("Failed to flush pages due to invalid file_id %d", file_id); - return rc; - } - - BPFileHandle *file_handle = open_list_[file_id]; - return purge_all_pages(file_handle); -} - -RC DiskBufferPool::purge_all_pages(BPFileHandle *file_handle) +RC DiskBufferPool::purge_all_pages() { - std::list used = bp_manager_.find_list(file_handle->file_desc); + std::list used = frame_manager_.find_list(file_desc_); for (std::list::iterator it = used.begin(); it != used.end(); ++it) { Frame *frame = *it; - if (frame->pin_count > 0) { + if (frame->pin_count_ > 0) { LOG_WARN("The page has been pinned, file_desc:%d, pagenum:%d, pin_count=%d", - frame->file_desc, frame->page.page_num, frame->pin_count); + frame->file_desc_, frame->page_.page_num, frame->pin_count_); continue; } - if (frame->dirty) { - RC rc = flush_page(frame); + if (frame->dirty_) { + RC rc = flush_page(*frame); if (rc != RC::SUCCESS) { - LOG_ERROR("Failed to flush all pages' of %s.", file_handle->file_name); + LOG_ERROR("Failed to flush all pages' of %s.", file_name_.c_str()); return rc; } } - bp_manager_.free(frame); + frame_manager_.free(frame); } return RC::SUCCESS; } -RC DiskBufferPool::check_all_pages_unpinned(int file_id) +RC DiskBufferPool::check_all_pages_unpinned() { - RC rc = check_file_id(file_id); - if (rc != RC::SUCCESS) { - LOG_ERROR("Failed to flush pages due to invalid file_id %d", file_id); - return rc; - } - - BPFileHandle *file_handle = open_list_[file_id]; - std::list frames = bp_manager_.find_list(file_handle->file_desc); + std::list frames = frame_manager_.find_list(file_desc_); for (auto & frame : frames) { - if (frame->page.page_num == 0 && frame->pin_count > 1) { - LOG_WARN("This page has been pinned. file id=%d, page num:%d, pin count=%d", - file_id, frame->page.page_num, frame->pin_count); - } else if (frame->page.page_num != 0 && frame->pin_count > 0) { - LOG_WARN("This page has been pinned. file id=%d, page num:%d, pin count=%d", - file_id, frame->page.page_num, frame->pin_count); + if (frame->page_num() == BP_HEADER_PAGE && frame->pin_count_ > 1) { + LOG_WARN("This page has been pinned. file desc=%d, page num:%d, pin count=%d", + file_desc_, frame->page_num(), frame->pin_count_); + } else if (frame->page_num() != BP_HEADER_PAGE && frame->pin_count_ > 0) { + LOG_WARN("This page has been pinned. file desc=%d, page num:%d, pin count=%d", + file_desc_, frame->page_num(), frame->pin_count_); } } - LOG_INFO("all pages have been checked of file id %d", file_id); + LOG_INFO("all pages have been checked of file desc %d", file_desc_); return RC::SUCCESS; } -RC DiskBufferPool::flush_page(Frame *frame) +RC DiskBufferPool::flush_page(Frame &frame) { // The better way is use mmap the block into memory, // so it is easier to flush data to file. - s64_t offset = ((s64_t)frame->page.page_num) * sizeof(Page); - if (lseek(frame->file_desc, offset, SEEK_SET) == offset - 1) { - LOG_ERROR("Failed to flush page %lld of %d due to failed to seek %s.", offset, frame->file_desc, strerror(errno)); + Page &page = frame.page_; + s64_t offset = ((s64_t)page.page_num) * sizeof(Page); + if (lseek(file_desc_, offset, SEEK_SET) == offset - 1) { + LOG_ERROR("Failed to flush page %lld of %d due to failed to seek %s.", offset, file_desc_, strerror(errno)); return RC::IOERR_SEEK; } - if (write(frame->file_desc, &(frame->page), sizeof(Page)) != sizeof(Page)) { - LOG_ERROR("Failed to flush page %lld of %d due to %s.", offset, frame->file_desc, strerror(errno)); + if (write(file_desc_, &page, sizeof(Page)) != sizeof(Page)) { + LOG_ERROR("Failed to flush page %lld of %d due to %s.", offset, file_desc_, strerror(errno)); return RC::IOERR_WRITE; } - frame->dirty = false; - LOG_DEBUG("Flush block. file desc=%d, page num=%d", frame->file_desc, frame->page.page_num); + frame.dirty_ = false; + LOG_DEBUG("Flush block. file desc=%d, page num=%d", file_desc_, page.page_num); return RC::SUCCESS; } -RC DiskBufferPool::allocate_page(Frame **buffer) +RC DiskBufferPool::allocate_frame(Frame **buffer) { - Frame *frame = bp_manager_.alloc(); + Frame *frame = frame_manager_.alloc(); if (frame != nullptr) { *buffer = frame; return RC::SUCCESS; } - frame = bp_manager_.begin_purge(); + frame = frame_manager_.begin_purge(); if (frame == nullptr) { LOG_ERROR("All pages have been used and pinned."); return RC::NOMEM; } - if (frame->dirty) { - RC rc = flush_page(frame); + if (frame->dirty_) { + RC rc = bp_manager_.flush_page(*frame); if (rc != RC::SUCCESS) { LOG_ERROR("Failed to aclloc block due to failed to flush old block."); return rc; } } - bp_manager_.mark_modified(frame); + frame_manager_.mark_modified(frame); *buffer = frame; return RC::SUCCESS; } -RC DiskBufferPool::check_file_id(int file_id) +RC DiskBufferPool::check_page_num(PageNum page_num) { - if (file_id < 0 || file_id >= MAX_OPEN_FILE) { - LOG_ERROR("Invalid fileId:%d.", file_id); - return RC::BUFFERPOOL_ILLEGAL_FILE_ID; + if (page_num >= file_header_->page_count) { + LOG_ERROR("Invalid pageNum:%d, file's name:%s", page_num, file_name_.c_str()); + return RC::BUFFERPOOL_INVALID_PAGE_NUM; } - if (!open_list_[file_id]) { - LOG_ERROR("Invalid fileId:%d, it is empty.", file_id); - return RC::BUFFERPOOL_ILLEGAL_FILE_ID; + if ((file_header_->bitmap[page_num / 8] & (1 << (page_num % 8))) == 0) { + LOG_ERROR("Invalid pageNum:%d, file's name:%s", page_num, file_name_.c_str()); + return RC::BUFFERPOOL_INVALID_PAGE_NUM; } return RC::SUCCESS; } -RC DiskBufferPool::get_page_count(int file_id, int *page_count) +RC DiskBufferPool::load_page(PageNum page_num, Frame *frame) { - RC rc = RC::SUCCESS; - if ((rc = check_file_id(file_id)) != RC::SUCCESS) { - return rc; + s64_t offset = ((s64_t)page_num) * sizeof(Page); + if (lseek(file_desc_, offset, SEEK_SET) == -1) { + LOG_ERROR("Failed to load page %s:%d, due to failed to lseek:%s.", + file_name_.c_str(), page_num, strerror(errno)); + + return RC::IOERR_SEEK; + } + if (read(file_desc_, &(frame->page_), sizeof(Page)) != sizeof(Page)) { + LOG_ERROR("Failed to load page %s:%d, due to failed to read data:%s.", + file_name_.c_str(), page_num, strerror(errno)); + return RC::IOERR_READ; } - *page_count = open_list_[file_id]->file_sub_header->page_count; return RC::SUCCESS; } -RC DiskBufferPool::check_page_num(PageNum page_num, BPFileHandle *file_handle) +RC DiskBufferPool::get_page_count(int *page_count) { - if (page_num >= file_handle->file_sub_header->page_count) { - LOG_ERROR("Invalid pageNum:%d, file's name:%s", page_num, file_handle->file_name); - return RC::BUFFERPOOL_INVALID_PAGE_NUM; + *page_count = file_header_->allocated_pages; + return RC::SUCCESS; +} +int DiskBufferPool::file_desc() const +{ + return file_desc_; +} +//////////////////////////////////////////////////////////////////////////////// +BufferPoolManager::BufferPoolManager() +{ + frame_manager_.init(true/*dynamic*/, MEM_POOL_ITEM_NUM); +} + +BufferPoolManager::~BufferPoolManager() +{ + std::unordered_map tmp_bps; + tmp_bps.swap(buffer_pools_); + + for (auto &iter : tmp_bps) { + delete iter.second; } - if ((file_handle->bitmap[page_num / 8] & (1 << (page_num % 8))) == 0) { - LOG_ERROR("Invalid pageNum:%d, file's name:%s", page_num, file_handle->file_name); - return RC::BUFFERPOOL_INVALID_PAGE_NUM; +} + +RC BufferPoolManager::create_file(const char *file_name) +{ + int fd = open(file_name, O_RDWR | O_CREAT | O_EXCL, S_IREAD | S_IWRITE); + if (fd < 0) { + LOG_ERROR("Failed to create %s, due to %s.", file_name, strerror(errno)); + return RC::SCHEMA_DB_EXIST; + } + + close(fd); + + /** + * Here don't care about the failure + */ + fd = open(file_name, O_RDWR); + if (fd < 0) { + LOG_ERROR("Failed to open for readwrite %s, due to %s.", file_name, strerror(errno)); + return RC::IOERR_ACCESS; + } + + Page page; + memset(&page, 0, sizeof(Page)); + + BPFileHeader *file_header = (BPFileHeader *)page.data; + file_header->allocated_pages = 1; + file_header->page_count = 1; + + char *bitmap = file_header->bitmap; + bitmap[0] |= 0x01; + if (lseek(fd, 0, SEEK_SET) == -1) { + LOG_ERROR("Failed to seek file %s to position 0, due to %s .", file_name, strerror(errno)); + close(fd); + return RC::IOERR_SEEK; } + + if (write(fd, (char *)&page, sizeof(Page)) != sizeof(Page)) { + LOG_ERROR("Failed to write header to file %s, due to %s.", file_name, strerror(errno)); + close(fd); + return RC::IOERR_WRITE; + } + + close(fd); + LOG_INFO("Successfully create %s.", file_name); return RC::SUCCESS; } -RC DiskBufferPool::load_page(PageNum page_num, BPFileHandle *file_handle, Frame *frame) +RC BufferPoolManager::open_file(const char *_file_name, DiskBufferPool *& _bp) { - s64_t offset = ((s64_t)page_num) * sizeof(Page); - if (lseek(file_handle->file_desc, offset, SEEK_SET) == -1) { - LOG_ERROR( - "Failed to load page %s:%d, due to failed to lseek:%s.", file_handle->file_name, page_num, strerror(errno)); + std::string file_name(_file_name); + + if (buffer_pools_.find(file_name) != buffer_pools_.end()) { + LOG_WARN("file already opened. file name=%s", _file_name); + return RC::BUFFERPOOL_OPEN; + } - return RC::IOERR_SEEK; + DiskBufferPool *bp = new DiskBufferPool(*this, frame_manager_); + RC rc = bp->open_file(_file_name); + if (rc != RC::SUCCESS) { + LOG_WARN("failed to open file name"); + delete bp; + return rc; } - if (read(file_handle->file_desc, &(frame->page), sizeof(Page)) != sizeof(Page)) { - LOG_ERROR( - "Failed to load page %s:%d, due to failed to read data:%s.", file_handle->file_name, page_num, strerror(errno)); - return RC::IOERR_READ; + + buffer_pools_.insert(std::pair(file_name, bp)); + fd_buffer_pools_.insert(std::pair(bp->file_desc(), bp)); + _bp = bp; + return RC::SUCCESS; +} + +RC BufferPoolManager::close_file(const char *_file_name) +{ + std::string file_name(_file_name); + auto iter = buffer_pools_.find(file_name); + if (iter == buffer_pools_.end()) { + LOG_WARN("file has not opened: %s", _file_name); + return RC::INTERNAL; } + + int fd = iter->second->file_desc(); + fd_buffer_pools_.erase(fd); + + DiskBufferPool *bp = iter->second; + buffer_pools_.erase(iter); + delete bp; return RC::SUCCESS; } + +RC BufferPoolManager::flush_page(Frame &frame) +{ + int fd = frame.file_desc(); + auto iter = fd_buffer_pools_.find(fd); + if (iter == fd_buffer_pools_.end()) { + LOG_WARN("unknown buffer pool of fd %d", fd); + return RC::INTERNAL; + } + + DiskBufferPool *bp = iter->second; + return bp->flush_page(frame); +} + +static BufferPoolManager *default_bpm = nullptr; +void BufferPoolManager::set_instance(BufferPoolManager *bpm) +{ + if (default_bpm != nullptr && bpm != nullptr) { + LOG_ERROR("default buffer pool manager has been setted"); + abort(); + } + default_bpm = bpm; +} +BufferPoolManager &BufferPoolManager::instance() +{ + return *default_bpm; +} diff --git a/src/observer/storage/default/disk_buffer_pool.h b/src/observer/storage/default/disk_buffer_pool.h index 90881919a9379b9ee85cae8c85218a112eca4293..131df891bb77f486152bc99a004bbd168bdc9139 100644 --- a/src/observer/storage/default/disk_buffer_pool.h +++ b/src/observer/storage/default/disk_buffer_pool.h @@ -14,19 +14,23 @@ See the Mulan PSL v2 for more details. */ #ifndef __OBSERVER_STORAGE_COMMON_PAGE_MANAGER_H_ #define __OBSERVER_STORAGE_COMMON_PAGE_MANAGER_H_ +#include +#include #include #include -#include #include - #include -#include #include +#include +#include #include "rc.h" #include "common/mm/mem_pool.h" -typedef int PageNum; +typedef int32_t PageNum; + +class BufferPoolManager; +class DiskBufferPool; // #define BP_INVALID_PAGE_NUM (-1) @@ -34,73 +38,82 @@ typedef int PageNum; #define BP_PAGE_DATA_SIZE (BP_PAGE_SIZE - sizeof(PageNum)) #define BP_FILE_SUB_HDR_SIZE (sizeof(BPFileSubHeader)) #define BP_BUFFER_SIZE 256 -#define MAX_OPEN_FILE 1024 -typedef struct { +struct Page { PageNum page_num; char data[BP_PAGE_DATA_SIZE]; -} Page; +}; // sizeof(Page) should be equal to BP_PAGE_SIZE -typedef struct { - PageNum page_count; - int allocated_pages; -} BPFileSubHeader; - -typedef struct { - int file_id; - std::set pages; -} BPDisposedPages; - -typedef struct Frame_ { - bool dirty; - unsigned int pin_count; - unsigned long acc_time; - int file_desc; - Page page; +/** + * BufferPool的文件第一个页面,存放一些元数据信息,包括了后面每页的分配信息。 + * TODO 1. 当前的做法,只能分配比较少的页面,你可以扩展一下,支持更多的页面或无限多的页面吗? + * 可以参考Linux ext(n)和Windows NTFS等文件系统 + * 2. 当前使用bitmap存放页面分配情况,但是这种方法在页面非常多的时候,查找空闲页面的 + * 效率非常低,你有办法优化吗? + */ +struct BPFileHeader { + int32_t page_count; //! 当前文件一共有多少个页面 + int32_t allocated_pages; //! 已经分配了多少个页面 + char bitmap[0]; //! 页面分配位图, 第0个页面(就是当前页面),总是1 +}; - bool can_purge() +class Frame +{ +public: + void clear_page() { - return pin_count <= 0; + memset(&page_, 0, sizeof(page_)); } -} Frame; -typedef struct BPPageHandle { - BPPageHandle() : open(false), frame(nullptr) - {} + PageNum page_num() const + { + return page_.page_num; + } - PageNum page_num() const { - return frame->page.page_num; + void set_page_num(PageNum page_num) + { + page_.page_num = page_num; } + + /** + * 标记指定页面为“脏”页。如果修改了页面的内容,则应调用此函数, + * 以便该页面被淘汰出缓冲区时系统将新的页面数据写入磁盘文件 + */ void mark_dirty() { - this->frame->dirty = true; + dirty_ = true; } char *data() { - return this->frame->page.data; + return page_.data; } - bool open; - Frame *frame; -} BPPageHandle; -class BPFileHandle { -public: - BPFileHandle(); - ~BPFileHandle(); + int file_desc() const + { + return file_desc_; + } -public: - bool bopen; - const char *file_name; - int file_desc; - Frame *hdr_frame; - Page *hdr_page; - char *bitmap; - BPFileSubHeader *file_sub_header; + void set_file_desc(int fd) + { + file_desc_ = fd; + } + bool can_purge() + { + return pin_count_ <= 0; + } +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 { +class BPFrameManager : public common::MemPoolSimple { public: - BPManager(const char *tag); + BPFrameManager(const char *tag); Frame *get(int file_desc, PageNum page_num); @@ -111,26 +124,7 @@ public: class DiskBufferPool { public: - static DiskBufferPool *mk_instance() - { - 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(BufferPoolManager &bp_manager, BPFrameManager &frame_manager); ~DiskBufferPool(); /** @@ -142,53 +136,36 @@ public: * 根据文件名打开一个分页文件,返回文件ID * @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和页号获取指定页面到缓冲区,返回页面句柄指针。 * @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 get_page_num(BPPageHandle *page_handle, PageNum *page_num); - - /** - * 根据页面句柄指针返回对应的数据区指针 - */ - RC get_data(BPPageHandle *page_handle, char **data); + RC allocate_page(Frame **frame); /** * 比purge_page多一个动作, 在磁盘上将对应的页数据删掉。 */ - RC dispose_page(int file_id, PageNum page_num); + RC dispose_page(PageNum page_num); /** * 释放指定文件关联的页的内存, 如果已经脏, 则刷到磁盘,除了pinned page - * @param file_handle - * @param page_num 如果不指定page_num 将刷新所有页 */ - RC purge_page(int file_id, PageNum page_num); - - /** - * 标记指定页面为“脏”页。如果修改了页面的内容,则应调用此函数, - * 以便该页面被淘汰出缓冲区时系统将新的页面数据写入磁盘文件 - */ - RC mark_dirty(BPPageHandle *page_handle); + RC purge_page(PageNum page_num); + RC purge_all_pages(); /** * 此函数用于解除pageHandle对应页面的驻留缓冲区限制。 @@ -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: - RC allocate_page(Frame **buf); + RC allocate_frame(Frame **buf); /** - * 刷新指定文件关联的所有脏页到磁盘,除了pinned page - * @param file_handle - * @param page_num 如果不指定page_num 将刷新所有页 + * 刷新指定页面到磁盘(flush),并且释放关联的Frame */ - RC purge_page(BPFileHandle *file_handle, PageNum page_num); - RC purge_page(Frame *used_frame); - 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); + RC purge_frame(Frame *used_frame); + RC check_page_num(PageNum page_num); -private: - DiskBufferPool(); + /** + * 加载指定页面的数据到内存中 + */ + RC load_page(PageNum page_num, Frame *frame); private: - BPManager bp_manager_; - BPFileHandle *open_list_[MAX_OPEN_FILE] = {nullptr}; - std::map disposed_pages; - - static int POOL_NUM; + BufferPoolManager &bp_manager_; + BPFrameManager & frame_manager_; + std::string file_name_; + int file_desc_ = -1; + Frame * hdr_frame_ = nullptr; + BPFileHeader * file_header_ = nullptr; + std::set 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 buffer_pools_; + std::unordered_map fd_buffer_pools_; +}; #endif //__OBSERVER_STORAGE_COMMON_PAGE_MANAGER_H_ diff --git a/src/observer/storage/index/bplus_tree.cpp b/src/observer/storage/index/bplus_tree.cpp index ee6a5f2cfc86f5d6c5215ebbc8eae5b0950dc2d3..50ab0702ae618baf041bc67b91c6120b72348ed7 100644 --- a/src/observer/storage/index/bplus_tree.cpp +++ b/src/observer/storage/index/bplus_tree.cpp @@ -38,8 +38,8 @@ int calc_leaf_page_capacity(int attr_length) } ///////////////////////////////////////////////////////////////////////////////// -IndexNodeHandler::IndexNodeHandler(const IndexFileHeader &header, BPPageHandle &page_handle) - : header_(header), page_num_(page_handle.page_num()), node_((IndexNode *)page_handle.data()) +IndexNodeHandler::IndexNodeHandler(const IndexFileHeader &header, Frame *frame) + : header_(header), page_num_(frame->page_num()), node_((IndexNode *)frame->data()) {} bool IndexNodeHandler::is_leaf() const @@ -122,8 +122,8 @@ bool IndexNodeHandler::validate() const } ///////////////////////////////////////////////////////////////////////////////// -LeafIndexNodeHandler::LeafIndexNodeHandler(const IndexFileHeader &header, BPPageHandle &page_handle) - : IndexNodeHandler(header, page_handle), leaf_node_((LeafIndexNode *)page_handle.data()) +LeafIndexNodeHandler::LeafIndexNodeHandler(const IndexFileHeader &header, Frame *frame) + : IndexNodeHandler(header, frame), leaf_node_((LeafIndexNode *)frame->data()) {} void LeafIndexNodeHandler::init_empty() @@ -224,7 +224,7 @@ int LeafIndexNodeHandler::remove(const char *key, const KeyComparator &comparato return 0; } -RC LeafIndexNodeHandler::move_half_to(LeafIndexNodeHandler &other, DiskBufferPool *bp, int file_id) +RC LeafIndexNodeHandler::move_half_to(LeafIndexNodeHandler &other, DiskBufferPool *bp) { const int size = this->size(); const int move_index = size / 2; @@ -234,7 +234,7 @@ RC LeafIndexNodeHandler::move_half_to(LeafIndexNodeHandler &other, DiskBufferPoo this->increase_size(- ( size - move_index)); return RC::SUCCESS; } -RC LeafIndexNodeHandler::move_first_to_end(LeafIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool, int file_id) +RC LeafIndexNodeHandler::move_first_to_end(LeafIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool) { other.append(__item_at(0)); @@ -245,7 +245,7 @@ RC LeafIndexNodeHandler::move_first_to_end(LeafIndexNodeHandler &other, DiskBuff return RC::SUCCESS; } -RC LeafIndexNodeHandler::move_last_to_front(LeafIndexNodeHandler &other, DiskBufferPool *bp, int file_id) +RC LeafIndexNodeHandler::move_last_to_front(LeafIndexNodeHandler &other, DiskBufferPool *bp) { other.preappend(__item_at(size() - 1)); @@ -255,7 +255,7 @@ RC LeafIndexNodeHandler::move_last_to_front(LeafIndexNodeHandler &other, DiskBuf /** * move all items to left page */ -RC LeafIndexNodeHandler::move_to(LeafIndexNodeHandler &other, DiskBufferPool *bp, int file_id) +RC LeafIndexNodeHandler::move_to(LeafIndexNodeHandler &other, DiskBufferPool *bp) { memcpy(other.__item_at(other.size()), this->__item_at(0), this->size() * item_size()); other.increase_size(this->size()); @@ -265,17 +265,17 @@ RC LeafIndexNodeHandler::move_to(LeafIndexNodeHandler &other, DiskBufferPool *bp PageNum next_right_page_num = this->next_page(); if (next_right_page_num != BP_INVALID_PAGE_NUM) { - BPPageHandle next_right_page_handle; - RC rc = bp->get_this_page(file_id, next_right_page_num, &next_right_page_handle); + Frame *next_right_frame; + RC rc = bp->get_this_page(next_right_page_num, &next_right_frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch next right page. page number:%d. rc=%d:%s", next_right_page_num, rc, strrc(rc)); return rc; } - LeafIndexNodeHandler next_right_node(header_, next_right_page_handle); + LeafIndexNodeHandler next_right_node(header_, next_right_frame); next_right_node.set_prev_page(other.page_num()); - next_right_page_handle.mark_dirty(); - bp->unpin_page(&next_right_page_handle); + next_right_frame->mark_dirty(); + bp->unpin_page(next_right_frame); } return RC::SUCCESS; } @@ -322,7 +322,7 @@ std::string to_string(const LeafIndexNodeHandler &handler, const KeyPrinter &pri return ss.str(); } -bool LeafIndexNodeHandler::validate(const KeyComparator &comparator, DiskBufferPool *bp, int file_id) const +bool LeafIndexNodeHandler::validate(const KeyComparator &comparator, DiskBufferPool *bp) const { bool result = IndexNodeHandler::validate(); if (false == result) { @@ -343,20 +343,20 @@ bool LeafIndexNodeHandler::validate(const KeyComparator &comparator, DiskBufferP return true; } - BPPageHandle parent_page_handle; - RC rc = bp->get_this_page(file_id, parent_page_num, &parent_page_handle); + Frame *parent_frame; + RC rc = bp->get_this_page(parent_page_num, &parent_frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch parent page. page num=%d, rc=%d:%s", parent_page_num, rc, strrc(rc)); return false; } - InternalIndexNodeHandler parent_node(header_, parent_page_handle); + InternalIndexNodeHandler parent_node(header_, parent_frame); int index_in_parent = parent_node.value_index(this->page_num()); if (index_in_parent < 0) { LOG_WARN("invalid leaf node. cannot find index in parent. this page num=%d, parent page num=%d", this->page_num(), parent_page_num); - bp->unpin_page(&parent_page_handle); + bp->unpin_page(parent_frame); return false; } @@ -366,7 +366,7 @@ bool LeafIndexNodeHandler::validate(const KeyComparator &comparator, DiskBufferP LOG_WARN("invalid leaf node. first item should be greate than or equal to parent item. " \ "this page num=%d, parent page num=%d, index in parent=%d", this->page_num(), parent_node.page_num(), index_in_parent); - bp->unpin_page(&parent_page_handle); + bp->unpin_page(parent_frame); return false; } } @@ -377,17 +377,17 @@ bool LeafIndexNodeHandler::validate(const KeyComparator &comparator, DiskBufferP LOG_WARN("invalid leaf node. last item should be less than the item at the first after item in parent." \ "this page num=%d, parent page num=%d, parent item to compare=%d", this->page_num(), parent_node.page_num(), index_in_parent + 1); - bp->unpin_page(&parent_page_handle); + bp->unpin_page(parent_frame); return false; } } - bp->unpin_page(&parent_page_handle); + bp->unpin_page(parent_frame); return true; } ///////////////////////////////////////////////////////////////////////////////// -InternalIndexNodeHandler::InternalIndexNodeHandler(const IndexFileHeader &header, BPPageHandle &page_handle) - : IndexNodeHandler(header, page_handle), internal_node_((InternalIndexNode *)page_handle.data()) +InternalIndexNodeHandler::InternalIndexNodeHandler(const IndexFileHeader &header, Frame *frame) + : IndexNodeHandler(header, frame), internal_node_((InternalIndexNode *)frame->data()) {} std::string to_string(const InternalIndexNodeHandler &node, const KeyPrinter &printer) @@ -436,11 +436,11 @@ void InternalIndexNodeHandler::insert(const char *key, PageNum page_num, const K increase_size(1); } -RC InternalIndexNodeHandler::move_half_to(InternalIndexNodeHandler &other, DiskBufferPool *bp, int file_id) +RC InternalIndexNodeHandler::move_half_to(InternalIndexNodeHandler &other, DiskBufferPool *bp) { const int size = this->size(); const int move_index = size / 2; - RC rc = other.copy_from(this->__item_at(move_index), size - move_index, bp, file_id); + RC rc = other.copy_from(this->__item_at(move_index), size - move_index, bp); if (rc != RC::SUCCESS) { LOG_WARN("failed to copy item to new node. rc=%d:%s", rc, strrc(rc)); return rc; @@ -538,9 +538,9 @@ void InternalIndexNodeHandler::remove(int index) increase_size(-1); } -RC InternalIndexNodeHandler::move_to(InternalIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool, int file_id) +RC InternalIndexNodeHandler::move_to(InternalIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool) { - RC rc = other.copy_from(__item_at(0), size(), disk_buffer_pool, file_id); + RC rc = other.copy_from(__item_at(0), size(), disk_buffer_pool); if (rc != RC::SUCCESS) { LOG_WARN("failed to copy items to other node. rc=%d:%s", rc, strrc(rc)); return rc; @@ -550,9 +550,9 @@ RC InternalIndexNodeHandler::move_to(InternalIndexNodeHandler &other, DiskBuffer return RC::SUCCESS; } -RC InternalIndexNodeHandler::move_first_to_end(InternalIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool, int file_id) +RC InternalIndexNodeHandler::move_first_to_end(InternalIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool) { - RC rc = other.append(__item_at(0), disk_buffer_pool, file_id); + RC rc = other.append(__item_at(0), disk_buffer_pool); if (rc != RC::SUCCESS) { LOG_WARN("failed to append item to others."); return rc; @@ -565,9 +565,9 @@ RC InternalIndexNodeHandler::move_first_to_end(InternalIndexNodeHandler &other, return rc; } -RC InternalIndexNodeHandler::move_last_to_front(InternalIndexNodeHandler &other, DiskBufferPool *bp, int file_id) +RC InternalIndexNodeHandler::move_last_to_front(InternalIndexNodeHandler &other, DiskBufferPool *bp) { - RC rc = other.preappend(__item_at(size() - 1), bp, file_id); + RC rc = other.preappend(__item_at(size() - 1), bp); if (rc != RC::SUCCESS) { LOG_WARN("failed to preappend to others"); return rc; @@ -579,50 +579,50 @@ RC InternalIndexNodeHandler::move_last_to_front(InternalIndexNodeHandler &other, /** * copy items from other node to self's right */ -RC InternalIndexNodeHandler::copy_from(const char *items, int num, DiskBufferPool *disk_buffer_pool, int file_id) +RC InternalIndexNodeHandler::copy_from(const char *items, int num, DiskBufferPool *disk_buffer_pool) { memcpy(__item_at(this->size()), items, num * item_size()); RC rc = RC::SUCCESS; PageNum this_page_num = this->page_num(); - BPPageHandle page_handle; + Frame *frame = nullptr; for (int i = 0; i < num; i++) { const PageNum page_num = *(const PageNum *)((items + i * item_size()) + key_size()); - rc = disk_buffer_pool->get_this_page(file_id, page_num, &page_handle); + rc = disk_buffer_pool->get_this_page(page_num, &frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to set child's page num. child page num:%d, this page num=%d, rc=%d:%s", page_num, this_page_num, rc, strrc(rc)); return rc; } - IndexNodeHandler child_node(header_, page_handle); + IndexNodeHandler child_node(header_, frame); child_node.set_parent_page_num(this_page_num); - page_handle.mark_dirty(); - disk_buffer_pool->unpin_page(&page_handle); + frame->mark_dirty(); + disk_buffer_pool->unpin_page(frame); } increase_size(num); return rc; } -RC InternalIndexNodeHandler::append(const char *item, DiskBufferPool *bp, int file_id) +RC InternalIndexNodeHandler::append(const char *item, DiskBufferPool *bp) { - return this->copy_from(item, 1, bp, file_id); + return this->copy_from(item, 1, bp); } -RC InternalIndexNodeHandler::preappend(const char *item, DiskBufferPool *bp, int file_id) +RC InternalIndexNodeHandler::preappend(const char *item, DiskBufferPool *bp) { PageNum child_page_num = *(PageNum *)(item + key_size()); - BPPageHandle page_handle; - RC rc = bp->get_this_page(file_id, child_page_num, &page_handle); + Frame *frame = nullptr; + RC rc = bp->get_this_page(child_page_num, &frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch child page. rc=%d:%s", rc, strrc(rc)); return rc; } - IndexNodeHandler child_node(header_, page_handle); + IndexNodeHandler child_node(header_, frame); child_node.set_parent_page_num(this->page_num()); - page_handle.mark_dirty(); - bp->unpin_page(&page_handle); + frame->mark_dirty(); + bp->unpin_page(frame); if (this->size() > 0) { memmove(__item_at(1), __item_at(0), this->size() * item_size()); @@ -658,7 +658,7 @@ int InternalIndexNodeHandler::item_size() const return key_size() + this->value_size(); } -bool InternalIndexNodeHandler::validate(const KeyComparator &comparator, DiskBufferPool *bp, int file_id) const +bool InternalIndexNodeHandler::validate(const KeyComparator &comparator, DiskBufferPool *bp) const { bool result = IndexNodeHandler::validate(); if (false == result) { @@ -679,19 +679,19 @@ bool InternalIndexNodeHandler::validate(const KeyComparator &comparator, DiskBuf if (page_num < 0) { LOG_WARN("this page num=%d, got invalid child page. page num=%d", this->page_num(), page_num); } else { - BPPageHandle child_page_handle; - RC rc = bp->get_this_page(file_id, page_num, &child_page_handle); + Frame *child_frame; + RC rc = bp->get_this_page(page_num, &child_frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch child page while validate internal page. page num=%d, rc=%d:%s", page_num, rc, strrc(rc)); } else { - IndexNodeHandler child_node(header_, child_page_handle); + IndexNodeHandler child_node(header_, child_frame); if (child_node.parent_page_num() != this->page_num()) { LOG_WARN("child's parent page num is invalid. child page num=%d, parent page num=%d, this page num=%d", child_node.page_num(), child_node.parent_page_num(), this->page_num()); result = false; } - bp->unpin_page(&child_page_handle); + bp->unpin_page(child_frame); } } } @@ -705,19 +705,19 @@ bool InternalIndexNodeHandler::validate(const KeyComparator &comparator, DiskBuf return result; } - BPPageHandle parent_page_handle; - RC rc = bp->get_this_page(file_id, parent_page_num, &parent_page_handle); + Frame *parent_frame; + RC rc = bp->get_this_page(parent_page_num, &parent_frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch parent page. page num=%d, rc=%d:%s", parent_page_num, rc, strrc(rc)); return false; } - InternalIndexNodeHandler parent_node(header_, parent_page_handle); + InternalIndexNodeHandler parent_node(header_, parent_frame); int index_in_parent = parent_node.value_index(this->page_num()); if (index_in_parent < 0) { LOG_WARN("invalid internal node. cannot find index in parent. this page num=%d, parent page num=%d", this->page_num(), parent_page_num); - bp->unpin_page(&parent_page_handle); + bp->unpin_page(parent_frame); return false; } @@ -727,7 +727,7 @@ bool InternalIndexNodeHandler::validate(const KeyComparator &comparator, DiskBuf LOG_WARN("invalid internal node. the second item should be greate than or equal to parent item. " \ "this page num=%d, parent page num=%d, index in parent=%d", this->page_num(), parent_node.page_num(), index_in_parent); - bp->unpin_page(&parent_page_handle); + bp->unpin_page(parent_frame); return false; } } @@ -738,11 +738,11 @@ bool InternalIndexNodeHandler::validate(const KeyComparator &comparator, DiskBuf LOG_WARN("invalid internal node. last item should be less than the item at the first after item in parent." \ "this page num=%d, parent page num=%d, parent item to compare=%d", this->page_num(), parent_node.page_num(), index_in_parent + 1); - bp->unpin_page(&parent_page_handle); + bp->unpin_page(parent_frame); return false; } } - bp->unpin_page(&parent_page_handle); + bp->unpin_page(parent_frame); return result; } @@ -751,40 +751,40 @@ bool InternalIndexNodeHandler::validate(const KeyComparator &comparator, DiskBuf RC BplusTreeHandler::sync() { - return disk_buffer_pool_->purge_all_pages(file_id_); + return disk_buffer_pool_->purge_all_pages(); } RC BplusTreeHandler::create(const char *file_name, AttrType attr_type, int attr_length, int internal_max_size /* = -1*/, int leaf_max_size /* = -1 */) { - DiskBufferPool *disk_buffer_pool = theGlobalDiskBufferPool(); - RC rc = disk_buffer_pool->create_file(file_name); + BufferPoolManager &bpm = BufferPoolManager::instance(); + RC rc = bpm.create_file(file_name); if (rc != RC::SUCCESS) { LOG_WARN("Failed to create file. file name=%s, rc=%d:%s", file_name, rc, strrc(rc)); return rc; } LOG_INFO("Successfully create index file:%s", file_name); - int file_id; - rc = disk_buffer_pool->open_file(file_name, &file_id); + DiskBufferPool *bp = nullptr; + rc = bpm.open_file(file_name, bp); if (rc != RC::SUCCESS) { LOG_WARN("Failed to open file. file name=%s, rc=%d:%s", file_name, rc, strrc(rc)); return rc; } LOG_INFO("Successfully open index file %s.", file_name); - BPPageHandle header_page_handle; - rc = disk_buffer_pool->allocate_page(file_id, &header_page_handle); + Frame *header_frame; + rc = bp->allocate_page(&header_frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to allocate header page for bplus tree. rc=%d:%s", rc, strrc(rc)); - disk_buffer_pool->close_file(file_id); + bpm.close_file(file_name); return rc; } - if (header_page_handle.page_num() != FIRST_INDEX_PAGE) { + if (header_frame->page_num() != FIRST_INDEX_PAGE) { LOG_WARN("header page num should be %d but got %d. is it a new file : %s", - FIRST_INDEX_PAGE, header_page_handle.page_num(), file_name); - disk_buffer_pool->close_file(file_id); + FIRST_INDEX_PAGE, header_frame->page_num(), file_name); + bpm.close_file(file_name); return RC::INTERNAL; } @@ -794,7 +794,8 @@ RC BplusTreeHandler::create(const char *file_name, AttrType attr_type, int attr_ if (leaf_max_size < 0) { leaf_max_size = calc_leaf_page_capacity(attr_length); } - char *pdata = header_page_handle.data(); + + char *pdata = header_frame->data(); IndexFileHeader *file_header = (IndexFileHeader *)pdata; file_header->attr_length = attr_length; file_header->key_length = attr_length + sizeof(RID); @@ -803,14 +804,13 @@ RC BplusTreeHandler::create(const char *file_name, AttrType attr_type, int attr_ file_header->leaf_max_size = leaf_max_size; file_header->root_page = BP_INVALID_PAGE_NUM; - header_page_handle.mark_dirty(); - disk_buffer_pool->unpin_page(&header_page_handle); + header_frame->mark_dirty(); - disk_buffer_pool_ = disk_buffer_pool; - file_id_ = file_id; + disk_buffer_pool_ = bp; memcpy(&file_header_, pdata, sizeof(file_header_)); header_dirty_ = false; + bp->unpin_page(header_frame); mem_pool_item_ = new common::MemPoolItem(file_name); if (mem_pool_item_->init(file_header->key_length) < 0) { @@ -827,32 +827,31 @@ RC BplusTreeHandler::create(const char *file_name, AttrType attr_type, int attr_ RC BplusTreeHandler::open(const char *file_name) { - if (file_id_ >= 0) { + if (disk_buffer_pool_ != nullptr) { LOG_WARN("%s has been opened before index.open.", file_name); return RC::RECORD_OPENNED; } - DiskBufferPool *disk_buffer_pool = theGlobalDiskBufferPool(); - int file_id = 0; - RC rc = disk_buffer_pool->open_file(file_name, &file_id); + BufferPoolManager &bpm = BufferPoolManager::instance(); + DiskBufferPool *disk_buffer_pool; + RC rc = bpm.open_file(file_name, disk_buffer_pool); if (rc != RC::SUCCESS) { LOG_WARN("Failed to open file name=%s, rc=%d:%s", file_name, rc, strrc(rc)); return rc; } - BPPageHandle page_handle; - rc = disk_buffer_pool->get_this_page(file_id, FIRST_INDEX_PAGE, &page_handle); + Frame *frame; + rc = disk_buffer_pool->get_this_page(FIRST_INDEX_PAGE, &frame); if (rc != RC::SUCCESS) { LOG_WARN("Failed to get first page file name=%s, rc=%d:%s", file_name, rc, strrc(rc)); - disk_buffer_pool_->close_file(file_id); + bpm.close_file(file_name); return rc; } - char *pdata = page_handle.data(); + char *pdata = frame->data(); memcpy(&file_header_, pdata, sizeof(IndexFileHeader)); header_dirty_ = false; disk_buffer_pool_ = disk_buffer_pool; - file_id_ = file_id; mem_pool_item_ = new common::MemPoolItem(file_name); if (mem_pool_item_->init(file_header_.key_length) < 0) { @@ -862,19 +861,19 @@ RC BplusTreeHandler::open(const char *file_name) } // close old page_handle - disk_buffer_pool->unpin_page(&page_handle); + disk_buffer_pool->unpin_page(frame); key_comparator_.init(file_header_.attr_type, file_header_.attr_length); + key_printer_.init(file_header_.attr_type, file_header_.attr_length); LOG_INFO("Successfully open index %s", file_name); return RC::SUCCESS; } RC BplusTreeHandler::close() { - if (file_id_ != -1) { + if (disk_buffer_pool_ != nullptr) { - disk_buffer_pool_->close_file(file_id_); - file_id_ = -1; + disk_buffer_pool_->close_file(); // TODO delete mem_pool_item_; mem_pool_item_ = nullptr; @@ -884,52 +883,52 @@ RC BplusTreeHandler::close() return RC::SUCCESS; } -RC BplusTreeHandler::print_leaf(BPPageHandle &page_handle) +RC BplusTreeHandler::print_leaf(Frame *frame) { - LeafIndexNodeHandler leaf_node(file_header_, page_handle); + LeafIndexNodeHandler leaf_node(file_header_, frame); LOG_INFO("leaf node: %s", to_string(leaf_node, key_printer_).c_str()); - disk_buffer_pool_->unpin_page(&page_handle); + disk_buffer_pool_->unpin_page(frame); return RC::SUCCESS; } -RC BplusTreeHandler::print_internal_node_recursive(BPPageHandle &page_handle) +RC BplusTreeHandler::print_internal_node_recursive(Frame *frame) { RC rc = RC::SUCCESS; LOG_INFO("bplus tree. file header: %s", file_header_.to_string().c_str()); - InternalIndexNodeHandler internal_node(file_header_, page_handle); + InternalIndexNodeHandler internal_node(file_header_, frame); LOG_INFO("internal node: %s", to_string(internal_node, key_printer_).c_str()); int node_size = internal_node.size(); for (int i = 0; i < node_size; i++) { PageNum page_num = internal_node.value_at(i); - BPPageHandle child_page_handle; - rc = disk_buffer_pool_->get_this_page(file_id_, page_num, &child_page_handle); + Frame *child_frame; + rc = disk_buffer_pool_->get_this_page(page_num, &child_frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch child page. page id=%d, rc=%d:%s", page_num, rc, strrc(rc)); - disk_buffer_pool_->unpin_page(&page_handle); + disk_buffer_pool_->unpin_page(frame); return rc; } - IndexNodeHandler node(file_header_, child_page_handle); + IndexNodeHandler node(file_header_, child_frame); if (node.is_leaf()) { - rc = print_leaf(child_page_handle); + rc = print_leaf(child_frame); } else { - rc = print_internal_node_recursive(child_page_handle); + rc = print_internal_node_recursive(child_frame); } if (rc != RC::SUCCESS) { - LOG_WARN("failed to print node. page id=%d, rc=%d:%s", child_page_handle.page_num(), rc, strrc(rc)); - disk_buffer_pool_->unpin_page(&page_handle); + LOG_WARN("failed to print node. page id=%d, rc=%d:%s", child_frame->page_num(), rc, strrc(rc)); + disk_buffer_pool_->unpin_page(frame); return rc; } } - disk_buffer_pool_->unpin_page(&page_handle); + disk_buffer_pool_->unpin_page(frame); return RC::SUCCESS; } RC BplusTreeHandler::print_tree() { - if (file_id_ < 0) { + if (disk_buffer_pool_ == nullptr) { LOG_WARN("Index hasn't been created or opened, fail to print"); return RC::SUCCESS; } @@ -938,19 +937,19 @@ RC BplusTreeHandler::print_tree() return RC::SUCCESS; } - BPPageHandle page_handle; + Frame *frame; PageNum page_num = file_header_.root_page; - RC rc = disk_buffer_pool_->get_this_page(file_id_, page_num, &page_handle); + RC rc = disk_buffer_pool_->get_this_page(page_num, &frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch page. page id=%d, rc=%d:%s", page_num, rc, strrc(rc)); return rc; } - IndexNodeHandler node(file_header_, page_handle); + IndexNodeHandler node(file_header_, frame); if (node.is_leaf()) { - rc = print_leaf(page_handle); + rc = print_leaf(frame); } else { - rc = print_internal_node_recursive(page_handle); + rc = print_internal_node_recursive(frame); } return rc; } @@ -962,26 +961,26 @@ RC BplusTreeHandler::print_leafs() return RC::SUCCESS; } - BPPageHandle page_handle; + Frame *frame; - RC rc = left_most_page(page_handle); + RC rc = left_most_page(frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to get left most page. rc=%d:%s", rc, strrc(rc)); return rc; } - while (page_handle.page_num() != BP_INVALID_PAGE_NUM) { - LeafIndexNodeHandler leaf_node(file_header_, page_handle); + while (frame->page_num() != BP_INVALID_PAGE_NUM) { + LeafIndexNodeHandler leaf_node(file_header_, frame); LOG_INFO("leaf info: %s", to_string(leaf_node, key_printer_).c_str()); PageNum next_page_num = leaf_node.next_page(); - disk_buffer_pool_->unpin_page(&page_handle); + disk_buffer_pool_->unpin_page(frame); if (next_page_num == BP_INVALID_PAGE_NUM) { break; } - rc = disk_buffer_pool_->get_this_page(file_id_, next_page_num, &page_handle); + rc = disk_buffer_pool_->get_this_page(next_page_num, &frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to get next page. page id=%d, rc=%d:%s", next_page_num, rc, strrc(rc)); return rc; @@ -990,31 +989,31 @@ RC BplusTreeHandler::print_leafs() return rc; } -bool BplusTreeHandler::validate_node_recursive(BPPageHandle &page_handle) +bool BplusTreeHandler::validate_node_recursive(Frame *frame) { bool result = true; - IndexNodeHandler node(file_header_, page_handle); + IndexNodeHandler node(file_header_, frame); if (node.is_leaf()) { - LeafIndexNodeHandler leaf_node(file_header_, page_handle); - result = leaf_node.validate(key_comparator_, disk_buffer_pool_, file_id_); + LeafIndexNodeHandler leaf_node(file_header_, frame); + result = leaf_node.validate(key_comparator_, disk_buffer_pool_); } else { - InternalIndexNodeHandler internal_node(file_header_, page_handle); - result = internal_node.validate(key_comparator_, disk_buffer_pool_, file_id_); + InternalIndexNodeHandler internal_node(file_header_, frame); + result = internal_node.validate(key_comparator_, disk_buffer_pool_); for (int i = 0; result && i < internal_node.size(); i++) { PageNum page_num = internal_node.value_at(i); - BPPageHandle child_page_handle; - RC rc = disk_buffer_pool_->get_this_page(file_id_, page_num, &child_page_handle); + Frame *child_frame; + RC rc = disk_buffer_pool_->get_this_page(page_num, &child_frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch child page.page id=%d, rc=%d:%s", page_num, rc, strrc(rc)); result = false; break; } - result = validate_node_recursive(child_page_handle); + result = validate_node_recursive(child_frame); } } - disk_buffer_pool_->unpin_page(&page_handle); + disk_buffer_pool_->unpin_page(frame); return result; } @@ -1024,8 +1023,8 @@ bool BplusTreeHandler::validate_leaf_link() return true; } - BPPageHandle page_handle; - RC rc = left_most_page(page_handle); + Frame *frame; + RC rc = left_most_page(frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch left most page. rc=%d:%s", rc, strrc(rc)); return false; @@ -1033,31 +1032,31 @@ bool BplusTreeHandler::validate_leaf_link() PageNum prev_page_num = BP_INVALID_PAGE_NUM; - LeafIndexNodeHandler leaf_node(file_header_, page_handle); + LeafIndexNodeHandler leaf_node(file_header_, frame); if (leaf_node.prev_page() != prev_page_num) { LOG_WARN("invalid page. current_page_num=%d, prev page num should be %d but got %d", - page_handle.page_num(), prev_page_num, leaf_node.prev_page()); + frame->page_num(), prev_page_num, leaf_node.prev_page()); return false; } PageNum next_page_num = leaf_node.next_page(); - prev_page_num = page_handle.page_num(); + prev_page_num = frame->page_num(); char *prev_key = (char *)mem_pool_item_->alloc(); memcpy(prev_key, leaf_node.key_at(leaf_node.size() - 1), file_header_.key_length); - disk_buffer_pool_->unpin_page(&page_handle); + disk_buffer_pool_->unpin_page(frame); bool result = true; while (result && next_page_num != BP_INVALID_PAGE_NUM) { - rc = disk_buffer_pool_->get_this_page(file_id_, next_page_num, &page_handle); + rc = disk_buffer_pool_->get_this_page(next_page_num, &frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch next page. page num=%d, rc=%d:%s", next_page_num, rc, strrc(rc)); return false; } - LeafIndexNodeHandler leaf_node(file_header_, page_handle); + LeafIndexNodeHandler leaf_node(file_header_, frame); if (leaf_node.prev_page() != prev_page_num) { LOG_WARN("invalid page. current_page_num=%d, prev page num should be %d but got %d", - page_handle.page_num(), prev_page_num, leaf_node.prev_page()); + frame->page_num(), prev_page_num, leaf_node.prev_page()); result = false; } if (key_comparator_(prev_key, leaf_node.key_at(0)) >= 0) { @@ -1067,8 +1066,8 @@ bool BplusTreeHandler::validate_leaf_link() next_page_num = leaf_node.next_page(); memcpy(prev_key, leaf_node.key_at(leaf_node.size() - 1), file_header_.key_length); - prev_page_num = page_handle.page_num(); - disk_buffer_pool_->unpin_page(&page_handle); + prev_page_num = frame->page_num(); + disk_buffer_pool_->unpin_page(frame); } free_key(prev_key); @@ -1082,14 +1081,14 @@ bool BplusTreeHandler::validate_tree() return true; } - BPPageHandle page_handle; - RC rc = disk_buffer_pool_->get_this_page(file_id_, file_header_.root_page, &page_handle); + Frame *frame; + RC rc = disk_buffer_pool_->get_this_page(file_header_.root_page, &frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch root page. page id=%d, rc=%d:%s", file_header_.root_page, rc, strrc(rc)); return rc; } - if (!validate_node_recursive(page_handle) || !validate_leaf_link()) { + if (!validate_node_recursive(frame) || !validate_leaf_link()) { LOG_WARN("Current B+ Tree is invalid"); print_tree(); return false; @@ -1104,68 +1103,68 @@ bool BplusTreeHandler::is_empty() const return file_header_.root_page == BP_INVALID_PAGE_NUM; } -RC BplusTreeHandler::find_leaf(const char *key, BPPageHandle &page_handle) +RC BplusTreeHandler::find_leaf(const char *key, Frame *&frame) { return find_leaf_internal( [&](InternalIndexNodeHandler &internal_node) { return internal_node.value_at(internal_node.lookup(key_comparator_, key)); }, - page_handle); + frame); } -RC BplusTreeHandler::left_most_page(BPPageHandle &page_handle) +RC BplusTreeHandler::left_most_page(Frame *&frame) { return find_leaf_internal( [&](InternalIndexNodeHandler &internal_node) { return internal_node.value_at(0); }, - page_handle + frame ); } -RC BplusTreeHandler::right_most_page(BPPageHandle &page_handle) +RC BplusTreeHandler::right_most_page(Frame *&frame) { return find_leaf_internal( [&](InternalIndexNodeHandler &internal_node) { return internal_node.value_at(internal_node.size() - 1); }, - page_handle + frame ); } RC BplusTreeHandler::find_leaf_internal(const std::function &child_page_getter, - BPPageHandle &page_handle) + Frame *&frame) { if (is_empty()) { return RC::EMPTY; } - RC rc = disk_buffer_pool_->get_this_page(file_id_, file_header_.root_page, &page_handle); + RC rc = disk_buffer_pool_->get_this_page(file_header_.root_page, &frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch root page. page id=%d, rc=%d:%s", file_header_.root_page, rc, strrc(rc)); return rc; } - IndexNode *node = (IndexNode *)page_handle.data(); + IndexNode *node = (IndexNode *)frame->data(); while (false == node->is_leaf) { - InternalIndexNodeHandler internal_node(file_header_, page_handle); + InternalIndexNodeHandler internal_node(file_header_, frame); PageNum page_num = child_page_getter(internal_node); - disk_buffer_pool_->unpin_page(&page_handle); + disk_buffer_pool_->unpin_page(frame); - rc = disk_buffer_pool_->get_this_page(file_id_, page_num, &page_handle); + rc = disk_buffer_pool_->get_this_page(page_num, &frame); if (rc != RC::SUCCESS) { - LOG_WARN("Failed to load page file_id:%d, page_num:%d", file_id_, page_num); + LOG_WARN("Failed to load page page_num:%d", page_num); return rc; } - node = (IndexNode *)page_handle.data(); + node = (IndexNode *)frame->data(); } return RC::SUCCESS; } -RC BplusTreeHandler::insert_entry_into_leaf_node(BPPageHandle &page_handle, const char *key, const RID *rid) +RC BplusTreeHandler::insert_entry_into_leaf_node(Frame *frame, const char *key, const RID *rid) { - LeafIndexNodeHandler leaf_node(file_header_, page_handle); + LeafIndexNodeHandler leaf_node(file_header_, frame); bool exists = false; int insert_position = leaf_node.lookup(key_comparator_, key, &exists); if (exists) { @@ -1175,36 +1174,36 @@ RC BplusTreeHandler::insert_entry_into_leaf_node(BPPageHandle &page_handle, cons if (leaf_node.size() < leaf_node.max_size()) { leaf_node.insert(insert_position, key, (const char *)rid); - page_handle.mark_dirty(); - disk_buffer_pool_->unpin_page(&page_handle); + frame->mark_dirty(); + disk_buffer_pool_->unpin_page(frame); return RC::SUCCESS; } - BPPageHandle new_page_handle; - RC rc = split(page_handle, new_page_handle); + Frame * new_frame = nullptr; + RC rc = split(frame, new_frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to split leaf node. rc=%d:%s", rc, strrc(rc)); return rc; } - LeafIndexNodeHandler new_index_node(file_header_, new_page_handle); - new_index_node.set_prev_page(page_handle.page_num()); + LeafIndexNodeHandler new_index_node(file_header_, new_frame); + new_index_node.set_prev_page(frame->page_num()); new_index_node.set_next_page(leaf_node.next_page()); new_index_node.set_parent_page_num(leaf_node.parent_page_num()); - leaf_node.set_next_page(new_page_handle.page_num()); + leaf_node.set_next_page(new_frame->page_num()); PageNum next_page_num = new_index_node.next_page(); if (next_page_num != BP_INVALID_PAGE_NUM) { - BPPageHandle next_page_handle; - rc = disk_buffer_pool_->get_this_page(file_id_, next_page_num, &next_page_handle); + Frame * next_frame; + rc = disk_buffer_pool_->get_this_page(next_page_num, &next_frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch next page. page num=%d, rc=%d:%s", next_page_num, rc, strrc(rc)); return rc; } - LeafIndexNodeHandler next_node(file_header_, next_page_handle); - next_node.set_prev_page(new_page_handle.page_num()); - disk_buffer_pool_->unpin_page(&next_page_handle); + LeafIndexNodeHandler next_node(file_header_, next_frame); + next_node.set_prev_page(new_frame->page_num()); + disk_buffer_pool_->unpin_page(next_frame); } if (insert_position < leaf_node.size()) { @@ -1213,94 +1212,94 @@ RC BplusTreeHandler::insert_entry_into_leaf_node(BPPageHandle &page_handle, cons new_index_node.insert(insert_position - leaf_node.size(), key, (const char *)rid); } - return insert_entry_into_parent(page_handle, new_page_handle, new_index_node.key_at(0)); + return insert_entry_into_parent(frame, new_frame, new_index_node.key_at(0)); } -RC BplusTreeHandler::insert_entry_into_parent(BPPageHandle &page_handle, BPPageHandle &new_page_handle, const char *key) +RC BplusTreeHandler::insert_entry_into_parent(Frame *frame, Frame *new_frame, const char *key) { RC rc = RC::SUCCESS; - IndexNodeHandler node_handler(file_header_, page_handle); - IndexNodeHandler new_node_handler(file_header_, new_page_handle); + IndexNodeHandler node_handler(file_header_, frame); + IndexNodeHandler new_node_handler(file_header_, new_frame); PageNum parent_page_num = node_handler.parent_page_num(); if (parent_page_num == BP_INVALID_PAGE_NUM) { // create new root page - BPPageHandle root_page; - rc = disk_buffer_pool_->allocate_page(file_id_, &root_page); + Frame *root_frame; + rc = disk_buffer_pool_->allocate_page(&root_frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to allocate new root page. rc=%d:%s", rc, strrc(rc)); return rc; } - InternalIndexNodeHandler root_node(file_header_, root_page); + InternalIndexNodeHandler root_node(file_header_, root_frame); root_node.init_empty(); - root_node.create_new_root(page_handle.page_num(), key, new_page_handle.page_num()); - node_handler.set_parent_page_num(root_page.page_num()); - new_node_handler.set_parent_page_num(root_page.page_num()); + root_node.create_new_root(frame->page_num(), key, new_frame->page_num()); + node_handler.set_parent_page_num(root_frame->page_num()); + new_node_handler.set_parent_page_num(root_frame->page_num()); - page_handle.mark_dirty(); - new_page_handle.mark_dirty(); - disk_buffer_pool_->unpin_page(&page_handle); - disk_buffer_pool_->unpin_page(&new_page_handle); + frame->mark_dirty(); + new_frame->mark_dirty(); + disk_buffer_pool_->unpin_page(frame); + disk_buffer_pool_->unpin_page(new_frame); - file_header_.root_page = root_page.page_num(); + file_header_.root_page = root_frame->page_num(); update_root_page_num(); // TODO - root_page.mark_dirty(); - disk_buffer_pool_->unpin_page(&root_page); + root_frame->mark_dirty(); + disk_buffer_pool_->unpin_page(root_frame); return RC::SUCCESS; } else { - BPPageHandle parent_page_handle; - rc = disk_buffer_pool_->get_this_page(file_id_, parent_page_num, &parent_page_handle); + Frame *parent_frame; + rc = disk_buffer_pool_->get_this_page(parent_page_num, &parent_frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to insert entry into leaf. rc=%d:%s", rc, strrc(rc)); // should do more things to recover return rc; } - InternalIndexNodeHandler node(file_header_, parent_page_handle); + InternalIndexNodeHandler node(file_header_, parent_frame); /// current node is not in full mode, insert the entry and return if (node.size() < node.max_size()) { - node.insert(key, new_page_handle.page_num(), key_comparator_); + node.insert(key, new_frame->page_num(), key_comparator_); new_node_handler.set_parent_page_num(parent_page_num); - page_handle.mark_dirty(); - new_page_handle.mark_dirty(); - parent_page_handle.mark_dirty(); - disk_buffer_pool_->unpin_page(&page_handle); - disk_buffer_pool_->unpin_page(&new_page_handle); - disk_buffer_pool_->unpin_page(&parent_page_handle); + frame->mark_dirty(); + new_frame->mark_dirty(); + parent_frame->mark_dirty(); + disk_buffer_pool_->unpin_page(frame); + disk_buffer_pool_->unpin_page(new_frame); + disk_buffer_pool_->unpin_page(parent_frame); } else { // we should split the node and insert the entry and then insert new entry to current node's parent - BPPageHandle new_parent_page_handle; - rc = split(parent_page_handle, new_parent_page_handle); + Frame * new_parent_frame; + rc = split(parent_frame, new_parent_frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to split internal node. rc=%d:%s", rc, strrc(rc)); - disk_buffer_pool_->unpin_page(&page_handle); - disk_buffer_pool_->unpin_page(&new_page_handle); - disk_buffer_pool_->unpin_page(&parent_page_handle); + disk_buffer_pool_->unpin_page(frame); + disk_buffer_pool_->unpin_page(new_frame); + disk_buffer_pool_->unpin_page(parent_frame); } else { // insert into left or right ? decide by key compare result - InternalIndexNodeHandler new_node(file_header_, new_parent_page_handle); + InternalIndexNodeHandler new_node(file_header_, new_parent_frame); if (key_comparator_(key, new_node.key_at(0)) > 0) { - new_node.insert(key, new_page_handle.page_num(), key_comparator_); + new_node.insert(key, new_frame->page_num(), key_comparator_); new_node_handler.set_parent_page_num(new_node.page_num()); } else { - node.insert(key, new_page_handle.page_num(), key_comparator_); + node.insert(key, new_frame->page_num(), key_comparator_); new_node_handler.set_parent_page_num(node.page_num()); } - disk_buffer_pool_->unpin_page(&page_handle); - disk_buffer_pool_->unpin_page(&new_page_handle); + disk_buffer_pool_->unpin_page(frame); + disk_buffer_pool_->unpin_page(new_frame); - rc = insert_entry_into_parent(parent_page_handle, new_parent_page_handle, new_node.key_at(0)); + rc = insert_entry_into_parent(parent_frame, new_parent_frame, new_node.key_at(0)); } } } @@ -1314,9 +1313,9 @@ RC BplusTreeHandler::insert_entry_into_parent(BPPageHandle &page_handle, BPPageH * @param intert_position the intert position of new key */ template -RC BplusTreeHandler::split(BPPageHandle &page_handle, BPPageHandle &new_page_handle) +RC BplusTreeHandler::split(Frame *frame, Frame *&new_frame) { - IndexNodeHandlerType old_node(file_header_, page_handle); + IndexNodeHandlerType old_node(file_header_, frame); char *new_parent_key = (char *)mem_pool_item_->alloc(); if (new_parent_key == nullptr) { @@ -1325,36 +1324,36 @@ RC BplusTreeHandler::split(BPPageHandle &page_handle, BPPageHandle &new_page_han } // add a new node - RC rc = disk_buffer_pool_->allocate_page(file_id_, &new_page_handle); + RC rc = disk_buffer_pool_->allocate_page(&new_frame); if (rc != RC::SUCCESS) { - LOG_WARN("Failed to split index page due to failed to allocate page, file_id:%d. rc=%d:%s", file_id_, rc, strrc(rc)); + LOG_WARN("Failed to split index page due to failed to allocate page, rc=%d:%s", rc, strrc(rc)); return rc; } - IndexNodeHandlerType new_node(file_header_, new_page_handle); + IndexNodeHandlerType new_node(file_header_, new_frame); new_node.init_empty(); new_node.set_parent_page_num(old_node.parent_page_num()); - old_node.move_half_to(new_node, disk_buffer_pool_, file_id_); + old_node.move_half_to(new_node, disk_buffer_pool_); - page_handle.mark_dirty(); - new_page_handle.mark_dirty(); + frame->mark_dirty(); + new_frame->mark_dirty(); return RC::SUCCESS; } RC BplusTreeHandler::update_root_page_num() { - BPPageHandle header_page_handle; - RC rc = disk_buffer_pool_->get_this_page(file_id_, FIRST_INDEX_PAGE, &header_page_handle); + Frame * header_frame; + RC rc = disk_buffer_pool_->get_this_page(FIRST_INDEX_PAGE, &header_frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch header page. rc=%d:%s", rc, strrc(rc)); return rc; } - IndexFileHeader *header = (IndexFileHeader *)header_page_handle.data(); + IndexFileHeader *header = (IndexFileHeader *)header_frame->data(); header->root_page = file_header_.root_page; - header_page_handle.mark_dirty(); - disk_buffer_pool_->unpin_page(&header_page_handle); + header_frame->mark_dirty(); + disk_buffer_pool_->unpin_page(header_frame); return rc; } @@ -1368,19 +1367,19 @@ RC BplusTreeHandler::create_new_tree(const char *key, const RID *rid) return rc; } - BPPageHandle page_handle; - rc = disk_buffer_pool_->allocate_page(file_id_, &page_handle); + Frame *frame; + rc = disk_buffer_pool_->allocate_page(&frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to allocate root page. rc=%d:%s", rc, strrc(rc)); return rc; } - LeafIndexNodeHandler leaf_node(file_header_, page_handle); + LeafIndexNodeHandler leaf_node(file_header_, frame); leaf_node.init_empty(); leaf_node.insert(0, key, (const char *)rid); - file_header_.root_page = page_handle.page_num(); - page_handle.mark_dirty(); - disk_buffer_pool_->unpin_page(&page_handle); + file_header_.root_page = frame->page_num(); + frame->mark_dirty(); + disk_buffer_pool_->unpin_page(frame); rc = update_root_page_num(); // disk_buffer_pool_->check_all_pages_unpinned(file_id_); @@ -1391,7 +1390,7 @@ char *BplusTreeHandler::make_key(const char *user_key, const RID &rid) { char *key = (char *)mem_pool_item_->alloc(); if (key == nullptr) { - LOG_WARN("Failed to alloc memory for key. file_id:%d", file_id_); + LOG_WARN("Failed to alloc memory for key."); return nullptr; } memcpy(key, user_key, file_header_.attr_length); @@ -1406,11 +1405,6 @@ void BplusTreeHandler::free_key(char *key) RC BplusTreeHandler::insert_entry(const char *user_key, const RID *rid) { - if (file_id_ < 0) { - LOG_WARN("Index isn't ready!"); - return RC::RECORD_CLOSED; - } - if (user_key == nullptr || rid == nullptr) { LOG_WARN("Invalid arguments, key is empty or rid is empty"); return RC::INVALID_ARGUMENT; @@ -1418,7 +1412,7 @@ RC BplusTreeHandler::insert_entry(const char *user_key, const RID *rid) char *key = make_key(user_key, *rid); if (key == nullptr) { - LOG_WARN("Failed to alloc memory for key. file_id:%d", file_id_); + LOG_WARN("Failed to alloc memory for key."); return RC::NOMEM; } @@ -1426,18 +1420,18 @@ RC BplusTreeHandler::insert_entry(const char *user_key, const RID *rid) return create_new_tree(key, rid); } - BPPageHandle page_handle; - RC rc = find_leaf(key, page_handle); + Frame *frame; + RC rc = find_leaf(key, frame); if (rc != RC::SUCCESS) { - LOG_WARN("Failed to find leaf file_id:%d, %s. rc=%d:%s", file_id_, rid->to_string().c_str(), rc, strrc(rc)); + LOG_WARN("Failed to find leaf %s. rc=%d:%s", rid->to_string().c_str(), rc, strrc(rc)); mem_pool_item_->free(key); return rc; } - rc = insert_entry_into_leaf_node(page_handle, key, rid); + rc = insert_entry_into_leaf_node(frame, key, rid); if (rc != RC::SUCCESS) { - LOG_TRACE("Failed to insert into leaf of index %d, rid:%s", file_id_, rid->to_string().c_str()); - disk_buffer_pool_->unpin_page(&page_handle); + LOG_TRACE("Failed to insert into leaf of index, rid:%s", rid->to_string().c_str()); + disk_buffer_pool_->unpin_page(frame); mem_pool_item_->free(key); // disk_buffer_pool_->check_all_pages_unpinned(file_id_); return rc; @@ -1451,14 +1445,6 @@ RC BplusTreeHandler::insert_entry(const char *user_key, const RID *rid) RC BplusTreeHandler::get_entry(const char *user_key, std::list &rids) { - if (file_id_ < 0) { - LOG_WARN("Index isn't ready!"); - return RC::RECORD_CLOSED; - } - - LOG_INFO("before get entry"); - disk_buffer_pool_->check_all_pages_unpinned(file_id_); - BplusTreeScanner scanner(*this); RC rc = scanner.open(user_key, true/*left_inclusive*/, user_key, true/*right_inclusive*/); if (rc != RC::SUCCESS) { @@ -1477,17 +1463,15 @@ RC BplusTreeHandler::get_entry(const char *user_key, std::list &rids) } else { rc = RC::SUCCESS; } - LOG_INFO("after get entry"); - disk_buffer_pool_->check_all_pages_unpinned(file_id_); return rc; } -RC BplusTreeHandler::adjust_root(BPPageHandle &root_page_handle) +RC BplusTreeHandler::adjust_root(Frame *root_frame) { - IndexNodeHandler root_node(file_header_, root_page_handle); + IndexNodeHandler root_node(file_header_, root_frame); if (root_node.is_leaf() && root_node.size() > 0) { - root_page_handle.mark_dirty(); - disk_buffer_pool_->unpin_page(&root_page_handle); + root_frame->mark_dirty(); + disk_buffer_pool_->unpin_page(root_frame); return RC::SUCCESS; } @@ -1496,36 +1480,36 @@ RC BplusTreeHandler::adjust_root(BPPageHandle &root_page_handle) file_header_.root_page = BP_INVALID_PAGE_NUM; } else { // this is an internal node and has only one child node - InternalIndexNodeHandler internal_node(file_header_, root_page_handle); + InternalIndexNodeHandler internal_node(file_header_, root_frame); const PageNum child_page_num = internal_node.value_at(0); - BPPageHandle child_page_handle; - RC rc = disk_buffer_pool_->get_this_page(file_id_, child_page_num, &child_page_handle); + Frame * child_frame; + RC rc = disk_buffer_pool_->get_this_page(child_page_num, &child_frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch child page. page num=%d, rc=%d:%s", child_page_num, rc, strrc(rc)); return rc; } - IndexNodeHandler child_node(file_header_, child_page_handle); + IndexNodeHandler child_node(file_header_, child_frame); child_node.set_parent_page_num(BP_INVALID_PAGE_NUM); - disk_buffer_pool_->unpin_page(&child_page_handle); + disk_buffer_pool_->unpin_page(child_frame); file_header_.root_page = child_page_num; } update_root_page_num(); - PageNum old_root_page_num = root_page_handle.page_num(); - disk_buffer_pool_->unpin_page(&root_page_handle); - disk_buffer_pool_->dispose_page(file_id_, old_root_page_num); + PageNum old_root_page_num = root_frame->page_num(); + disk_buffer_pool_->unpin_page(root_frame); + disk_buffer_pool_->dispose_page(old_root_page_num); return RC::SUCCESS; } template -RC BplusTreeHandler::coalesce_or_redistribute(BPPageHandle &page_handle) +RC BplusTreeHandler::coalesce_or_redistribute(Frame *frame) { - IndexNodeHandlerType index_node(file_header_, page_handle); + IndexNodeHandlerType index_node(file_header_, frame); if (index_node.size() >= index_node.min_size()) { - disk_buffer_pool_->unpin_page(&page_handle); + disk_buffer_pool_->unpin_page(frame); return RC::SUCCESS; } @@ -1533,27 +1517,27 @@ RC BplusTreeHandler::coalesce_or_redistribute(BPPageHandle &page_handle) if (BP_INVALID_PAGE_NUM == parent_page_num) { // this is the root page if (index_node.size() > 1) { - disk_buffer_pool_->unpin_page(&page_handle); + disk_buffer_pool_->unpin_page(frame); } else { // adjust the root node - adjust_root(page_handle); + adjust_root(frame); } return RC::SUCCESS; } - BPPageHandle parent_page_handle; - RC rc = disk_buffer_pool_->get_this_page(file_id_, parent_page_num, &parent_page_handle); + Frame * parent_frame; + RC rc = disk_buffer_pool_->get_this_page(parent_page_num, &parent_frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch parent page. page id=%d, rc=%d:%s", parent_page_num, rc, strrc(rc)); - disk_buffer_pool_->unpin_page(&page_handle); + disk_buffer_pool_->unpin_page(frame); return rc; } - InternalIndexNodeHandler parent_index_node(file_header_, parent_page_handle); + InternalIndexNodeHandler parent_index_node(file_header_, parent_frame); int index = parent_index_node.lookup(key_comparator_, index_node.key_at(index_node.size() - 1)); - if (parent_index_node.value_at(index) != page_handle.page_num()) { + if (parent_index_node.value_at(index) != frame->page_num()) { LOG_ERROR("lookup return an invalid value. index=%d, this page num=%d, but got %d", - index, page_handle.page_num(), parent_index_node.value_at(index)); + index, frame->page_num(), parent_index_node.value_at(index)); } PageNum neighbor_page_num; if (index == 0) { @@ -1562,53 +1546,52 @@ RC BplusTreeHandler::coalesce_or_redistribute(BPPageHandle &page_handle) neighbor_page_num = parent_index_node.value_at(index - 1); } - BPPageHandle neighbor_page_handle; - rc = disk_buffer_pool_->get_this_page(file_id_, neighbor_page_num, &neighbor_page_handle); + Frame * neighbor_frame; + rc = disk_buffer_pool_->get_this_page(neighbor_page_num, &neighbor_frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch neighbor page. page id=%d, rc=%d:%s", neighbor_page_num, rc, strrc(rc)); // TODO do more thing to release resource - disk_buffer_pool_->unpin_page(&page_handle); - disk_buffer_pool_->unpin_page(&parent_page_handle); + disk_buffer_pool_->unpin_page(frame); + disk_buffer_pool_->unpin_page(parent_frame); return rc; } - IndexNodeHandlerType neighbor_node(file_header_, neighbor_page_handle); + IndexNodeHandlerType neighbor_node(file_header_, neighbor_frame); if (index_node.size() + neighbor_node.size() > index_node.max_size()) { - rc = redistribute(neighbor_page_handle, page_handle, parent_page_handle, index); + rc = redistribute(neighbor_frame, frame, parent_frame, index); } else { - rc = coalesce(neighbor_page_handle, page_handle, parent_page_handle, index); + rc = coalesce(neighbor_frame, frame, parent_frame, index); } return rc; } template -RC BplusTreeHandler::coalesce(BPPageHandle &neighbor_page_handle, BPPageHandle &page_handle, - BPPageHandle &parent_page_handle, int index) +RC BplusTreeHandler::coalesce(Frame *neighbor_frame, Frame *frame, Frame *parent_frame, int index) { - IndexNodeHandlerType neighbor_node(file_header_, neighbor_page_handle); - IndexNodeHandlerType node(file_header_, page_handle); + IndexNodeHandlerType neighbor_node(file_header_, neighbor_frame); + IndexNodeHandlerType node(file_header_, frame); - InternalIndexNodeHandler parent_node(file_header_, parent_page_handle); + InternalIndexNodeHandler parent_node(file_header_, parent_frame); - BPPageHandle *left_page_handle = nullptr; - BPPageHandle *right_page_handle = nullptr; + Frame *left_frame = nullptr; + Frame *right_frame = nullptr; if (index == 0) { // neighbor node is at right - left_page_handle = &page_handle; - right_page_handle = &neighbor_page_handle; + left_frame = frame; + right_frame = neighbor_frame; index++; } else { - left_page_handle = &neighbor_page_handle; - right_page_handle = &page_handle; + left_frame = neighbor_frame; + right_frame = frame; // neighbor is at left } - IndexNodeHandlerType left_node(file_header_, *left_page_handle); - IndexNodeHandlerType right_node(file_header_, *right_page_handle); + IndexNodeHandlerType left_node(file_header_, left_frame); + IndexNodeHandlerType right_node(file_header_, right_frame); parent_node.remove(index); // parent_node.validate(key_comparator_, disk_buffer_pool_, file_id_); - RC rc = right_node.move_to(left_node, disk_buffer_pool_, file_id_); + RC rc = right_node.move_to(left_node, disk_buffer_pool_); if (rc != RC::SUCCESS) { LOG_WARN("failed to move right node to left. rc=%d:%s", rc, strrc(rc)); return rc; @@ -1616,101 +1599,95 @@ RC BplusTreeHandler::coalesce(BPPageHandle &neighbor_page_handle, BPPageHandle & // left_node.validate(key_comparator_); if (left_node.is_leaf()) { - LeafIndexNodeHandler left_leaf_node(file_header_, *left_page_handle); - LeafIndexNodeHandler right_leaf_node(file_header_, *right_page_handle); + LeafIndexNodeHandler left_leaf_node(file_header_, left_frame); + LeafIndexNodeHandler right_leaf_node(file_header_, right_frame); left_leaf_node.set_next_page(right_leaf_node.next_page()); PageNum next_right_page_num = right_leaf_node.next_page(); if (next_right_page_num != BP_INVALID_PAGE_NUM) { - BPPageHandle next_right_page_handle; - rc = disk_buffer_pool_->get_this_page(file_id_, next_right_page_num, &next_right_page_handle); + Frame *next_right_frame; + rc = disk_buffer_pool_->get_this_page(next_right_page_num, &next_right_frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch next right page. page number:%d. rc=%d:%s", next_right_page_num, rc, strrc(rc)); - disk_buffer_pool_->unpin_page(&page_handle); - disk_buffer_pool_->unpin_page(&neighbor_page_handle); - disk_buffer_pool_->unpin_page(&parent_page_handle); + disk_buffer_pool_->unpin_page(frame); + disk_buffer_pool_->unpin_page(neighbor_frame); + disk_buffer_pool_->unpin_page(parent_frame); return rc; } - LeafIndexNodeHandler next_right_node(file_header_, next_right_page_handle); + LeafIndexNodeHandler next_right_node(file_header_, next_right_frame); next_right_node.set_prev_page(left_node.page_num()); - disk_buffer_pool_->unpin_page(&next_right_page_handle); + disk_buffer_pool_->unpin_page(next_right_frame); } } - PageNum right_page_num = right_page_handle->page_num(); - disk_buffer_pool_->unpin_page(left_page_handle); - disk_buffer_pool_->unpin_page(right_page_handle); - disk_buffer_pool_->dispose_page(file_id_, right_page_num); - return coalesce_or_redistribute(parent_page_handle); + PageNum right_page_num = right_frame->page_num(); + disk_buffer_pool_->unpin_page(left_frame); + disk_buffer_pool_->unpin_page(right_frame); + disk_buffer_pool_->dispose_page(right_page_num); + return coalesce_or_redistribute(parent_frame); } template -RC BplusTreeHandler::redistribute(BPPageHandle &neighbor_page_handle, BPPageHandle &page_handle, - BPPageHandle &parent_page_handle, int index) +RC BplusTreeHandler::redistribute(Frame *neighbor_frame, Frame *frame, Frame *parent_frame, int index) { - InternalIndexNodeHandler parent_node(file_header_, parent_page_handle); - IndexNodeHandlerType neighbor_node(file_header_, neighbor_page_handle); - IndexNodeHandlerType node(file_header_, page_handle); + InternalIndexNodeHandler parent_node(file_header_, parent_frame); + IndexNodeHandlerType neighbor_node(file_header_, neighbor_frame); + IndexNodeHandlerType node(file_header_, frame); if (neighbor_node.size() < node.size()) { LOG_ERROR("got invalid nodes. neighbor node size %d, this node size %d", neighbor_node.size(), node.size()); } if (index == 0) { // the neighbor is at right - neighbor_node.move_first_to_end(node, disk_buffer_pool_, file_id_); + neighbor_node.move_first_to_end(node, disk_buffer_pool_); // neighbor_node.validate(key_comparator_, disk_buffer_pool_, file_id_); // node.validate(key_comparator_, disk_buffer_pool_, file_id_); parent_node.set_key_at(index + 1, neighbor_node.key_at(0)); // parent_node.validate(key_comparator_, disk_buffer_pool_, file_id_); } else { // the neighbor is at left - neighbor_node.move_last_to_front(node, disk_buffer_pool_, file_id_); + neighbor_node.move_last_to_front(node, disk_buffer_pool_); // neighbor_node.validate(key_comparator_, disk_buffer_pool_, file_id_); // node.validate(key_comparator_, disk_buffer_pool_, file_id_); parent_node.set_key_at(index, node.key_at(0)); // parent_node.validate(key_comparator_, disk_buffer_pool_, file_id_); } - neighbor_page_handle.mark_dirty(); - page_handle.mark_dirty(); - parent_page_handle.mark_dirty(); - disk_buffer_pool_->unpin_page(&parent_page_handle); - disk_buffer_pool_->unpin_page(&neighbor_page_handle); - disk_buffer_pool_->unpin_page(&page_handle); + neighbor_frame->mark_dirty(); + frame->mark_dirty(); + parent_frame->mark_dirty(); + disk_buffer_pool_->unpin_page(parent_frame); + disk_buffer_pool_->unpin_page(neighbor_frame); + disk_buffer_pool_->unpin_page(frame); return RC::SUCCESS; } -RC BplusTreeHandler::delete_entry_internal(BPPageHandle &leaf_page_handle, const char *key) +RC BplusTreeHandler::delete_entry_internal(Frame *leaf_frame, const char *key) { - LeafIndexNodeHandler leaf_index_node(file_header_, leaf_page_handle); + LeafIndexNodeHandler leaf_index_node(file_header_, leaf_frame); const int remove_count = leaf_index_node.remove(key, key_comparator_); if (remove_count == 0) { LOG_TRACE("no data to remove"); - disk_buffer_pool_->unpin_page(&leaf_page_handle); + disk_buffer_pool_->unpin_page(leaf_frame); return RC::RECORD_RECORD_NOT_EXIST; } // leaf_index_node.validate(key_comparator_, disk_buffer_pool_, file_id_); - leaf_page_handle.mark_dirty(); + leaf_frame->mark_dirty(); if (leaf_index_node.size() >= leaf_index_node.min_size()) { - disk_buffer_pool_->unpin_page(&leaf_page_handle); + disk_buffer_pool_->unpin_page(leaf_frame); return RC::SUCCESS; } - return coalesce_or_redistribute(leaf_page_handle); + return coalesce_or_redistribute(leaf_frame); } RC BplusTreeHandler::delete_entry(const char *user_key, const RID *rid) { - if (file_id_ < 0) { - LOG_WARN("Failed to delete index entry, due to index is't ready"); - return RC::RECORD_CLOSED; - } - char *key = (char *)mem_pool_item_->alloc(); if (nullptr == key) { LOG_WARN("Failed to alloc memory for key. size=%d", file_header_.key_length); @@ -1719,24 +1696,20 @@ RC BplusTreeHandler::delete_entry(const char *user_key, const RID *rid) memcpy(key, user_key, file_header_.attr_length); memcpy(key + file_header_.attr_length, rid, sizeof(*rid)); - LOG_INFO("before delete"); - disk_buffer_pool_->check_all_pages_unpinned(file_id_); - BPPageHandle leaf_page_handle; - RC rc = find_leaf(key, leaf_page_handle); + Frame *leaf_frame; + RC rc = find_leaf(key, leaf_frame); if (rc != RC::SUCCESS) { LOG_WARN("failed to find leaf page. rc =%d:%s", rc, strrc(rc)); mem_pool_item_->free(key); return rc; } - rc = delete_entry_internal(leaf_page_handle, key); + rc = delete_entry_internal(leaf_frame, key); if (rc != RC::SUCCESS) { - LOG_WARN("Failed to delete index %d", file_id_); + LOG_WARN("Failed to delete index"); mem_pool_item_->free(key); return rc; } mem_pool_item_->free(key); - LOG_INFO("after delete"); - disk_buffer_pool_->check_all_pages_unpinned(file_id_); return RC::SUCCESS; } @@ -1771,7 +1744,7 @@ RC BplusTreeScanner::open(const char *left_user_key, bool left_inclusive, } if (nullptr == left_user_key) { - rc = tree_handler_.left_most_page(left_page_handle_); + rc = tree_handler_.left_most_page(left_frame_); if (rc != RC::SUCCESS) { LOG_WARN("failed to find left most page. rc=%d:%s", rc, strrc(rc)); return rc; @@ -1785,14 +1758,14 @@ RC BplusTreeScanner::open(const char *left_user_key, bool left_inclusive, } else { left_key = tree_handler_.make_key(left_user_key, *RID::max()); } - rc = tree_handler_.find_leaf(left_key, left_page_handle_); + rc = tree_handler_.find_leaf(left_key, left_frame_); if (rc != RC::SUCCESS) { LOG_WARN("failed to find left page. rc=%d:%s", rc, strrc(rc)); tree_handler_.free_key(left_key); return rc; } - LeafIndexNodeHandler left_node(tree_handler_.file_header_, left_page_handle_); + LeafIndexNodeHandler left_node(tree_handler_.file_header_, left_frame_); int left_index = left_node.lookup(tree_handler_.key_comparator_, left_key); tree_handler_.free_key(left_key); // lookup 返回的是适合插入的位置,还需要判断一下是否在合适的边界范围内 @@ -1802,8 +1775,8 @@ RC BplusTreeScanner::open(const char *left_user_key, bool left_inclusive, return RC::SUCCESS; } - tree_handler_.disk_buffer_pool_->unpin_page(&left_page_handle_); - rc = tree_handler_.disk_buffer_pool_->get_this_page(tree_handler_.file_id_, next_page_num, &left_page_handle_); + tree_handler_.disk_buffer_pool_->unpin_page(left_frame_); + rc = tree_handler_.disk_buffer_pool_->get_this_page(next_page_num, &left_frame_); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch next page. page num=%d, rc=%d:%s", next_page_num, rc, strrc(rc)); return rc; @@ -1816,13 +1789,13 @@ RC BplusTreeScanner::open(const char *left_user_key, bool left_inclusive, // 没有指定右边界范围,那么就返回右边界最大值 if (nullptr == right_user_key) { - rc = tree_handler_.right_most_page(right_page_handle_); + rc = tree_handler_.right_most_page(right_frame_); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch right most page. rc=%d:%s", rc, strrc(rc)); return rc; } - LeafIndexNodeHandler node(tree_handler_.file_header_, right_page_handle_); + LeafIndexNodeHandler node(tree_handler_.file_header_, right_frame_); end_index_ = node.size() - 1; } else { @@ -1833,14 +1806,14 @@ RC BplusTreeScanner::open(const char *left_user_key, bool left_inclusive, right_key = tree_handler_.make_key(right_user_key, *RID::min()); } - rc = tree_handler_.find_leaf(right_key, right_page_handle_); + rc = tree_handler_.find_leaf(right_key, right_frame_); if (rc != RC::SUCCESS) { LOG_WARN("failed to find left page. rc=%d:%s", rc, strrc(rc)); tree_handler_.free_key(right_key); return rc; } - LeafIndexNodeHandler right_node(tree_handler_.file_header_, right_page_handle_); + LeafIndexNodeHandler right_node(tree_handler_.file_header_, right_frame_); int right_index = right_node.lookup(tree_handler_.key_comparator_, right_key); tree_handler_.free_key(right_key); // lookup 返回的是适合插入的位置,需要根据实际情况做调整 @@ -1856,14 +1829,14 @@ RC BplusTreeScanner::open(const char *left_user_key, bool left_inclusive, return RC::SUCCESS; } - tree_handler_.disk_buffer_pool_->unpin_page(&right_page_handle_); - rc = tree_handler_.disk_buffer_pool_->get_this_page(tree_handler_.file_id_, prev_page_num, &right_page_handle_); + tree_handler_.disk_buffer_pool_->unpin_page(right_frame_); + rc = tree_handler_.disk_buffer_pool_->get_this_page(prev_page_num, &right_frame_); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch prev page num. page num=%d, rc=%d:%s", prev_page_num, rc, strrc(rc)); return rc; } - LeafIndexNodeHandler tmp_node(tree_handler_.file_header_, right_page_handle_); + LeafIndexNodeHandler tmp_node(tree_handler_.file_header_, right_frame_); right_index = tmp_node.size() - 1; } end_index_ = right_index; @@ -1872,12 +1845,12 @@ RC BplusTreeScanner::open(const char *left_user_key, bool left_inclusive, // 判断是否左边界比右边界要靠后 // 两个边界最多会多一页 // 查找不存在的元素,或者不存在的范围数据时,可能会存在这个问题 - if (left_page_handle_.page_num() == right_page_handle_.page_num() && + if (left_frame_->page_num() == right_frame_->page_num() && iter_index_ > end_index_) { end_index_ = -1; } else { - LeafIndexNodeHandler left_node(tree_handler_.file_header_, left_page_handle_); - LeafIndexNodeHandler right_node(tree_handler_.file_header_, right_page_handle_); + LeafIndexNodeHandler left_node(tree_handler_.file_header_, left_frame_); + LeafIndexNodeHandler right_node(tree_handler_.file_header_, right_frame_); if (left_node.prev_page() == right_node.page_num()) { end_index_ = -1; } @@ -1891,10 +1864,10 @@ RC BplusTreeScanner::next_entry(RID *rid) return RC::RECORD_EOF; } - LeafIndexNodeHandler node(tree_handler_.file_header_, left_page_handle_); + LeafIndexNodeHandler node(tree_handler_.file_header_, left_frame_); memcpy(rid, node.value_at(iter_index_), sizeof(*rid)); - if (left_page_handle_.page_num() == right_page_handle_.page_num() && + if (left_frame_->page_num() == right_frame_->page_num() && iter_index_ == end_index_) { end_index_ = -1; return RC::SUCCESS; @@ -1906,14 +1879,14 @@ RC BplusTreeScanner::next_entry(RID *rid) } RC rc = RC::SUCCESS; - if (left_page_handle_.page_num() != right_page_handle_.page_num()) { + if (left_frame_->page_num() != right_frame_->page_num()) { PageNum page_num = node.next_page(); - tree_handler_.disk_buffer_pool_->unpin_page(&left_page_handle_); + tree_handler_.disk_buffer_pool_->unpin_page(left_frame_); if (page_num == BP_INVALID_PAGE_NUM) { LOG_WARN("got invalid next page. page num=%d", page_num); rc = RC::INTERNAL; } else { - rc = tree_handler_.disk_buffer_pool_->get_this_page(tree_handler_.file_id_, page_num, &left_page_handle_); + rc = tree_handler_.disk_buffer_pool_->get_this_page(page_num, &left_frame_); if (rc != RC::SUCCESS) { LOG_WARN("failed to fetch next page. page num=%d, rc=%d:%s", page_num, rc, strrc(rc)); return rc; @@ -1923,7 +1896,7 @@ RC BplusTreeScanner::next_entry(RID *rid) } } else if (end_index_ != -1) { LOG_WARN("should have more pages but not. left page=%d, right page=%d", - left_page_handle_.page_num(), right_page_handle_.page_num()); + left_frame_->page_num(), right_frame_->page_num()); rc = RC::INTERNAL; } return rc; @@ -1931,11 +1904,11 @@ RC BplusTreeScanner::next_entry(RID *rid) RC BplusTreeScanner::close() { - if (left_page_handle_.open) { - tree_handler_.disk_buffer_pool_->unpin_page(&left_page_handle_); + if (left_frame_ != nullptr) { + tree_handler_.disk_buffer_pool_->unpin_page(left_frame_); } - if (right_page_handle_.open) { - tree_handler_.disk_buffer_pool_->unpin_page(&right_page_handle_); + if (right_frame_ != nullptr) { + tree_handler_.disk_buffer_pool_->unpin_page(right_frame_); } end_index_ = -1; inited_ = false; diff --git a/src/observer/storage/index/bplus_tree.h b/src/observer/storage/index/bplus_tree.h index 3700f40128b9df73178e485ccf03db36de257a9d..91d9d483fbf13598f147dc36349e79ce3144e90d 100644 --- a/src/observer/storage/index/bplus_tree.h +++ b/src/observer/storage/index/bplus_tree.h @@ -19,6 +19,7 @@ See the Mulan PSL v2 for more details. */ #include #include +#include #include "storage/common/record_manager.h" #include "storage/default/disk_buffer_pool.h" @@ -244,17 +245,17 @@ struct InternalIndexNode : public IndexNode { class IndexNodeHandler { public: - IndexNodeHandler(const IndexFileHeader &header, BPPageHandle &page_handle); + IndexNodeHandler(const IndexFileHeader &header, Frame *frame); void init_empty(bool leaf); bool is_leaf() const; - int key_size() const; - int value_size() const; - int item_size() const; + int key_size() const; + int value_size() const; + int item_size() const; void increase_size(int n); - int size() const; + int size() const; void set_parent_page_num(PageNum page_num); PageNum parent_page_num() const; @@ -272,7 +273,7 @@ protected: class LeafIndexNodeHandler : public IndexNodeHandler { public: - LeafIndexNodeHandler(const IndexFileHeader &header, BPPageHandle &page_handle); + LeafIndexNodeHandler(const IndexFileHeader &header, Frame *frame); void init_empty(); void set_next_page(PageNum page_num); @@ -293,18 +294,18 @@ public: void insert(int index, const char *key, const char *value); void remove(int index); int remove(const char *key, const KeyComparator &comparator); - RC move_half_to(LeafIndexNodeHandler &other, DiskBufferPool *bp, int file_id); - RC move_first_to_end(LeafIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool, int file_id); - RC move_last_to_front(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); + RC move_last_to_front(LeafIndexNodeHandler &other, DiskBufferPool *bp); /** * 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 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); private: @@ -321,20 +322,20 @@ private: class InternalIndexNodeHandler : public IndexNodeHandler { public: - InternalIndexNodeHandler(const IndexFileHeader &header, BPPageHandle &page_handle); + InternalIndexNodeHandler(const IndexFileHeader &header, Frame *frame); void init_empty(); 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); - RC move_half_to(LeafIndexNodeHandler &other, DiskBufferPool *bp, int file_id); + RC move_half_to(LeafIndexNodeHandler &other, DiskBufferPool *bp); char *key_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 remove(int index); @@ -349,18 +350,18 @@ public: int max_size() const; int min_size() const; - RC move_to(InternalIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool, int file_id); - RC move_first_to_end(InternalIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool, int file_id); - RC move_last_to_front(InternalIndexNodeHandler &other, DiskBufferPool *bp, int file_id); - RC move_half_to(InternalIndexNodeHandler &other, DiskBufferPool *bp, int file_id); + RC move_to(InternalIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool); + RC move_first_to_end(InternalIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool); + RC move_last_to_front(InternalIndexNodeHandler &other, DiskBufferPool *bp); + 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); private: - RC copy_from(const char *items, int num, DiskBufferPool *disk_buffer_pool, int file_id); - RC append(const char *item, DiskBufferPool *bp, int file_id); - RC preappend(const char *item, DiskBufferPool *bp, int file_id); + RC copy_from(const char *items, int num, DiskBufferPool *disk_buffer_pool); + RC append(const char *item, DiskBufferPool *bp); + RC preappend(const char *item, DiskBufferPool *bp); private: char *__item_at(int index) const; @@ -418,11 +419,6 @@ public: RC sync(); - const int get_file_id() - { - return file_id_; - } - /** * Check whether current B+ tree is invalid or not. * return true means current tree is valid, return false means current tree is invalid. @@ -435,52 +431,48 @@ public: RC print_leafs(); private: - RC print_leaf(BPPageHandle &page_handle); - RC print_internal_node_recursive(BPPageHandle &page_handle); + RC print_leaf(Frame *frame); + RC print_internal_node_recursive(Frame *frame); bool validate_node(IndexNode *node); bool validate_leaf_link(); - bool validate_node_recursive(BPPageHandle &page_handle); + bool validate_node_recursive(Frame *frame); protected: - RC find_leaf(const char *key, BPPageHandle &page_handle); - RC left_most_page(BPPageHandle &page_handle); - RC right_most_page(BPPageHandle &page_handle); + RC find_leaf(const char *key, Frame *&frame); + RC left_most_page(Frame *&frame); + RC right_most_page(Frame *&frame); RC find_leaf_internal(const std::function &child_page_getter, - BPPageHandle &page_handle); + Frame *&frame); RC insert_into_parent( - PageNum parent_page, BPPageHandle &left_page_handle, const char *pkey, BPPageHandle &right_page_handle); - RC split_leaf(BPPageHandle &leaf_page_handle); + PageNum parent_page, Frame *left_frame, const char *pkey, Frame &right_frame); - 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 - RC split(BPPageHandle &page_handle, BPPageHandle &new_page_handle); + RC split(Frame *frame, Frame *&new_frame); template - RC coalesce_or_redistribute(BPPageHandle &page_handle); + RC coalesce_or_redistribute(Frame *frame); template - RC coalesce(BPPageHandle &neighbor_page_handle, BPPageHandle &page_handle, - BPPageHandle &parent_page_handle, int index); + RC coalesce(Frame *neighbor_frame, Frame *frame, Frame *parent_frame, int index); template - RC redistribute(BPPageHandle &neighbor_page_handle, BPPageHandle &page_handle, - BPPageHandle &parent_page_handle, int index); + RC redistribute(Frame *neighbor_frame, Frame *frame, Frame *parent_frame, int index); - RC insert_entry_into_parent(BPPageHandle &page_handle, BPPageHandle &new_page_handle, const char *key); - RC insert_entry_into_leaf_node(BPPageHandle &page_handle, const char *pkey, const RID *rid); + RC insert_entry_into_parent(Frame *frame, Frame *new_frame, const char *key); + RC insert_entry_into_leaf_node(Frame *frame, const char *pkey, const RID *rid); RC update_root_page_num(); RC create_new_tree(const char *key, const RID *rid); - RC adjust_root(BPPageHandle &root_page_handle); + RC adjust_root(Frame *root_frame); private: char *make_key(const char *user_key, const RID &rid); void free_key(char *key); protected: DiskBufferPool *disk_buffer_pool_ = nullptr; - int file_id_ = -1; bool header_dirty_ = false; IndexFileHeader file_header_; @@ -519,10 +511,10 @@ private: /// 使用左右叶子节点和位置来表示扫描的起始位置和终止位置 /// 起始位置和终止位置都是有效的数据 - BPPageHandle left_page_handle_; - BPPageHandle right_page_handle_; - int iter_index_ = -1; - int end_index_ = -1; // use -1 for end of scan + Frame * left_frame_ = nullptr; + Frame * right_frame_ = nullptr; + int iter_index_ = -1; + int end_index_ = -1; // use -1 for end of scan }; #endif //__OBSERVER_STORAGE_COMMON_INDEX_MANAGER_H_ diff --git a/src/observer/storage/index/bplus_tree_index.cpp b/src/observer/storage/index/bplus_tree_index.cpp index 36ccf3c43c0bfda5ad8300752a348ee3b8ab94f4..ea69bcc0746872317ef583b05d3d1b707a5ccbb7 100644 --- a/src/observer/storage/index/bplus_tree_index.cpp +++ b/src/observer/storage/index/bplus_tree_index.cpp @@ -79,10 +79,8 @@ RC BplusTreeIndex::open(const char *file_name, const IndexMeta &index_meta, cons RC BplusTreeIndex::close() { if (inited_) { - LOG_INFO("Begin to close index, file_id:%d, index:%s, field:%s", - index_handler_.get_file_id(), - index_meta_.name(), - index_meta_.field()); + LOG_INFO("Begin to close index, index:%s, field:%s", + index_meta_.name(), index_meta_.field()); index_handler_.close(); inited_ = false; } diff --git a/unitest/bp_manager_test.cpp b/unitest/bp_manager_test.cpp index 6fe40b4ffcdf7eec7516bfbc662af887ec584d3f..cef9d4310ebbd66d414ca4cbe48c1549953dec06 100644 --- a/unitest/bp_manager_test.cpp +++ b/unitest/bp_manager_test.cpp @@ -15,68 +15,68 @@ See the Mulan PSL v2 for more details. */ #include "storage/default/disk_buffer_pool.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); - frame1->file_desc = 0; - frame1->page.page_num = 1; + frame1->set_file_desc(0); + 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); - frame2->file_desc = 0; - frame2->page.page_num = 2; + frame2->set_file_desc(0); + 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); - frame3->file_desc = 0; - frame3->page.page_num = 3; + frame3->set_file_desc(0); + frame3->set_page_num(3); - frame2 = bp_manager.get(0, 2); + frame2 = frame_manager.get(0, 2); ASSERT_NE(frame2, nullptr); - Frame *frame4 = bp_manager.alloc(); - frame4->file_desc = 0; - frame4->page.page_num = 4; + Frame *frame4 = frame_manager.alloc(); + frame4->set_file_desc(0); + frame4->set_page_num(4); - bp_manager.free(frame1); - frame1 = bp_manager.get(0, 1); + frame_manager.free(frame1); + frame1 = frame_manager.get(0, 1); 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); - bp_manager.free(frame3); - bp_manager.free(frame4); + frame_manager.free(frame2); + frame_manager.free(frame3); + frame_manager.free(frame4); - ASSERT_EQ(nullptr, bp_manager.get(0, 2)); - ASSERT_EQ(nullptr, bp_manager.get(0, 3)); - ASSERT_EQ(nullptr, bp_manager.get(0, 4)); + ASSERT_EQ(nullptr, frame_manager.get(0, 2)); + ASSERT_EQ(nullptr, frame_manager.get(0, 3)); + 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 used_list; for (int i = 0; i < size; i++) { - Frame *item = bp_manager.alloc(); + Frame *item = frame_manager.alloc(); ASSERT_NE(item, nullptr); 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++) { - Frame *item = bp_manager.alloc(); + Frame *item = frame_manager.alloc(); ASSERT_EQ(item, nullptr); } @@ -86,26 +86,26 @@ void test_alloc(BPManager &bp_manager) Frame *item = used_list.front(); used_list.pop_front(); - bp_manager.free(item); + frame_manager.free(item); } else { - Frame *item = bp_manager.alloc(); + Frame *item = frame_manager.alloc(); 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"); - bp_manager.init(false, 2); + BPFrameManager frame_manager("Test"); + 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) @@ -117,4 +117,4 @@ int main(int argc, char **argv) // 调用RUN_ALL_TESTS()运行所有测试用例 // main函数返回RUN_ALL_TESTS()的运行结果 return RUN_ALL_TESTS(); -} \ No newline at end of file +} diff --git a/unitest/bplus_tree_test.cpp b/unitest/bplus_tree_test.cpp index 0af06ff58fa054dcf9bf0d23537fab519493a427..5fa48fd2c90c4cf43a54f98eec9b11cfa3392795 100644 --- a/unitest/bplus_tree_test.cpp +++ b/unitest/bplus_tree_test.cpp @@ -321,20 +321,11 @@ TEST(test_bplus_tree, test_leaf_index_node_handle) index_file_header.attr_type = INTS; 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; key_comparator.init(INTS, 4); - LeafIndexNodeHandler leaf_node(index_file_header, page_handle); + LeafIndexNodeHandler leaf_node(index_file_header, &frame); leaf_node.init_empty(); ASSERT_EQ(0, leaf_node.size()); @@ -389,20 +380,11 @@ TEST(test_bplus_tree, test_internal_index_node_handle) index_file_header.attr_type = INTS; 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; key_comparator.init(INTS, 4); - InternalIndexNodeHandler internal_node(index_file_header, page_handle); + InternalIndexNodeHandler internal_node(index_file_header, &frame); internal_node.init_empty(); ASSERT_EQ(0, internal_node.size()); @@ -480,8 +462,6 @@ TEST(test_bplus_tree, test_scanner) { LoggerFactory::init_default("test.log"); - DiskBufferPool::set_pool_num(POOL_NUM); - const char *index_name = "scanner.btree"; ::remove(index_name); handler = new BplusTreeHandler(); @@ -689,10 +669,7 @@ TEST(test_bplus_tree, test_scanner) TEST(test_bplus_tree, test_bplus_tree_insert) { - 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); handler = new BplusTreeHandler();