From 3692425b2927d95cc37052fa375625f76211d49b Mon Sep 17 00:00:00 2001
From: RockChinQ <1010553892@qq.com>
Date: Thu, 13 Jul 2023 11:34:01 +0000
Subject: [PATCH] =?UTF-8?q?feat:=20storage=E4=BB=BB=E5=8A=A1=E7=9A=84disk?=
 =?UTF-8?q?=5Fmanager=E5=AD=90=E4=BB=BB=E5=8A=A1=E5=AE=9E=E7=8E=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .gitignore                   |  2 ++
 src/storage/disk_manager.cpp | 61 +++++++++++++++++++++++++++++++++++-
 2 files changed, 62 insertions(+), 1 deletion(-)
 create mode 100644 .gitignore

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6f31401
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+build/
+.vscode/
diff --git a/src/storage/disk_manager.cpp b/src/storage/disk_manager.cpp
index dbba39c..107023b 100644
--- a/src/storage/disk_manager.cpp
+++ b/src/storage/disk_manager.cpp
@@ -14,6 +14,8 @@ See the Mulan PSL v2 for more details. */
 #include <string.h>    // for memset
 #include <sys/stat.h>  // for stat
 #include <unistd.h>    // for lseek
+#include <iostream>    // for cout
+#include <fstream>     // for ofstream
 
 #include "defs.h"
 
@@ -31,7 +33,15 @@ void DiskManager::write_page(int fd, page_id_t page_no, const char *offset, int
     // 1.lseek()定位到文件头,通过(fd,page_no)可以定位指定页面及其在磁盘文件中的偏移量
     // 2.调用write()函数
     // 注意write返回值与num_bytes不等时 throw InternalError("DiskManager::write_page Error");
+    int offset_byte = page_no * PAGE_SIZE;
 
+    if (lseek(fd, offset_byte, SEEK_SET) != offset_byte) {
+        throw InternalError("Failed to seek page " + std::to_string(page_no) + " in file " + std::to_string(fd));
+    }
+
+    if (write(fd, offset, num_bytes) != num_bytes) {
+        throw InternalError("Failed to write page " + std::to_string(page_no) + " in file " + std::to_string(fd));
+    }
 }
 
 /**
@@ -46,7 +56,15 @@ void DiskManager::read_page(int fd, page_id_t page_no, char *offset, int num_byt
     // 1.lseek()定位到文件头,通过(fd,page_no)可以定位指定页面及其在磁盘文件中的偏移量
     // 2.调用read()函数
     // 注意read返回值与num_bytes不等时,throw InternalError("DiskManager::read_page Error");
+    int offset_byte = page_no * PAGE_SIZE;
 
+    if (lseek(fd, offset_byte, SEEK_SET) != offset_byte) {
+        throw InternalError("Failed to seek page " + std::to_string(page_no) + " in file " + std::to_string(fd));
+    }
+
+    if (read(fd, offset, num_bytes) != num_bytes) {
+        throw InternalError("Failed to read page " + std::to_string(page_no) + " in file " + std::to_string(fd));
+    }
 }
 
 /**
@@ -102,6 +120,14 @@ void DiskManager::create_file(const std::string &path) {
     // Todo:
     // 调用open()函数,使用O_CREAT模式
     // 注意不能重复创建相同文件
+    int fd = open(path.c_str(), O_CREAT, 0666);
+    if (fd < 0) {
+        throw std::runtime_error("Failed to create file: " + path);
+    }
+
+    // 到底该不该存到文件打开列表中?
+    // 应该在下面open_file()函数中存入文件打开列表中?
+    close(fd);
 }
 
 /**
@@ -112,7 +138,15 @@ void DiskManager::destroy_file(const std::string &path) {
     // Todo:
     // 调用unlink()函数
     // 注意不能删除未关闭的文件
-    
+    if (path2fd_.count(path) > 0){
+        throw std::runtime_error("Cannot destroy an opened file: " + path);
+    }
+
+    int symbol = unlink(path.c_str());
+
+    if (symbol < 0) {
+        throw std::runtime_error("Failed to destroy file: " + path);
+    }
 }
 
 
@@ -126,6 +160,22 @@ int DiskManager::open_file(const std::string &path) {
     // 调用open()函数,使用O_RDWR模式
     // 注意不能重复打开相同文件,并且需要更新文件打开列表
 
+    // 检查文件是否已经打开
+    if (path2fd_.count(path) > 0) {
+        throw std::runtime_error("Cannot open an opened file: " + path);
+    }
+
+    // 打开文件
+    int fd = open(path.c_str(), O_RDWR);
+
+    if (fd < 0) {
+        throw std::runtime_error("Failed to open file: " + path);
+    }
+
+    path2fd_[path] = fd;
+    fd2path_[fd] = path;
+
+    return fd;
 }
 
 /**
@@ -136,7 +186,16 @@ void DiskManager::close_file(int fd) {
     // Todo:
     // 调用close()函数
     // 注意不能关闭未打开的文件,并且需要更新文件打开列表
+    if (fd2path_.count(fd) == 0) {
+        throw std::runtime_error("Cannot close an unopened file: " + fd);
+    }
+
+    close(fd);
+
+    std::string path = fd2path_[fd];
 
+    path2fd_.erase(path);
+    fd2path_.erase(fd);
 }
 
 
-- 
GitLab