From 88ca5bca2b3d351d1ebf87ef5a1c1ad4d8c8eed8 Mon Sep 17 00:00:00 2001 From: Koschei <nitianzero@gmail.com> Date: Wed, 26 Jun 2024 12:29:47 +0800 Subject: [PATCH] fix: resolve memory leaks --- src/index/ix_index_handle.cpp | 67 +++++++++++++------------ src/index/ix_index_handle.h | 36 +++++++------ src/index/ix_manager.h | 13 +++-- src/index/ix_scan.cpp | 2 +- src/rmdb.cpp | 21 ++++++-- src/transaction/transaction_manager.cpp | 2 + src/transaction/transaction_manager.h | 12 ++++- 7 files changed, 95 insertions(+), 58 deletions(-) diff --git a/src/index/ix_index_handle.cpp b/src/index/ix_index_handle.cpp index b7a2821..7f336d4 100644 --- a/src/index/ix_index_handle.cpp +++ b/src/index/ix_index_handle.cpp @@ -240,6 +240,7 @@ IxIndexHandle::IxIndexHandle(DiskManager *disk_manager, BufferPoolManager *buffe disk_manager_->read_page(fd, IX_FILE_HDR_PAGE, buf, PAGE_SIZE); file_hdr_ = new IxFileHdr(); file_hdr_->deserialize(buf); + delete []buf; // disk_manager管ç†çš„fd对应的文件ä¸ï¼Œè®¾ç½®ä»Žfile_hdr_->num_pages开始分é…page_no // int now_page_no = disk_manager_->get_fd2pageno(fd); @@ -255,8 +256,9 @@ IxIndexHandle::IxIndexHandle(DiskManager *disk_manager, BufferPoolManager *buffe * @note need to Unlatch and unpin the leaf node outside! * 注æ„:用了FindLeafPage之åŽä¸€å®šè¦unlatchå¶ç»“点,å¦åˆ™ä¸‹æ¬¡latchè¯¥ç»“ç‚¹ä¼šå µå¡žï¼ */ -std::pair<IxNodeHandle *, bool> IxIndexHandle::find_leaf_page(const char *key, Operation operation, - Transaction *transaction, bool find_first) { +std::pair<std::shared_ptr<IxNodeHandle>, bool> IxIndexHandle::find_leaf_page(const char *key, Operation operation, + Transaction *transaction, + bool find_first) { // Todo: // 1. èŽ·å–æ ¹èŠ‚ç‚¹ // 2. ä»Žæ ¹èŠ‚ç‚¹å¼€å§‹ä¸æ–å‘ä¸‹æŸ¥æ‰¾ç›®æ ‡key @@ -338,14 +340,14 @@ bool IxIndexHandle::get_value(const char *key, std::vector<Rid> *result, Transac * @note need to unpin the new node outside * 注æ„:本函数执行完毕åŽï¼ŒåŽŸnodeå’Œnew node都需è¦åœ¨å‡½æ•°å¤–é¢è¿›è¡Œunpin */ -IxNodeHandle *IxIndexHandle::split(IxNodeHandle *node) { +std::shared_ptr<IxNodeHandle> IxIndexHandle::split(std::shared_ptr<IxNodeHandle> &node) { // Todo: // 1. 将原结点的键值对平å‡åˆ†é…,å³åŠéƒ¨åˆ†åˆ†è£‚为新的å³å…„弟结点 // 需è¦åˆå§‹åŒ–新节点的page_hdr内容 // 2. 如果新的å³å…„弟结点是å¶å结点,更新新旧节点的prev_leafå’Œnext_leaf指针 // 为新节点分é…键值对,更新旧节点的键值对数记录 // 3. 如果新的å³å…„å¼Ÿç»“ç‚¹ä¸æ˜¯å¶å结点,更新该结点的所有å©å结点的父节点信æ¯(使用IxIndexHandle::maintain_child()) - auto &&new_sibling_node = create_node(); + auto new_sibling_node = create_node(); new_sibling_node->page->WLatch(); auto &&split_point = node->get_min_size(); if (node->is_leaf_page()) { @@ -393,8 +395,8 @@ IxNodeHandle *IxIndexHandle::split(IxNodeHandle *node) { * å³åŠéƒ¨åˆ†çš„键值对分裂为新的å³å…„å¼ŸèŠ‚ç‚¹ï¼Œåœ¨å‚æ•°ä¸ç§°ä¸ºnew_node(å‚考Split函数æ¥ç†è§£old_nodeå’Œnew_node) * @note 本函数执行完毕åŽï¼Œnew nodeå’Œold node都需è¦åœ¨å‡½æ•°å¤–é¢è¿›è¡Œunpin */ -void IxIndexHandle::insert_into_parent(IxNodeHandle *old_node, const char *key, IxNodeHandle *new_node, - Transaction *transaction) { +void IxIndexHandle::insert_into_parent(std::shared_ptr<IxNodeHandle> &old_node, const char *key, + std::shared_ptr<IxNodeHandle> &new_node, Transaction *transaction) { // Todo: // 1. 分裂å‰çš„结点(原结点, old_node)是å¦ä¸ºæ ¹ç»“ç‚¹ï¼Œå¦‚æžœä¸ºæ ¹ç»“ç‚¹éœ€è¦åˆ†é…æ–°çš„root // 2. 获å–原结点(old_node)的父亲结点 @@ -569,8 +571,8 @@ bool IxIndexHandle::delete_entry(const char *key, Transaction *transaction) { } if (transaction != nullptr) { // for (auto &page: *transaction->get_index_deleted_page_set()) { - // assert(page->get_pin_count() == 0); - // assert(buffer_pool_manager_->delete_page(page->get_page_id())); + // assert(page->get_pin_count() == 0); + // assert(buffer_pool_manager_->delete_page(page->get_page_id())); // } transaction->get_index_deleted_page_set()->clear(); } @@ -583,7 +585,7 @@ bool IxIndexHandle::delete_entry(const char *key, Transaction *transaction) { * @return bool æ ¹ç»“ç‚¹æ˜¯å¦éœ€è¦è¢«åˆ 除 * @note size of root page can be less than min size and this method is only called within coalesce_or_redistribute() */ -bool IxIndexHandle::adjust_root(IxNodeHandle *old_root_node) { +bool IxIndexHandle::adjust_root(std::shared_ptr<IxNodeHandle> &old_root_node) { // Todo: // 1. 如果old_root_node是内部结点,并且大å°ä¸º1,则直接把它的å©åæ›´æ–°æˆæ–°çš„æ ¹ç»“点 // 2. 如果old_root_node是å¶ç»“点,且大å°ä¸º0,则直接更新root page @@ -626,7 +628,8 @@ bool IxIndexHandle::adjust_root(IxNodeHandle *old_root_node) { * index>0,则neighbor是nodeå‰é©±ç»“点,表示:neighbor(left) node(right) * æ³¨æ„æ›´æ–°parent结点的相关kv对 */ -void IxIndexHandle::redistribute(IxNodeHandle *neighbor_node, IxNodeHandle *node, IxNodeHandle *parent, int index) { +void IxIndexHandle::redistribute(std::shared_ptr<IxNodeHandle> &neighbor_node, std::shared_ptr<IxNodeHandle> &node, + std::shared_ptr<IxNodeHandle> &parent, int index) { // Todo: // 1. 通过index判æ–neighbor_node是å¦ä¸ºnodeçš„å‰é©±ç»“点 // 2. 从neighbor_nodeä¸ç§»åŠ¨ä¸€ä¸ªé”®å€¼å¯¹åˆ°nodeç»“ç‚¹ä¸ @@ -668,7 +671,8 @@ void IxIndexHandle::redistribute(IxNodeHandle *neighbor_node, IxNodeHandle *node * @return true means parent node should be deleted, false means no deletion happend * @note Assume that *neighbor_node is the left sibling of *node (neighbor -> node) */ -bool IxIndexHandle::coalesce(IxNodeHandle **neighbor_node, IxNodeHandle **node, IxNodeHandle **parent, int index, +bool IxIndexHandle::coalesce(std::shared_ptr<IxNodeHandle> *neighbor_node, std::shared_ptr<IxNodeHandle> *node, + std::shared_ptr<IxNodeHandle> *parent, int index, Transaction *transaction, bool *root_is_latched) { // Todo: // 1. 用index判æ–neighbor_node是å¦ä¸ºnodeçš„å‰é©±ç»“ç‚¹ï¼Œè‹¥ä¸æ˜¯åˆ™äº¤æ¢ä¸¤ä¸ªç»“点,让neighbor_node作为左结点,node作为å³ç»“点 @@ -720,7 +724,8 @@ bool IxIndexHandle::coalesce(IxNodeHandle **neighbor_node, IxNodeHandle **node, * If sibling's size + input page's size >= 2 * page's minsize, then redistribute. * Otherwise, merge(Coalesce). */ -bool IxIndexHandle::coalesce_or_redistribute(IxNodeHandle *node, Transaction *transaction, bool *root_is_latched) { +bool IxIndexHandle::coalesce_or_redistribute(std::shared_ptr<IxNodeHandle> &node, Transaction *transaction, + bool *root_is_latched) { // Todo: // 1. 判æ–node结点是å¦ä¸ºæ ¹èŠ‚ç‚¹ // 1.1 å¦‚æžœæ˜¯æ ¹èŠ‚ç‚¹ï¼Œéœ€è¦è°ƒç”¨AdjustRoot() 函数æ¥è¿›è¡Œå¤„ç†ï¼Œè¿”å›žæ ¹èŠ‚ç‚¹æ˜¯å¦éœ€è¦è¢«åˆ 除 @@ -793,7 +798,7 @@ bool IxIndexHandle::coalesce_or_redistribute(IxNodeHandle *node, Transaction *tr * @note iidå’Œridå˜çš„䏿˜¯ä¸€ä¸ªä¸œè¥¿ï¼Œridæ˜¯ä¸Šå±‚ä¼ è¿‡æ¥çš„记录ä½ç½®ï¼Œiid是索引内部生æˆçš„索引槽ä½ç½® */ Rid IxIndexHandle::get_rid(const Iid &iid) const { - IxNodeHandle *node = fetch_node(iid.page_no); + auto node = fetch_node(iid.page_no); if (iid.slot_no >= node->get_size()) { throw IndexEntryNotFoundError(); } @@ -866,7 +871,7 @@ Iid IxIndexHandle::upper_bound(const char *key) { * @return Iid */ Iid IxIndexHandle::leaf_end() const { - IxNodeHandle *node = fetch_node(file_hdr_->last_leaf_); + auto node = fetch_node(file_hdr_->last_leaf_); Iid iid = {.page_no = file_hdr_->last_leaf_, .slot_no = node->get_size()}; buffer_pool_manager_->unpin_page(node->get_page_id(), false); // unpin it! return iid; @@ -890,10 +895,9 @@ Iid IxIndexHandle::leaf_begin() const { * @return IxNodeHandle* * @note pin the page, remember to unpin it outside! */ -IxNodeHandle *IxIndexHandle::fetch_node(int page_no) const { - Page *page = buffer_pool_manager_->fetch_page({fd_, page_no}); - IxNodeHandle *node = new IxNodeHandle(file_hdr_, page); - return node; +std::shared_ptr<IxNodeHandle> IxIndexHandle::fetch_node(int page_no) const { + auto *page = buffer_pool_manager_->fetch_page({fd_, page_no}); + return std::make_shared<IxNodeHandle>(file_hdr_, page); } /** @@ -906,15 +910,12 @@ IxNodeHandle *IxIndexHandle::fetch_node(int page_no) const { * 在最开始æ’入时,一直是create node,那么first_page_no一直没å˜ï¼Œä¸€ç›´æ˜¯IX_NO_PAGE * 与Record的处ç†ä¸åŒï¼ŒRecord将未æ’入满的记录页认为是free_page */ -IxNodeHandle *IxIndexHandle::create_node() { - IxNodeHandle *node; - file_hdr_->num_pages_++; - +std::shared_ptr<IxNodeHandle> IxIndexHandle::create_node() { + ++file_hdr_->num_pages_; PageId new_page_id = {.fd = fd_, .page_no = INVALID_PAGE_ID}; // 从3开始分é…page_no,第一次分é…之åŽï¼Œnew_page_id.page_no=3,file_hdr_.num_pages=4 - Page *page = buffer_pool_manager_->new_page(&new_page_id); - node = new IxNodeHandle(file_hdr_, page); - return node; + auto *page = buffer_pool_manager_->new_page(&new_page_id); + return std::make_shared<IxNodeHandle>(file_hdr_, page); } /** @@ -922,11 +923,11 @@ IxNodeHandle *IxIndexHandle::create_node() { * * @param node */ -void IxIndexHandle::maintain_parent(IxNodeHandle *node) { - IxNodeHandle *curr = node; +void IxIndexHandle::maintain_parent(std::shared_ptr<IxNodeHandle> &node) { + auto curr = node; while (curr->get_parent_page_no() != IX_NO_PAGE) { // Load its parent - IxNodeHandle *parent = fetch_node(curr->get_parent_page_no()); + auto parent = fetch_node(curr->get_parent_page_no()); int rank = parent->find_child(curr); char *parent_key = parent->get_key(rank); char *child_first_key = curr->get_key(0); @@ -945,14 +946,14 @@ void IxIndexHandle::maintain_parent(IxNodeHandle *node) { * * @param leaf è¦åˆ 除的leaf */ -void IxIndexHandle::erase_leaf(IxNodeHandle *leaf) { +void IxIndexHandle::erase_leaf(std::shared_ptr<IxNodeHandle> &leaf) { assert(leaf->is_leaf_page()); - IxNodeHandle *prev = fetch_node(leaf->get_prev_leaf()); + auto prev = fetch_node(leaf->get_prev_leaf()); prev->set_next_leaf(leaf->get_next_leaf()); buffer_pool_manager_->unpin_page(prev->get_page_id(), true); - IxNodeHandle *next = fetch_node(leaf->get_next_leaf()); + auto next = fetch_node(leaf->get_next_leaf()); next->set_prev_leaf(leaf->get_prev_leaf()); // æ³¨æ„æ¤å¤„是SetPrevLeaf() buffer_pool_manager_->unpin_page(next->get_page_id(), true); } @@ -969,11 +970,11 @@ void IxIndexHandle::release_node_handle(IxNodeHandle &node) { /** * @brief å°†node的第child_idx个å©å结点的父节点置为node */ -void IxIndexHandle::maintain_child(IxNodeHandle *node, int child_idx) { +void IxIndexHandle::maintain_child(std::shared_ptr<IxNodeHandle> &node, int child_idx) { if (!node->is_leaf_page()) { // Current node is inner node, load its child and set its parent to current node int child_page_no = node->value_at(child_idx); - IxNodeHandle *child = fetch_node(child_page_no); + auto child = fetch_node(child_page_no); child->set_parent_page_no(node->get_page_no()); buffer_pool_manager_->unpin_page(child->get_page_id(), true); } diff --git a/src/index/ix_index_handle.h b/src/index/ix_index_handle.h index c249c8c..e5632ef 100644 --- a/src/index/ix_index_handle.h +++ b/src/index/ix_index_handle.h @@ -161,7 +161,7 @@ public: * @param child * @return int */ - int find_child(IxNodeHandle *child) { + int find_child(std::shared_ptr<IxNodeHandle> child) { // TODO:优化为什么ä¸äºŒåˆ† int rid_idx; for (rid_idx = 0; rid_idx < page_hdr->num_key; rid_idx++) { @@ -219,11 +219,16 @@ private: public: IxIndexHandle(DiskManager *disk_manager, BufferPoolManager *buffer_pool_manager, int fd); + ~IxIndexHandle() { + delete file_hdr_; + } + // for search bool get_value(const char *key, std::vector<Rid> *result, Transaction *transaction); - std::pair<IxNodeHandle *, bool> find_leaf_page(const char *key, Operation operation, Transaction *transaction, - bool find_first = false); + std::pair<std::shared_ptr<IxNodeHandle>, bool> find_leaf_page(const char *key, Operation operation, + Transaction *transaction, + bool find_first = false); // check unique bool is_unique(const char *key, Rid &value, Transaction *transaction); @@ -231,21 +236,24 @@ public: // for insert page_id_t insert_entry(const char *key, const Rid &value, Transaction *transaction); - IxNodeHandle *split(IxNodeHandle *node); + std::shared_ptr<IxNodeHandle> split(std::shared_ptr<IxNodeHandle> &node); - void insert_into_parent(IxNodeHandle *old_node, const char *key, IxNodeHandle *new_node, Transaction *transaction); + void insert_into_parent(std::shared_ptr<IxNodeHandle> &old_node, const char *key, + std::shared_ptr<IxNodeHandle> &new_node, Transaction *transaction); // for delete bool delete_entry(const char *key, Transaction *transaction); - bool coalesce_or_redistribute(IxNodeHandle *node, Transaction *transaction = nullptr, + bool coalesce_or_redistribute(std::shared_ptr<IxNodeHandle> &node, Transaction *transaction = nullptr, bool *root_is_latched = nullptr); - bool adjust_root(IxNodeHandle *old_root_node); + bool adjust_root(std::shared_ptr<IxNodeHandle> &old_root_node); - void redistribute(IxNodeHandle *neighbor_node, IxNodeHandle *node, IxNodeHandle *parent, int index); + void redistribute(std::shared_ptr<IxNodeHandle> &neighbor_node, std::shared_ptr<IxNodeHandle> &node, + std::shared_ptr<IxNodeHandle> &parent, int index); - bool coalesce(IxNodeHandle **neighbor_node, IxNodeHandle **node, IxNodeHandle **parent, int index, + bool coalesce(std::shared_ptr<IxNodeHandle> *neighbor_node, std::shared_ptr<IxNodeHandle> *node, + std::shared_ptr<IxNodeHandle> *parent, int index, Transaction *transaction, bool *root_is_latched); Iid lower_bound(const char *key); @@ -263,18 +271,18 @@ private: bool is_empty() const { return file_hdr_->root_page_ == IX_NO_PAGE; } // for get/create node - IxNodeHandle *fetch_node(int page_no) const; + std::shared_ptr<IxNodeHandle> fetch_node(int page_no) const; - IxNodeHandle *create_node(); + std::shared_ptr<IxNodeHandle> create_node(); // for maintain data structure - void maintain_parent(IxNodeHandle *node); + void maintain_parent(std::shared_ptr<IxNodeHandle> &node); - void erase_leaf(IxNodeHandle *leaf); + void erase_leaf(std::shared_ptr<IxNodeHandle> &leaf); void release_node_handle(IxNodeHandle &node); - void maintain_child(IxNodeHandle *node, int child_idx); + void maintain_child(std::shared_ptr<IxNodeHandle> &node, int child_idx); // for index test Rid get_rid(const Iid &iid) const; diff --git a/src/index/ix_manager.h b/src/index/ix_manager.h index 4b315d7..6b4dd38 100644 --- a/src/index/ix_manager.h +++ b/src/index/ix_manager.h @@ -30,7 +30,7 @@ public: std::string get_index_name(const std::string &filename, const std::vector<std::string> &index_cols) { std::ostringstream oss; oss << filename; - for (const auto &col : index_cols) { + for (const auto &col: index_cols) { oss << "_" << col; } oss << ".idx"; @@ -40,7 +40,7 @@ public: std::string get_index_name(const std::string &filename, const std::vector<ColMeta> &index_cols) { std::ostringstream oss; oss << filename; - for (const auto &col : index_cols) { + for (const auto &col: index_cols) { oss << "_" << col.name; } oss << ".idx"; @@ -61,7 +61,7 @@ public: return disk_manager_->is_file(index_name); } - void create_index(const std::string &ix_name, const std::vector<ColMeta>& index_cols) { + void create_index(const std::string &ix_name, const std::vector<ColMeta> &index_cols) { // Create index file disk_manager_->create_file(ix_name); // Open index file @@ -89,8 +89,8 @@ public: col_num, col_tot_len, btree_order, (btree_order + 1) * col_tot_len, IX_INIT_ROOT_PAGE, IX_INIT_ROOT_PAGE); for (int i = 0; i < col_num; ++i) { - fhdr->col_types_.push_back(index_cols[i].type); - fhdr->col_lens_.push_back(index_cols[i].len); + fhdr->col_types_.emplace_back(index_cols[i].type); + fhdr->col_lens_.emplace_back(index_cols[i].len); } fhdr->update_tot_len(); @@ -99,6 +99,9 @@ public: disk_manager_->write_page(fd, IX_FILE_HDR_PAGE, data, fhdr->tot_len_); + delete fhdr; + delete []data; + char page_buf[PAGE_SIZE]; // 在内å˜ä¸åˆå§‹åŒ–page_bufä¸çš„内容,然åŽå°†å…¶å†™å…¥ç£ç›˜ memset(page_buf, 0, PAGE_SIZE); // 注æ„leaf header页å·ä¸º1ï¼Œä¹Ÿæ ‡è®°ä¸ºå¶å结点,其å‰ä¸€ä¸ª/åŽä¸€ä¸ªå¶å凿Œ‡å‘root node diff --git a/src/index/ix_scan.cpp b/src/index/ix_scan.cpp index f737276..a65dc76 100644 --- a/src/index/ix_scan.cpp +++ b/src/index/ix_scan.cpp @@ -16,7 +16,7 @@ See the Mulan PSL v2 for more details. */ */ void IxScan::next() { assert(!is_end()); - IxNodeHandle *node = ih_->fetch_node(iid_.page_no); + auto &&node = ih_->fetch_node(iid_.page_no); assert(node->is_leaf_page()); assert(iid_.slot_no < node->get_size()); // increment slot no diff --git a/src/rmdb.cpp b/src/rmdb.cpp index fa42f6f..4b54a0e 100644 --- a/src/rmdb.cpp +++ b/src/rmdb.cpp @@ -71,6 +71,7 @@ void SetTransaction(txn_id_t *txn_id, Context *context) { void *client_handler(void *sock_fd) { int fd = *((int *) sock_fd); + free(sock_fd); pthread_mutex_unlock(sockfd_mutex); int i_recvBytes; @@ -112,6 +113,9 @@ void *client_handler(void *sock_fd) { if (strcmp(data_recv, "crash") == 0) { std::cout << "Server crash" << std::endl; delete []data_send; + for (auto &[_, txn]: txn_manager->txn_map) { + delete txn; + } exit(1); } @@ -250,25 +254,31 @@ void start_server() { while (!should_exit) { std::cout << "Waiting for new connection..." << std::endl; + // 解决局部å˜é‡æžæž„问题 + int *sockfd = (int *) malloc(sizeof(int)); + pthread_t thread_id; struct sockaddr_in s_addr_client{}; int client_length = sizeof(s_addr_client); if (setjmp(jmpbuf)) { + free(sockfd); std::cout << "Break from Server Listen Loop\n"; break; } // Block here. Until server accepts a new connection. pthread_mutex_lock(sockfd_mutex); - int sockfd = accept(sockfd_server, (struct sockaddr *) (&s_addr_client), (socklen_t *) (&client_length)); - if (sockfd == -1) { + *sockfd = accept(sockfd_server, (struct sockaddr *) (&s_addr_client), (socklen_t *) (&client_length)); + if (*sockfd == -1) { + free(sockfd); std::cout << "Accept error!" << std::endl; continue; // ignore current socket ,continue while loop. } // 和客户端建立连接,并开å¯ä¸€ä¸ªçº¿ç¨‹è´Ÿè´£å¤„ç†å®¢æˆ·ç«¯è¯·æ±‚ - if (pthread_create(&thread_id, nullptr, &client_handler, (void *) (&sockfd)) != 0) { + if (pthread_create(&thread_id, nullptr, &client_handler, (void *) (sockfd)) != 0) { + free(sockfd); std::cout << "Create thread fail!" << std::endl; break; // break while loop } @@ -280,6 +290,11 @@ void start_server() { if (ret == -1) { printf("%s\n", strerror(errno)); } // assert(ret != -1); sm_manager->close_db(); + + for (auto &[_, txn]: txn_manager->txn_map) { + delete txn; + } + std::cout << " DB has been closed.\n"; std::cout << "Server shuts down." << std::endl; } diff --git a/src/transaction/transaction_manager.cpp b/src/transaction/transaction_manager.cpp index 63f2361..9e5df52 100644 --- a/src/transaction/transaction_manager.cpp +++ b/src/transaction/transaction_manager.cpp @@ -182,7 +182,9 @@ void TransactionManager::abort(Transaction *txn, LogManager *log_manager) { } delete write_record; } + delete context; write_set->clear(); + // é‡Šæ”¾æ‰€æœ‰é” auto &&lock_set = txn->get_lock_set(); for (auto &it: *lock_set) { diff --git a/src/transaction/transaction_manager.h b/src/transaction/transaction_manager.h index 7f9bc5c..2e58af2 100644 --- a/src/transaction/transaction_manager.h +++ b/src/transaction/transaction_manager.h @@ -50,14 +50,22 @@ public: * @param {txn_id_t} txn_id 事务ID */ Transaction *get_transaction(txn_id_t txn_id) { - if (txn_id == INVALID_TXN_ID) return nullptr; + if (txn_id == INVALID_TXN_ID) { + return nullptr; + } - std::unique_lock<std::mutex> lock(latch_); + std::unique_lock lock(latch_); if (txn_map.find(txn_id) == txn_map.end()) { return nullptr; } auto *res = txn_map[txn_id]; + if (res->get_state() == TransactionState::COMMITTED || res->get_state() == TransactionState::ABORTED) { + delete res; + txn_map.erase(txn_id); + return nullptr; + } + lock.unlock(); assert(res != nullptr); assert(res->get_thread_id() == std::this_thread::get_id()); -- GitLab