From 341981d2663042b73eafbfd3aecd7381f8321fbf Mon Sep 17 00:00:00 2001 From: Ludovic 'Archivist' Lagouardette Date: Mon, 5 Oct 2020 07:36:57 +0200 Subject: [PATCH] Progress on tagfs --- Makefile | 8 ++- include/gp/bitops.hpp | 7 +-- include/gp/tagfs/tagfs.hpp | 102 +++++++++++++++++++++++++++++++++++-- tests/tagfs_test.cpp | 6 +-- 4 files changed, 106 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index 536bb74..d4567df 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,7 @@ -CXX= g++ +CXX= clang++-10 CXXFLAGS= --std=c++20 -O0 -g -pthread -DGP_TESTS -DFUZZ_STRENGTH=500 -DNO_BENCH=1 -pedantic \ - -# -frtti -fprofile-instr-generate -fcoverage-mapping -Wno-unknown-attributes \ - -# -fsanitize=address -fno-omit-frame-pointer + -frtti -fprofile-instr-generate -fcoverage-mapping -Wno-unknown-attributes \ + -fsanitize=address -fno-omit-frame-pointer all: tests tests: bin/tests diff --git a/include/gp/bitops.hpp b/include/gp/bitops.hpp index 3858efd..6a33753 100644 --- a/include/gp/bitops.hpp +++ b/include/gp/bitops.hpp @@ -53,15 +53,12 @@ namespace gp{ } template - struct endian_wrapper { + struct endian_wrapper final { T value; - endian_wrapper(){}; + endian_wrapper(T v) : value{ mode == endian::native ? v : swap_endian(v) }{} - endian_wrapper(endian_wrapper& v) : value{ - v.value - }{} endian_wrapper& operator=(T p) { value = mode == endian::native ? p : swap_endian(p); diff --git a/include/gp/tagfs/tagfs.hpp b/include/gp/tagfs/tagfs.hpp index 5cd8c1a..9733283 100644 --- a/include/gp/tagfs/tagfs.hpp +++ b/include/gp/tagfs/tagfs.hpp @@ -36,7 +36,8 @@ namespace gp { auto it = data.begin()+offset; auto ret = buffer; for(auto& c : buffer) { - *(it++) = c; + auto cpy = it++; + *(cpy) = c; if(it == data.end()) { ret = buffer.slice_start(it - (data.begin() + offset)); break; @@ -64,8 +65,6 @@ namespace gp { constexpr static size_t page_size = gp::remove_reference::type::page_size(); constexpr static gp::array empty_page{gp::zero_t{}}; - - struct disk_root { gp::endian_wrapper magic; gp::endian_wrapper first_allocator_page; @@ -75,13 +74,108 @@ namespace gp { gp::endian_wrapper page_count; }; + struct tree_node { + constexpr static size_t node_pages = page_size/sizeof(uint64_t) - 2; + + gp::endian_wrapper node_level; + gp::endian_wrapper node_size; + gp::endian_wrapper data_pages[node_pages]; + + auto allocate_or_get_node_n(tagfs& fs, uint64_t index) { + struct ret_struct{ + gp::array page; + uint64_t page_id; + bool must_update; + }; + + ret_struct ret; + + if(auto attempt = fail_or_get_node_n(fs, index)) { + ret.page = attempt.value(); + ret.page_id = 0; + ret.must_update = false; + } else { + ret.page_id = data_pages[index] = fs.allocate_page(); + ret.must_update = true; + fs.disk->read(ret.page.as_buffer(), ret.page_id*page_size); + } + + return ret; + } + + auto fail_or_get_node_n(tagfs& fs, uint64_t index) -> gp::optional> { + + } + + auto get_page_at_rec(uint64_t page_offset) { + struct ret_struct { + bool still_ongoing; + uint64_t next_node; + uint64_t next_page; + }; + if(node_level) { + auto transmit = page_offset % node_pages; + auto local = page_offset / node_pages; + gp_config::assertion(local < node_pages, "node can't be within the page"); + gp_config::assertion(local < node_size, "node not within the page"); + return ret_struct{true, data_pages[local], transmit}; + } else { + gp_config::assertion(page_offset < node_pages, "node can't be within the page"); + gp_config::assertion(page_offset < node_size, "node not within the page"); + return ret_struct{false, 0, data_pages[page_offset]}; + } + } + + uint64_t get_page_at(vdisk_ptr& disk, uint64_t page_offset) { + auto [ongoing, page] = get_page_at_rec(page_offset); + if(!ongoing) return page; + gp::array explore; + do { + disk->read(explore.template cast(), page*page_size); + auto [t_ongoing, t_page] = explore.begin().get_page_at_rec(page); + ongoing = t_ongoing; + page = t_page; + } while(ongoing); + return page; + } + + + uint64_t set_page_at_rec(uint64_t page_offset, gp::array* page_data, gp::buffer page_list) { + struct ret_struct { + bool still_ongoing; + uint64_t next_page; + }; + if(node_level) { + auto transmit = page_offset % node_pages; + auto local = page_offset / node_pages; + + return ret_struct{true, transmit}; + } else { + return ret_struct{false, data_pages[page_offset]}; + } + } + + uint64_t set_page_at(vdisk_ptr& disk, uint64_t page_offset) { + auto [ongoing, page] = get_page_at_rec(page_offset); + if(!ongoing) return page; + gp::array explore; + do { + disk->read(explore.template cast(), page*page_size); + auto [t_ongoing, t_page] = explore.begin().get_page_at_rec(page); + ongoing = t_ongoing; + page = t_page; + } while(ongoing); + return page; + } + }; + struct file_description { gp::endian_wrapper reference_counter; }; public: tagfs(vdisk_ptr&& _disk) - : disk(gp::forward(disk)) + : disk(std::move(_disk)) {} private: diff --git a/tests/tagfs_test.cpp b/tests/tagfs_test.cpp index 940a547..b718e75 100644 --- a/tests/tagfs_test.cpp +++ b/tests/tagfs_test.cpp @@ -12,9 +12,9 @@ struct tagfs_test : public test_scaffold { virtual int run() { bool result = true; - // auto disk = std::move(std::make_unique>()); - auto disk = new gp::memory_vdisk<128*1025>(); - auto fs = gp::tagfs*>{std::forward*>(disk)}; + auto disk = std::make_unique>(); + //auto disk = new gp::memory_vdisk<128*1025>(); + auto fs = gp::tagfs{std::move(disk)}; fs.format(); return !result; }