diff options
author | Franciszek Malinka <franciszek.malinka@gmail.com> | 2022-11-06 15:35:18 +0100 |
---|---|---|
committer | kacper776 <54678026+kacper776@users.noreply.github.com> | 2022-11-06 23:54:31 +0100 |
commit | 62f335c52b36a9f5c58dde5a8fd6ce4600f35ccd (patch) | |
tree | 3d5f721627da787a137c06889ebd4e37a35136f2 | |
parent | 2e2d36c2986af1a44762a3fff40c57d1e16eaaec (diff) |
Added HeapFile implementation
-rw-r--r-- | komfydb/storage/BUILD | 3 | ||||
-rw-r--r-- | komfydb/storage/db_file.h | 21 | ||||
-rw-r--r-- | komfydb/storage/heap_file.cc | 83 | ||||
-rw-r--r-- | komfydb/storage/heap_file.h | 36 | ||||
-rw-r--r-- | komfydb/storage/page_id.h | 11 |
5 files changed, 125 insertions, 29 deletions
diff --git a/komfydb/storage/BUILD b/komfydb/storage/BUILD index d64b49c..583a7f3 100644 --- a/komfydb/storage/BUILD +++ b/komfydb/storage/BUILD @@ -31,4 +31,5 @@ cc_library( "@com_google_absl//absl/status", "@com_google_absl//absl/container:flat_hash_map", ], - visibility = ["//visibility:public"],) + visibility = ["//visibility:public"], +) diff --git a/komfydb/storage/db_file.h b/komfydb/storage/db_file.h index 80c913b..f92fb14 100644 --- a/komfydb/storage/db_file.h +++ b/komfydb/storage/db_file.h @@ -5,7 +5,6 @@ #include "absl/status/status.h" #include "absl/status/statusor.h" - #include "komfydb/common/tuple.h" #include "komfydb/common/tuple_desc.h" #include "komfydb/storage/db_file_iterator.h" @@ -27,21 +26,23 @@ class DbFile { public: virtual ~DbFile() = 0; - // TODO Shouldn't this return StatusOr? - virtual std::unique_ptr<Page> ReadPage(PageId id); + virtual absl::StatusOr<std::unique_ptr<Page>> ReadPage(PageId id); - virtual absl::Status WritePage(Page p); + // Not necessary for Lab 1 + // virtual absl::Status WritePage(Page* p?); - virtual absl::StatusOr<std::list<Page>> InsertTuple(TransactionId tid, - Tuple t); + // virtual absl::StatusOr<std::vector<Page*>> InsertTuple(TransactionId tid, + // Tuple t); - virtual absl::StatusOr<std::list<Page>> DeleteTuple(TransactionId tid, - Tuple t); + // virtual absl::StatusOr<std::vector<Page*>> DeleteTuple(TransactionId tid, + // Tuple t); - virtual DbFileIterator Iterator(TransactionId tid); + // TODO This method shouldn't be here for sure.. + // virtual std::unique_ptr<DbFileIterator> Iterator(TransactionId tid); - virtual int GetId(); + virtual unsigned int GetId(); + // TODO Shouldn't this return a const pointer? virtual TupleDesc* GetTupleDesc(); }; diff --git a/komfydb/storage/heap_file.cc b/komfydb/storage/heap_file.cc index e69de29..4477cd4 100644 --- a/komfydb/storage/heap_file.cc +++ b/komfydb/storage/heap_file.cc @@ -0,0 +1,83 @@ +#include "komfydb/storage/heap_file.h" + +#include <fstream> + +#include "komfydb/utils/utility.h" +#include "komfydb/config.h" +#include "komfydb/utils/status_macros.h" +#include "komfydb/common/tuple_desc.h" + +namespace komfydb::storage { + +HeapFile::HeapFile( + std::fstream& file, + TupleDesc td, + unsigned int table_id, + Permissions permissions) + : file(file), td(td), table_id(table_id), permissions(permissions) {} + +HeapFile::~HeapFile() { + file.close(); +} + +absl::StatusOr<std::unique_ptr<HeapFile>> HeapFile::Create( + const std::string& file_path, + TupleDesc* td, + Permissions permissions) { + ios_base::openmode mode = std::io::binary | std::io::in; + if (permissions == Permissions::READ_WRITE) { + mode |= std::io::out; + } + + std::fstream file; + file.open(file_path, mode); + if (!file.good()) { + return absl::InvalidArgumentError("Could not open specified db file."); + } + + file.seekg(0, file.end); + unsigned int file_length = file.tellg(); + if (file_length % CONFIG_PAGE_SIZE) { + file.close(); + return absl::InvalidArgumentError("File size not divisble by page size."); + } + + return std::make_unique<HeapFile>(file, td, ++table_cnt, permissions); +} + +std::fstream& HeapFile::GetFile() { + return file; +} + +unsigned int HeapFile::GetId() { + return table_id; +} + +unsigned int HeapFile::GetTupleDesc() { + return td; +} + +absl::StatusOr<std::unique_ptr<Page>> ReadPage(PageId id) { + if (id.table_id != table_id) { + return absl::InvalidArgumentError("Table ID does not match."); + } + + file.seekg(0, file.end); + unsigned int file_length = file.tellg(); + + int page_pos = CONFIG_PAGE_SIZE * id.page_no; + if (page_pos >= file_length) { + return absl::InvalidArgumentError("Page number out of range."); + } + + vector<uint8_t> data(CONFIG_PAGE_SIZE); + file.seekg(page_pos); + file.get(&data, CONFIG_PAGE_SIZE); + + ASSIGN_OR_RETURN(std::unique_ptr<Page> page, HeapPage::Create(id, &td, data)); + + return page; +} + +}; + diff --git a/komfydb/storage/heap_file.h b/komfydb/storage/heap_file.h index 0aec8ed..c284dce 100644 --- a/komfydb/storage/heap_file.h +++ b/komfydb/storage/heap_file.h @@ -8,7 +8,9 @@ #include "absl/status/status.h" #include "absl/status/statusor.h" +#include "komfydb/common/tuple.h" #include "komfydb/common/tuple_desc.h" +#include "komfydb/common/permissions.h" #include "komfydb/storage/db_file.h" #include "komfydb/storage/db_file_iterator.h" #include "komfydb/storage/page.h" @@ -19,6 +21,7 @@ namespace { using komfydb::common::Tuple; using komfydb::common::TupleDesc; +using komfydb::common::Permissions; using komfydb::transaction::TransactionId; }; // namespace @@ -27,28 +30,39 @@ namespace komfydb::storage { class HeapFile : DbFile { private: - std::fstream file; + std::fstream& file; + TupleDesc td; + unsigned int table_id; + Permissions permissions; + // TODO This is probably a very bad way to create table_id's, it's not + // thread safe. Probably it would be better to get some file's hash code. + static unsigned int table_cnt = 0; + + HeapFile(std::fstream& file, TupleDesc td, unsigned int table_id, Permissions permissions); public: - HeapFile(std::fstream& file, TupleDesc td); + ~HeapFile(); + + static absl::StatusOr<std::unique_ptr<HeapFile>> + Create(const std::string& file_name, TupleDesc td, Permissions permissions); std::fstream& GetFile(); - Page ReadPage(PageId id) override; + absl::StatusOr<std::unique_ptr<Page>> ReadPage(PageId id) override; - absl::Status WritePage(Page p) override; + // absl::Status WritePage(Page* p) override; - absl::StatusOr<std::list<Page>> InsertTuple(TransactionId tid, - Tuple t) override; + // absl::StatusOr<std::vector<Page*>> InsertTuple(TransactionId tid, + // Tuple t) override; - absl::StatusOr<std::list<Page>> DeleteTuple(TransactionId tid, - Tuple t) override; + // absl::StatusOr<std::vector<Page*>> DeleteTuple(TransactionId tid, + // Tuple t) override; - DbFileIterator Iterator(TransactionId tid) override; + // std::unique_ptr<DbFileIterator> Iterator(TransactionId tid) override; - int GetId() override; + unsigned int GetId() override; - TupleDesc GetTupleDesc() override; + TupleDesc* GetTupleDesc() override; }; }; // namespace komfydb::storage diff --git a/komfydb/storage/page_id.h b/komfydb/storage/page_id.h index 8a91b40..749090f 100644 --- a/komfydb/storage/page_id.h +++ b/komfydb/storage/page_id.h @@ -11,20 +11,17 @@ namespace komfydb::storage { class PageId { private: - int table_id; - int page_no; + unsigned int table_id; + unsigned int page_no; public: PageId(int table_id, int page_no); std::vector<uint8_t> Serialize(); - int GetTableId() const; + unsigned int GetTableId() const; - int GetPageNumber() const; - - // TODO(HashCode) - // int HashCode(); + unsigned int GetPageNumber() const; bool operator==(const PageId& p) const; |