diff --git a/src/catalog/simple_catalog.cpp b/src/catalog/simple_catalog.cpp index 50cc73c..a698b94 100644 --- a/src/catalog/simple_catalog.cpp +++ b/src/catalog/simple_catalog.cpp @@ -97,7 +97,8 @@ void SimpleCatalog::CreateTable(const std::string &table_name, const ColumnList Disk::CreateFile(Disk::GetFilePath(db_oid, oid)); } name2oid_[table_name] = oid; - oid2table_[oid] = std::make_shared(buffer_pool_, log_manager_, oid, db_oid, column_list, new_table); + oid2table_[oid] = std::make_shared
(buffer_pool_, log_manager_, oid, db_oid, column_list, new_table, + Disk::EmptyFile(Disk::GetFilePath(db_oid, oid))); // 检查:非新表不需要添加到Meta中 if (!new_table) { diff --git a/src/catalog/system_catalog.cpp b/src/catalog/system_catalog.cpp index 2073f2b..04cb47f 100644 --- a/src/catalog/system_catalog.cpp +++ b/src/catalog/system_catalog.cpp @@ -195,7 +195,8 @@ void SystemCatalog::CreateTable(const std::string &table_name, const ColumnList if (new_table) { Disk::CreateFile(Disk::GetFilePath(db_oid, oid)); } - oid2table_[oid] = std::make_shared
(buffer_pool_, log_manager_, oid, db_oid, column_list, new_table); + oid2table_[oid] = std::make_shared
(buffer_pool_, log_manager_, oid, db_oid, column_list, new_table, + Disk::EmptyFile(Disk::GetFilePath(db_oid, oid))); // 检查:非新表不需要添加到 Meta 中 if (!new_table) { @@ -430,8 +431,8 @@ void SystemCatalog::LoadTableMeta() { // 添加数据表 oid_manager_.SetEntryOid(OidType::TABLE, table_name, oid); - oid2table_[oid] = - std::make_shared
(buffer_pool_, log_manager_, oid, current_database_oid_, column_list, false); + oid2table_[oid] = std::make_shared
(buffer_pool_, log_manager_, oid, current_database_oid_, column_list, + false, Disk::EmptyFile(Disk::GetFilePath(GetDatabaseOid(oid), oid))); table2cardinality_[table_name] = cardinality; } } diff --git a/src/log/log_manager.cpp b/src/log/log_manager.cpp index 3d63028..c91a592 100644 --- a/src/log/log_manager.cpp +++ b/src/log/log_manager.cpp @@ -32,7 +32,7 @@ lsn_t LogManager::AppendInsertLog(xid_t xid, oid_t oid, pageid_t page_id, slotid if (att_.find(xid) == att_.end()) { throw DbException(std::to_string(xid) + " does not exist in att (in AppendInsertLog)"); } - auto log = std::make_shared(NULL_LSN, xid, att_[xid], oid, page_id, slot_id, offset, size, new_record); + auto log = std::make_shared(NULL_LSN, xid, att_.at(xid), oid, page_id, slot_id, offset, size, new_record); lsn_t lsn = next_lsn_.fetch_add(log->GetSize(), std::memory_order_relaxed); log->SetLSN(lsn); att_[xid] = lsn; @@ -50,7 +50,7 @@ lsn_t LogManager::AppendDeleteLog(xid_t xid, oid_t oid, pageid_t page_id, slotid if (att_.find(xid) == att_.end()) { throw DbException(std::to_string(xid) + " does not exist in att (in AppendDeleteLog)"); } - auto log = std::make_shared(NULL_LSN, xid, att_[xid], oid, page_id, slot_id); + auto log = std::make_shared(NULL_LSN, xid, att_.at(xid), oid, page_id, slot_id); lsn_t lsn = next_lsn_.fetch_add(log->GetSize(), std::memory_order_relaxed); log->SetLSN(lsn); att_[xid] = lsn; @@ -72,7 +72,7 @@ lsn_t LogManager::AppendNewPageLog(xid_t xid, oid_t oid, pageid_t prev_page_id, if (xid == DDL_XID) { log_xid = NULL_XID; } else { - log_xid = att_[xid]; + log_xid = att_.at(xid); } auto log = std::make_shared(NULL_LSN, xid, log_xid, oid, prev_page_id, page_id); lsn_t lsn = next_lsn_.fetch_add(log->GetSize(), std::memory_order_relaxed); @@ -113,7 +113,7 @@ lsn_t LogManager::AppendCommitLog(xid_t xid) { if (att_.find(xid) == att_.end()) { throw DbException(std::to_string(xid) + " does not exist in att (in AppendCommitLog)"); } - auto log = std::make_shared(NULL_LSN, xid, att_[xid]); + auto log = std::make_shared(NULL_LSN, xid, att_.at(xid)); lsn_t lsn = next_lsn_.fetch_add(log->GetSize(), std::memory_order_relaxed); log->SetLSN(lsn); { @@ -129,7 +129,7 @@ lsn_t LogManager::AppendRollbackLog(xid_t xid) { if (att_.find(xid) == att_.end()) { throw DbException(std::to_string(xid) + " does not exist in att (in AppendRollbackLog)"); } - auto log = std::make_shared(NULL_LSN, xid, att_[xid]); + auto log = std::make_shared(NULL_LSN, xid, att_.at(xid)); lsn_t lsn = next_lsn_.fetch_add(log->GetSize(), std::memory_order_relaxed); log->SetLSN(lsn); { @@ -246,6 +246,7 @@ void LogManager::Analyze() { in >> checkpoint_lsn; } // 根据 Checkpoint 日志恢复脏页表、活跃事务表等元信息 + // 必要时调用 transaction_manager_.SetNextXid 来恢复事务 id // LAB 2 BEGIN } diff --git a/src/storage/disk.cpp b/src/storage/disk.cpp index 61667da..2d64d2c 100644 --- a/src/storage/disk.cpp +++ b/src/storage/disk.cpp @@ -49,6 +49,13 @@ void Disk::RemoveDirectory(const std::string &path) { std::filesystem::remove_al bool Disk::FileExists(const std::string &path) { return std::filesystem::is_regular_file(path); } +bool Disk::EmptyFile(const std::string &path) { + if (!FileExists(path)) { + throw DbException("file " + path + " does not exist"); + } + return std::filesystem::is_empty(path); +} + void Disk::CreateFile(const std::string &path) { std::ofstream ofs(path); } void Disk::RemoveFile(const std::string &path) { std::filesystem::remove(path); } @@ -76,7 +83,7 @@ void Disk::ReadPage(const std::string &path, pageid_t page_id, char *data) { fs.seekg(page_id * DB_PAGE_SIZE); fs.read(data, DB_PAGE_SIZE); if (fs.gcount() != DB_PAGE_SIZE) { - throw DbException("read page failed: read " + std::to_string(fs.gcount()) + " bytes, expected " + + throw DbException(path + " read page failed: read " + std::to_string(fs.gcount()) + " bytes, expected " + std::to_string(DB_PAGE_SIZE) + " bytes"); } } diff --git a/src/storage/disk.h b/src/storage/disk.h index 92480ab..78c3e76 100644 --- a/src/storage/disk.h +++ b/src/storage/disk.h @@ -19,6 +19,8 @@ class Disk { static void RemoveDirectory(const std::string &path); static bool FileExists(const std::string &path); + static bool EmptyFile(const std::string &path); + static void CreateFile(const std::string &path); static void RemoveFile(const std::string &path); diff --git a/src/table/table.cpp b/src/table/table.cpp index 32e762f..b08737f 100644 --- a/src/table/table.cpp +++ b/src/table/table.cpp @@ -5,22 +5,18 @@ namespace huadb { Table::Table(BufferPool &buffer_pool, LogManager &log_manager, oid_t oid, oid_t db_oid, ColumnList column_list, - bool new_table) + bool new_table, bool is_empty) : buffer_pool_(buffer_pool), log_manager_(log_manager), oid_(oid), db_oid_(db_oid), column_list_(std::move(column_list)) { // 新建表时初始化第一个页面 - if (new_table) { - auto table_page = std::make_unique(buffer_pool_.NewPage(db_oid_, oid_, 0)); - table_page->Init(); - if (oid >= PRESERVED_OID) { - lsn_t lsn = log_manager_.AppendNewPageLog(DDL_XID, oid_, NULL_PAGE_ID, 0); - table_page->SetPageLSN(lsn); - } + if (new_table || is_empty) { + first_page_id_ = NULL_PAGE_ID; + } else { + first_page_id_ = 0; } - first_page_id_ = 0; } Rid Table::InsertRecord(std::shared_ptr record, xid_t xid, cid_t cid, bool write_log) { diff --git a/src/table/table.h b/src/table/table.h index 1ffe027..e964ec5 100644 --- a/src/table/table.h +++ b/src/table/table.h @@ -11,7 +11,7 @@ namespace huadb { class Table { public: Table(BufferPool &buffer_pool, LogManager &log_manager, oid_t oid, oid_t db_oid, ColumnList column_list, - bool new_table); + bool new_table, bool is_empty); // 插入记录,返回插入记录的 rid // write_log: 是否写日志。系统表操作不写日志,用户表操作写日志,lab 2 相关参数