diff --git a/.clangd b/.clangd index 50f2ce8..f6eaf7f 100644 --- a/.clangd +++ b/.clangd @@ -1,3 +1,5 @@ Diagnostics: Suppress: - unused-includes +Completion: + HeaderInsertion: Never diff --git a/include/vase/buffer/append.h b/include/vase/buffer/append.h index b67cfd6..a1fa063 100644 --- a/include/vase/buffer/append.h +++ b/include/vase/buffer/append.h @@ -21,8 +21,8 @@ struct AppendBuffer : Buffer { ~AppendBuffer(); - inline void key(char c); - void append(const char *text, uint32_t length); + inline 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); uint32_t count_lines(uint32_t pos, uint32_t length); @@ -33,5 +33,5 @@ private: inline uint32_t find_newline(uint32_t target, uint32_t low, uint32_t high); - inline void _append(const char *text, uint32_t length); + inline uint32_t _append(const char *text, uint32_t length); }; diff --git a/include/vase/shard.h b/include/vase/shard.h index bcbd400..ba88b54 100644 --- a/include/vase/shard.h +++ b/include/vase/shard.h @@ -66,6 +66,7 @@ struct Petal : Shard { : Shard(ShardKind::Petal, length, lines), source(source), pos(pos) {}; }; -std::pair split(Shard *n, uint32_t offset); +std::pair split_shard(Shard *n, uint32_t offset); +ShardPtr concat_shard(ShardPtr left, ShardPtr right); void print_shard(const Shard *shard, int depth = 0); diff --git a/include/vase/vase.h b/include/vase/vase.h index a493668..a172e9a 100644 --- a/include/vase/vase.h +++ b/include/vase/vase.h @@ -25,4 +25,18 @@ struct Vase { 0 ); } + + 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); + + root = concat_shard( + concat_shard(left, inserted), + right + ); + } }; diff --git a/src/main.cc b/src/main.cc index ed2b851..532fdaa 100644 --- a/src/main.cc +++ b/src/main.cc @@ -15,5 +15,11 @@ int main() { print_shard(vase.root.ptr); + std::cout << "\n->\n\n"; + + vase.insert(14, "gr\ntt", 5); + + print_shard(vase.root.ptr); + return 0; } diff --git a/src/vase/buffer/append.cc b/src/vase/buffer/append.cc index c5d39a1..74e3046 100644 --- a/src/vase/buffer/append.cc +++ b/src/vase/buffer/append.cc @@ -12,7 +12,7 @@ AppendBuffer::~AppendBuffer() { free(p); } -inline void AppendBuffer::key(char c) { +inline uint32_t AppendBuffer::key(char c) { if (t_offset == CHUNK_SIZE) new_text_chunk(); @@ -24,9 +24,13 @@ inline void AppendBuffer::key(char c) { (*l_current)[l_offset++] = current_offset; } ++current_offset; + + return current_offset - 1; } -void AppendBuffer::append(const char *text, uint32_t length) { +uint32_t AppendBuffer::append(const char *text, uint32_t length, uint32_t *line_count) { + uint32_t start = current_offset; + while (length) { uint32_t space = CHUNK_SIZE - t_offset; @@ -36,11 +40,13 @@ void AppendBuffer::append(const char *text, uint32_t length) { } uint32_t copy = length < space ? length : space; - _append(text, copy); + *line_count += _append(text, copy); text += copy; length -= copy; } + + return start; } const char *AppendBuffer::read(uint32_t pos, uint32_t *out_len) { @@ -125,12 +131,13 @@ inline void AppendBuffer::new_line_chunk() { l_offset = 0; } -inline void AppendBuffer::_append(const char *text, uint32_t length) { +inline uint32_t AppendBuffer::_append(const char *text, uint32_t length) { memcpy((*t_current) + t_offset, text, length); const char *p = text; const char *end = text + length; + uint32_t start_index = l_offset; while (p < end) { p = (const char *)memchr(p, '\n', end - p); if (!p) @@ -143,4 +150,6 @@ inline void AppendBuffer::_append(const char *text, uint32_t length) { t_offset += length; current_offset += length; + + return l_offset - start_index; } diff --git a/src/vase/shard.cc b/src/vase/shard.cc index 29c9471..daf6578 100644 --- a/src/vase/shard.cc +++ b/src/vase/shard.cc @@ -1,64 +1,49 @@ #include "vase/shard.h" -std::pair split(Shard *n, uint32_t offset) { +std::pair split_shard(Shard *n, uint32_t offset) { if (!n) return {nullptr, nullptr}; - if (offset == 0) return {nullptr, ShardPtr(n)}; - if (offset == n->length) return {ShardPtr(n), nullptr}; if (n->kind == Shard::ShardKind::Branch) { - Branch *b = static_cast(n); + Branch *b = (Branch *)n; if (offset < b->left.ptr->length) { - auto [a, b2] = split(b->left.ptr, offset); - - return { - a, - ShardPtr(new Branch( - b2.ptr, - b->right.ptr - )) - }; + auto [a, b2] = split_shard(b->left.ptr, offset); + return {a, ShardPtr(new Branch(b2.ptr, b->right.ptr))}; } else { - auto [a, b2] = split( - b->right.ptr, - offset - b->left.ptr->length - ); - - return { - ShardPtr(new Branch( - b->left.ptr, - a.ptr - )), - b2 - }; + auto [a, b2] = split_shard(b->right.ptr, offset - b->left.ptr->length); + return {ShardPtr(new Branch(b->left.ptr, a.ptr)), b2}; } + } else { + Petal *p = (Petal *)n; + + auto left = new Petal( + offset, + p->source->count_lines(0, offset), + p->source, + p->pos + ); + auto right = new Petal( + p->length - offset, + p->source->count_lines(offset, p->length), + p->source, + p->pos + offset + ); + + return {ShardPtr(left), ShardPtr(right)}; } +} - Petal *p = static_cast(n); - - auto left = new Petal( - offset, - p->source->count_lines(0, offset), - p->source, - p->pos - ); - - auto right = new Petal( - p->length - offset, - p->source->count_lines(offset, p->length), - p->source, - p->pos + offset - ); - - return { - ShardPtr(left), - ShardPtr(right) - }; +ShardPtr concat_shard(ShardPtr left, ShardPtr right) { + if (!left.ptr) + return right; + if (!right.ptr) + return left; + return new Branch(left.ptr, right.ptr); } void print_shard(const Shard *shard, int depth) { @@ -68,7 +53,6 @@ void print_shard(const Shard *shard, int depth) { } std::string indent(depth * 2, ' '); - std::cout << indent; if (shard->kind == Shard::ShardKind::Branch) {