From 5722731c6a95eaabdaa28140a1624d2e54ce6473 Mon Sep 17 00:00:00 2001 From: Syed Daanish Date: Tue, 4 Aug 2026 23:41:31 +0100 Subject: [PATCH] Cleanup namespace and api. --- include/vase/buffer/original.h | 2 +- include/vase/shard.h | 21 +++++++++--------- include/vase/vase.h | 8 ++++--- src/main.cc | 2 +- src/vase/buffer/append.cc | 2 ++ src/vase/buffer/original.cc | 15 ++++++++----- src/vase/shard.cc | 23 +++++++++---------- src/vase/vase.cc | 40 +++++++++++++++++++--------------- 8 files changed, 63 insertions(+), 50 deletions(-) diff --git a/include/vase/buffer/original.h b/include/vase/buffer/original.h index 9b48165..fbdd0ce 100644 --- a/include/vase/buffer/original.h +++ b/include/vase/buffer/original.h @@ -8,7 +8,7 @@ struct OriginalBuffer : Buffer { uint64_t len; int fd = -1; - OriginalBuffer(); + OriginalBuffer(std::filesystem::path base_dir); ~OriginalBuffer(); void initialize(); diff --git a/include/vase/shard.h b/include/vase/shard.h index 36bd98d..962b030 100644 --- a/include/vase/shard.h +++ b/include/vase/shard.h @@ -24,6 +24,17 @@ struct Shard { static void retain(Shard *n); static void release(Shard *n); + + static Shard *from_file(std::filesystem::path path, OriginalBuffer *b); + static std::vector from_swap(std::filesystem::path path, OriginalBuffer *b); + static Shard *new_empty(OriginalBuffer *b); + + static std::pair split(Shard *n, uint64_t offset); + static Shard *concat(Shard *left, Shard *right); + static Shard *merge(Shard *a, Shard *b); + static Shard *merge_leaves(Shard *a, Shard *b); + static Shard *append_leaf(Shard *root, Shard *leaf); + static Shard *build_balanced(Shard **pieces, uint64_t lo, uint64_t hi); }; struct Branch : Shard { @@ -52,13 +63,3 @@ struct Petal : Shard { : Shard(ShardKind::Petal, length, lines, 1), source(source), pos(pos) {}; }; - -Shard *create_file_shards(std::string &path, OriginalBuffer *b); -Shard *create_swap_shards(std::string &path, OriginalBuffer *b); - -std::pair split_shard(Shard *n, uint64_t offset); -Shard *concat_shard(Shard *left, Shard *right); -Shard *merge(Shard *a, Shard *b); -Shard *merge_leaves(Shard *a, Shard *b); -Shard *append_leaf(Shard *root, Shard *leaf); -Shard *build_balanced(Shard **pieces, uint64_t lo, uint64_t hi); diff --git a/include/vase/vase.h b/include/vase/vase.h index 2de228d..b9671c3 100644 --- a/include/vase/vase.h +++ b/include/vase/vase.h @@ -44,8 +44,10 @@ struct Vase { OriginalBuffer *original; AppendBuffer *append; Shard *root; + std::filesystem::path path; + std::filesystem::path swapdir; - Vase(std::string path); + Vase(std::filesystem::path path, std::filesystem::path swapdir); ~Vase(); @@ -82,8 +84,8 @@ struct Vase { void snapshot(); void prune_history(uint64_t n); - bool save(std::string path); - bool save_swap(std::string path); + bool save(); + bool save_swap(); uint64_t offset_of(Point point); Point point_of(uint64_t offset); diff --git a/src/main.cc b/src/main.cc index 757980c..4340451 100644 --- a/src/main.cc +++ b/src/main.cc @@ -7,7 +7,7 @@ int main(int argc, char *argv[]) { if (argc < 2) throw std::runtime_error("Please give filename."); - Vase vase = Vase(std::string(argv[1])); + Vase vase = Vase(argv[1], "/tmp"); Point p = {500, 1000}; vase.insert(&p, 'x'); diff --git a/src/vase/buffer/append.cc b/src/vase/buffer/append.cc index 7b2fd81..6bbf5f8 100644 --- a/src/vase/buffer/append.cc +++ b/src/vase/buffer/append.cc @@ -13,6 +13,8 @@ AppendBuffer::~AppendBuffer() { uint64_t AppendBuffer::append(char c) { if (t_offset == APPEND_CHUNK_SIZE) { t_current = (TChunk *)malloc(sizeof(TChunk)); + if (!t_current) + throw std::runtime_error("malloc failed"); buf.push_back(t_current); t_offset = 0; } diff --git a/src/vase/buffer/original.cc b/src/vase/buffer/original.cc index d95f2a0..1649841 100644 --- a/src/vase/buffer/original.cc +++ b/src/vase/buffer/original.cc @@ -1,12 +1,17 @@ #include "vase/buffer/original.h" #include "io/file.h" -OriginalBuffer::OriginalBuffer() { - char tmp_path[] = "/tmp/tbuf.XXXXXX"; - fd = mkstemp(tmp_path); +OriginalBuffer::OriginalBuffer(std::filesystem::path base_dir) { + if (!std::filesystem::exists(base_dir) || !std::filesystem::is_directory(base_dir)) + throw std::runtime_error("Swap directory does not exist or is not a directory."); + base_dir /= "tbuf.XXXXXX"; + auto s = base_dir.string(); + std::vector mutable_path(s.begin(), s.end()); + mutable_path.push_back('\0'); + fd = mkstemp(mutable_path.data()); if (fd == -1) - exit(1); - unlink(tmp_path); + throw std::runtime_error("mkstemp failed"); + unlink(mutable_path.data()); } OriginalBuffer::~OriginalBuffer() { diff --git a/src/vase/shard.cc b/src/vase/shard.cc index 704ce7e..fbb42ae 100644 --- a/src/vase/shard.cc +++ b/src/vase/shard.cc @@ -87,7 +87,7 @@ Shard *balance(Shard *node) { return node; } -Shard *merge(Shard *a, Shard *b) { +Shard *Shard::merge(Shard *a, Shard *b) { if (!a) return b ? (Shard::retain(b), b) : nullptr; if (!b) @@ -112,7 +112,7 @@ Shard *merge(Shard *a, Shard *b) { return balance(new Branch(a, b)); } -std::pair split_shard(Shard *n, uint64_t offset) { +std::pair Shard::split(Shard *n, uint64_t offset) { if (!n) return {nullptr, nullptr}; if (offset == 0) { @@ -127,12 +127,12 @@ std::pair split_shard(Shard *n, uint64_t offset) { if (n->kind == Shard::ShardKind::Branch) { Branch *b = (Branch *)n; if (offset < b->left->length) { - auto [a, b2] = split_shard(b->left, offset); + auto [a, b2] = split(b->left, offset); Shard *right = merge(b2, b->right); Shard::release(b2); return {a, right}; } else { - auto [a, b2] = split_shard(b->right, offset - b->left->length); + auto [a, b2] = split(b->right, offset - b->left->length); Shard *left = merge(b->left, a); Shard::release(a); return {left, b2}; @@ -177,7 +177,7 @@ std::pair split_shard(Shard *n, uint64_t offset) { } } -Shard *merge_leaves(Shard *a, Shard *b) { +Shard *Shard::merge_leaves(Shard *a, Shard *b) { if (a->kind != Shard::ShardKind::Petal || b->kind != Shard::ShardKind::Petal) return merge(a, b); Petal *pa = (Petal *)a; @@ -192,7 +192,7 @@ Shard *merge_leaves(Shard *a, Shard *b) { ); } -Shard *append_leaf(Shard *root, Shard *leaf) { +Shard *Shard::append_leaf(Shard *root, Shard *leaf) { if (!root) return leaf; if (root->kind == Shard::ShardKind::Petal && root->length < PETAL_SIZE_MAX) @@ -204,11 +204,11 @@ Shard *append_leaf(Shard *root, Shard *leaf) { return out; } -Shard *concat_shard(Shard *left, Shard *right) { +Shard *Shard::concat(Shard *left, Shard *right) { return merge(left, right); } -Shard *build_balanced(Shard **pieces, uint64_t lo, uint64_t hi) { +Shard *Shard::build_balanced(Shard **pieces, uint64_t lo, uint64_t hi) { if (hi - lo == 1) return pieces[lo]; size_t mid = lo + (hi - lo) / 2; @@ -220,18 +220,15 @@ Shard *build_balanced(Shard **pieces, uint64_t lo, uint64_t hi) { return node; } -Shard *create_file_shards(std::string &path, OriginalBuffer *o) { +Shard *Shard::from_file(std::filesystem::path path, OriginalBuffer *o) { int dest_fd = o->fd; if (dest_fd == -1) return nullptr; int src_fd = open(path.c_str(), O_RDONLY); if (src_fd == -1) return nullptr; - struct stat st; - if (fstat(src_fd, &st) == -1) - return nullptr; - uint64_t total = (uint64_t)st.st_size; + uint64_t total = std::filesystem::file_size(path); std::vector pieces; uint64_t pos = 0; pieces.reserve((total + PETAL_SIZE_MAX - 1) / PETAL_SIZE_MAX); diff --git a/src/vase/vase.cc b/src/vase/vase.cc index 9d04d35..e921a89 100644 --- a/src/vase/vase.cc +++ b/src/vase/vase.cc @@ -2,10 +2,16 @@ #include "utils/utils.h" #include "vase/iterators/line.h" -Vase::Vase(std::string path) { +Vase::Vase(std::filesystem::path path, std::filesystem::path swapdir) + : path(path), swapdir(swapdir) { + if (!std::filesystem::exists(swapdir) || !std::filesystem::is_directory(swapdir)) + throw std::runtime_error("Swap directory does not exist or is not a directory."); append = new AppendBuffer(); - original = new OriginalBuffer(); - root = create_file_shards(path, original); + original = new OriginalBuffer(swapdir); + if (std::filesystem::is_regular_file(path)) + root = Shard::from_file(path, original); + else + root = Shard::new_empty(original); history.push_back(root); Shard::retain(root); history_top = 0; @@ -94,7 +100,7 @@ void Vase::prune_history(uint64_t n) { history_top -= n; } -bool Vase::save(std::string path) { +bool Vase::save() { std::ofstream file(path, std::ios::binary); if (!file) return false; @@ -110,7 +116,7 @@ bool Vase::save(std::string path) { return true; } -bool Vase::save_swap(std::string path) { +bool Vase::save_swap() { } void Vase::insert(Point *point, char key) { @@ -120,9 +126,9 @@ void Vase::insert(Point *point, char key) { point->col++; uint64_t pos = append->append(key); Shard *inserted = new Petal(1, key == '\n', append, pos); - auto [left, right] = split_shard(root, offset_of(*point)); - Shard *left2 = append_leaf(left, inserted); - Shard *new_root = concat_shard(left2, right); + auto [left, right] = Shard::split(root, offset_of(*point)); + Shard *left2 = Shard::append_leaf(left, inserted); + Shard *new_root = Shard::concat(left2, right); Shard::release(left); Shard::release(right); Shard::release(left2); @@ -168,9 +174,9 @@ void Vase::_insert(Point *point, const char *data, uint64_t len) { point->col += col; } Shard *inserted = new Petal(len, lines, append, pos); - auto [left, right] = split_shard(root, offset); - Shard *left2 = append_leaf(left, inserted); - Shard *new_root = concat_shard(left2, right); + auto [left, right] = Shard::split(root, offset); + Shard *left2 = Shard::append_leaf(left, inserted); + Shard *new_root = Shard::concat(left2, right); Shard::release(left); Shard::release(right); Shard::release(left2); @@ -193,9 +199,9 @@ void Vase::erase(Point *point, uint64_t amount, Direction dir) { if (start_offset > end_offset) std::swap(start_offset, end_offset); uint64_t count = end_offset - start_offset; - auto [a, b] = split_shard(root, start_offset); - auto [d, c] = split_shard(b, count); - Shard *new_root = concat_shard(a, c); + auto [a, b] = Shard::split(root, start_offset); + auto [d, c] = Shard::split(b, count); + Shard *new_root = Shard::concat(a, c); Shard::release(a); Shard::release(b); Shard::release(c); @@ -212,9 +218,9 @@ void Vase::erase(Range range) { uint64_t start_offset = offset_of(start); uint64_t end_offset = offset_of(end); uint64_t count = end_offset - start_offset; - auto [a, b] = split_shard(root, start_offset); - auto [d, c] = split_shard(b, count); - Shard *new_root = concat_shard(a, c); + auto [a, b] = Shard::split(root, start_offset); + auto [d, c] = Shard::split(b, count); + Shard *new_root = Shard::concat(a, c); Shard::release(a); Shard::release(b); Shard::release(c);