From 23b7b8c8a8ac6fda8e52b0434da9c008e672cb5b Mon Sep 17 00:00:00 2001 From: Syed Daanish Date: Mon, 10 Aug 2026 14:21:46 +0100 Subject: [PATCH] Fix iteration and petal append bugs. --- .gitignore | 1 + include/internal/vase/shard.h | 3 +-- src/commands/ed/handle.cc | 2 +- src/internal/vase/iterators/petal.cc | 33 +++++++++++++++------------- src/internal/vase/shard.cc | 27 ++++++++++------------- src/internal/vase/vase.cc | 2 +- 6 files changed, 33 insertions(+), 35 deletions(-) diff --git a/.gitignore b/.gitignore index 782e984..67883c8 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ build/ .cache/ sample.txt +old* diff --git a/include/internal/vase/shard.h b/include/internal/vase/shard.h index 81e31c8..1787f82 100644 --- a/include/internal/vase/shard.h +++ b/include/internal/vase/shard.h @@ -30,8 +30,7 @@ struct Shard { static std::vector from_swap(std::filesystem::path &path, 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 *concat(Shard *a, Shard *b); static Shard *merge_leaves(Shard *a, Shard *b); static Shard *append(Shard *root, Shard *leaf); static Shard *build(Shard **pieces, uint64_t lo, uint64_t hi); diff --git a/src/commands/ed/handle.cc b/src/commands/ed/handle.cc index 9e3c163..06de350 100644 --- a/src/commands/ed/handle.cc +++ b/src/commands/ed/handle.cc @@ -34,7 +34,7 @@ bool Ed::handle(std::string cmd, bool eof) { throw ed_error("Line 0 is invalid."); if (line > vase.lines()) throw ed_error("Line position too high."); - Iterator it = vase.iterate(line - 1, Direction::Backward); + Iterator it = vase.iterate(line - 1, Direction::Forward); it.next(); std::cout << it.line << std::endl; } break; diff --git a/src/internal/vase/iterators/petal.cc b/src/internal/vase/iterators/petal.cc index 0049e44..174166a 100644 --- a/src/internal/vase/iterators/petal.cc +++ b/src/internal/vase/iterators/petal.cc @@ -88,24 +88,16 @@ void PetalIterator::seek_line(uint64_t line) { } else { auto *b = (Branch *)curr; uint64_t left_lines = b->left->lines; - if (dir == Direction::Forward) { - if (line < left_lines) { + if (line <= left_lines) { + if (dir == Direction::Forward) stack.push_back(b->right); - curr = b->left; - } else { - line -= left_lines; - global_offset += b->left->length; - curr = b->right; - } + curr = b->left; } else { - if (line <= left_lines) { - curr = b->left; - } else { - line -= left_lines; + line -= left_lines; + if (dir == Direction::Backward) stack.push_back(b->left); - global_offset += b->left->length; - curr = b->right; - } + global_offset += b->left->length; + curr = b->right; } } } @@ -115,6 +107,17 @@ void PetalIterator::seek_line(uint64_t line) { Petal *PetalIterator::_next(uint64_t *offset) { while (true) { if (petal) { + if (dir == Direction::Forward) { + if (petal_offset == petal->length) { + petal = nullptr; + continue; + } + } else { + if (petal_offset == 0) { + petal = nullptr; + continue; + } + } auto ret = petal; last_offset = global_offset; if (dir == Direction::Forward) diff --git a/src/internal/vase/shard.cc b/src/internal/vase/shard.cc index 0132774..ed87fb2 100644 --- a/src/internal/vase/shard.cc +++ b/src/internal/vase/shard.cc @@ -89,28 +89,25 @@ Shard *balance(Shard *node) { return node; } -Shard *Shard::merge(Shard *a, Shard *b) { +Shard *Shard::concat(Shard *a, Shard *b) { if (!a) return (Shard::retain(b), b); if (!b) return (Shard::retain(a), a); - if (a->height > b->height + 1) { Branch *ba = (Branch *)a; - Shard *r = merge(ba->right, b); + Shard *r = concat(ba->right, b); Shard *out = balance(new Branch(ba->left, r)); Shard::release(r); return out; } - if (b->height > a->height + 1) { Branch *bb = (Branch *)b; - Shard *l = merge(a, bb->left); + Shard *l = concat(a, bb->left); Shard *out = balance(new Branch(l, bb->right)); Shard::release(l); return out; } - return balance(new Branch(a, b)); } @@ -129,12 +126,12 @@ std::pair Shard::split(Shard *n, uint64_t offset) { Branch *b = (Branch *)n; if (offset < b->left->length) { auto [a, b2] = split(b->left, offset); - Shard *right = merge(b2, b->right); + Shard *right = concat(b2, b->right); Shard::release(b2); return {a, right}; } else { auto [a, b2] = split(b->right, offset - b->left->length); - Shard *left = merge(b->left, a); + Shard *left = concat(b->left, a); Shard::release(a); return {left, b2}; } @@ -162,11 +159,13 @@ std::pair Shard::split(Shard *n, uint64_t offset) { Shard *Shard::merge_leaves(Shard *a, Shard *b) { if (a->kind != Shard::Kind::Petal || b->kind != Shard::Kind::Petal) - return merge(a, b); + return concat(a, b); + if (a->length + b->length > PETAL_SIZE_MAX) + return concat(a, b); Petal *pa = (Petal *)a; Petal *pb = (Petal *)b; if (!(pa->source == pb->source && pa->pos + pa->length == pb->pos)) - return merge(a, b); + return concat(a, b); return new Petal( pa->length + pb->length, pa->lines + pb->lines, @@ -180,7 +179,7 @@ Shard *Shard::append(Shard *root, Shard *leaf) { Shard::retain(leaf); return leaf; } - if (root->kind == Shard::Kind::Petal && root->length < PETAL_SIZE_MAX) + if (root->kind == Shard::Kind::Petal) return merge_leaves(root, leaf); Branch *b = (Branch *)root; auto new_right = append(b->right, leaf); @@ -189,10 +188,6 @@ Shard *Shard::append(Shard *root, Shard *leaf) { return out; } -Shard *Shard::concat(Shard *left, Shard *right) { - return merge(left, right); -} - Shard *Shard::build(Shard **pieces, uint64_t lo, uint64_t hi) { if (hi - lo == 1) return pieces[lo]; @@ -206,7 +201,7 @@ Shard *Shard::build(Shard **pieces, uint64_t lo, uint64_t hi) { } static bool write_all(int fd, const void *data, size_t len) { - const char *p = static_cast(data); + const char *p = (const char *)data; while (len > 0) { ssize_t n = write(fd, p, len); if (n > 0) { diff --git a/src/internal/vase/vase.cc b/src/internal/vase/vase.cc index 0a9ea3b..c41985e 100644 --- a/src/internal/vase/vase.cc +++ b/src/internal/vase/vase.cc @@ -93,7 +93,7 @@ Vase &Vase::operator=(Vase &&other) noexcept { uint64_t Vase::length() { if (!root) return 0; - return root->length; + return root->length + posix_ending; } uint64_t Vase::lines() {