diff --git a/include/vase/buffer/append.h b/include/vase/buffer/append.h index a1fa063..2d16d45 100644 --- a/include/vase/buffer/append.h +++ b/include/vase/buffer/append.h @@ -21,7 +21,7 @@ struct AppendBuffer : Buffer { ~AppendBuffer(); - inline uint32_t key(char c); + uint32_t key(char c); uint32_t append(const char *text, uint32_t length, uint32_t *line_count); const char *read(uint32_t pos, uint32_t *out_len); diff --git a/include/vase/vase.h b/include/vase/vase.h index da8a0bb..efd7f26 100644 --- a/include/vase/vase.h +++ b/include/vase/vase.h @@ -15,31 +15,54 @@ struct Vase { ShardPtr root; - Vase(char *data, uint32_t length) - : original(data, length), - append() { - root = new Petal( - length, - original.newlines.size(), - &original, - 0 - ); + Vase(char *data, uint32_t length) : original(data, length), append() { + root = new Petal(length, original.newlines.size(), &original, 0); } uint32_t length() { return root.ptr->length; } + std::string to_string() { + std::string out; + flatten(root.ptr, out); + return out; + } + + void type(uint32_t offset, char key) { + uint32_t pos = append.key(key); + ShardPtr inserted = new Petal(1, key == '\n', &append, pos); + auto [left, right] = split_shard(root.ptr, offset); + left = append_leaf(left.ptr, inserted.ptr); + root = concat_shard(left, right); + } + void insert(uint32_t offset, const char *data, uint32_t len) { uint32_t lines = 0; uint32_t pos = append.append(data, len, &lines); - ShardPtr inserted = new Petal(len, lines, &append, pos); - auto [left, right] = split_shard(root.ptr, offset); - left = append_leaf(left.ptr, inserted.ptr); - root = concat_shard(left, right); } + + void flatten(Shard *s, std::string &out) { + if (s->kind == Shard::ShardKind::Petal) { + auto *p = static_cast(s); + uint32_t remaining = p->length; + uint32_t pos = p->pos; + while (remaining) { + uint32_t got; + const char *data = p->source->read(pos, &got); + uint32_t take = std::min(got, remaining); + out.append(data, take); + remaining -= take; + pos += take; + } + } else { + auto *b = static_cast(s); + flatten(b->left.ptr, out); + flatten(b->right.ptr, out); + } + } }; diff --git a/src/main.cc b/src/main.cc index 4814af3..d1a7e98 100644 --- a/src/main.cc +++ b/src/main.cc @@ -4,22 +4,32 @@ #include "vase/vase.h" int main() { - const char *text_o = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + const char *text_o = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\n"; uint32_t len = strlen(text_o); char *text = strdup(text_o); Vase vase = Vase(text, len); + std::cout << vase.to_string() << "\n"; + print_shard(vase.root.ptr); std::cout << "\n->\n\n"; vase.insert(14, "gr\ntt", 5); - vase.insert(200, "gr\ntt", 5); + vase.insert(58, "gr\ntt", 5); vase.insert(100, "gr\ntt", 5); vase.insert(20, "gr\ntt", 5); + vase.type(5, 'k'); + vase.type(6, 'l'); + vase.type(7, 'm'); + vase.type(8, 'n'); + print_shard(vase.root.ptr); + std::cout << "\n" + << vase.to_string(); + return 0; } diff --git a/src/vase/buffer/append.cc b/src/vase/buffer/append.cc index 74e3046..03874aa 100644 --- a/src/vase/buffer/append.cc +++ b/src/vase/buffer/append.cc @@ -12,7 +12,7 @@ AppendBuffer::~AppendBuffer() { free(p); } -inline uint32_t AppendBuffer::key(char c) { +uint32_t AppendBuffer::key(char c) { if (t_offset == CHUNK_SIZE) new_text_chunk(); diff --git a/src/vase/shard.cc b/src/vase/shard.cc index 68c4aa5..c698aa9 100644 --- a/src/vase/shard.cc +++ b/src/vase/shard.cc @@ -155,10 +155,8 @@ ShardPtr append_leaf(Shard *root, Shard *leaf) { return ShardPtr(leaf); if (root->kind == Shard::ShardKind::Petal) return merge_leaves(root, leaf); - Branch *b = (Branch *)root; auto new_right = append_leaf(b->right.ptr, leaf); - return balance(new Branch(b->left.ptr, new_right.ptr)); }