Procházet zdrojové kódy

Progress on tagfs

tagfs
Ludovic 'Archivist' Lagouardette před 3 roky
rodič
revize
341981d266
4 změnil soubory, kde provedl 106 přidání a 17 odebrání
  1. +3
    -5
      Makefile
  2. +2
    -5
      include/gp/bitops.hpp
  3. +98
    -4
      include/gp/tagfs/tagfs.hpp
  4. +3
    -3
      tests/tagfs_test.cpp

+ 3
- 5
Makefile Zobrazit soubor

@ -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

+ 2
- 5
include/gp/bitops.hpp Zobrazit soubor

@ -53,15 +53,12 @@ namespace gp{
}
template<typename T, endian mode = endian::big>
struct endian_wrapper {
struct endian_wrapper k">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);

+ 98
- 4
include/gp/tagfs/tagfs.hpp Zobrazit soubor

@ -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<decltype(*disk)>::type::page_size();
constexpr static gp::array<uint8_t, page_size> empty_page{gp::zero_t{}};
struct disk_root {
gp::endian_wrapper<uint64_t, gp::endian::little> magic;
gp::endian_wrapper<uint64_t, gp::endian::little> first_allocator_page;
@ -75,13 +74,108 @@ namespace gp {
gp::endian_wrapper<uint64_t, gp::endian::little> page_count;
};
struct tree_node {
constexpr static size_t node_pages = page_size/sizeof(uint64_t) - 2;
gp::endian_wrapper<uint64_t, gp::endian::little> node_level;
gp::endian_wrapper<uint64_t, gp::endian::little> node_size;
gp::endian_wrapper<uint64_t, gp::endian::little> data_pages[node_pages];
auto allocate_or_get_node_n(tagfs& fs, uint64_t index) {
struct ret_struct{
gp::array<uint8_t, page_size> 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<gp::array<uint8_t, page_size>> {
}
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<tree_node, 1> explore;
do {
disk->read(explore.template cast<char>(), 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<uint8_t, page_size>* page_data, gp::buffer<uint64_t> 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<tree_node, 1> explore;
do {
disk->read(explore.template cast<char>(), 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<uint32_t, gp::endian::little> reference_counter;
};
public:
tagfs(vdisk_ptr&& _disk)
: disk(gp::forward<vdisk_ptr>(disk))
: disk(std::move(_disk))
{}
private:

+ 3
- 3
tests/tagfs_test.cpp Zobrazit soubor

@ -12,9 +12,9 @@ struct tagfs_test : public test_scaffold {
virtual int run() {
bool result = true;
c1">// auto disk = std::move(std::make_unique<gp::memory_vdisk<128*1025>>());
k">auto disk = new gp::memory_vdisk<128*1025>();
auto fs = gp::tagfso"><gp::memory_vdisk<128*1025>*>{std::forward<gp::memory_vdisk<128*1025>*>(disk)};
k">auto disk = std::make_unique<gp::memory_vdisk<128*1025>>();
c1">//auto disk = new gp::memory_vdisk<128*1025>();
auto fs = gp::tagfs{std::move(disk)};
fs.format();
return !result;
}

Načítá se…
Zrušit
Uložit