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 相关参数