Make basic (unbalanced) insertion work.

This commit is contained in:
2026-07-28 03:26:28 +01:00
parent 92f59cbb86
commit 7503561c40
7 changed files with 70 additions and 54 deletions
+2
View File
@@ -1,3 +1,5 @@
Diagnostics: Diagnostics:
Suppress: Suppress:
- unused-includes - unused-includes
Completion:
HeaderInsertion: Never
+3 -3
View File
@@ -21,8 +21,8 @@ struct AppendBuffer : Buffer {
~AppendBuffer(); ~AppendBuffer();
inline void key(char c); inline uint32_t key(char c);
void append(const char *text, uint32_t length); uint32_t append(const char *text, uint32_t length, uint32_t *line_count);
const char *read(uint32_t pos, uint32_t *out_len); const char *read(uint32_t pos, uint32_t *out_len);
uint32_t count_lines(uint32_t pos, uint32_t length); 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 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);
}; };
+2 -1
View File
@@ -66,6 +66,7 @@ struct Petal : Shard {
: Shard(ShardKind::Petal, length, lines), source(source), pos(pos) {}; : Shard(ShardKind::Petal, length, lines), source(source), pos(pos) {};
}; };
std::pair<ShardPtr, ShardPtr> split(Shard *n, uint32_t offset); std::pair<ShardPtr, ShardPtr> split_shard(Shard *n, uint32_t offset);
ShardPtr concat_shard(ShardPtr left, ShardPtr right);
void print_shard(const Shard *shard, int depth = 0); void print_shard(const Shard *shard, int depth = 0);
+14
View File
@@ -25,4 +25,18 @@ struct Vase {
0 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
);
}
}; };
+6
View File
@@ -15,5 +15,11 @@ int main() {
print_shard(vase.root.ptr); print_shard(vase.root.ptr);
std::cout << "\n->\n\n";
vase.insert(14, "gr\ntt", 5);
print_shard(vase.root.ptr);
return 0; return 0;
} }
+13 -4
View File
@@ -12,7 +12,7 @@ AppendBuffer::~AppendBuffer() {
free(p); free(p);
} }
inline void AppendBuffer::key(char c) { inline uint32_t AppendBuffer::key(char c) {
if (t_offset == CHUNK_SIZE) if (t_offset == CHUNK_SIZE)
new_text_chunk(); new_text_chunk();
@@ -24,9 +24,13 @@ inline void AppendBuffer::key(char c) {
(*l_current)[l_offset++] = current_offset; (*l_current)[l_offset++] = current_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) { while (length) {
uint32_t space = CHUNK_SIZE - t_offset; 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; uint32_t copy = length < space ? length : space;
_append(text, copy); *line_count += _append(text, copy);
text += copy; text += copy;
length -= copy; length -= copy;
} }
return start;
} }
const char *AppendBuffer::read(uint32_t pos, uint32_t *out_len) { const char *AppendBuffer::read(uint32_t pos, uint32_t *out_len) {
@@ -125,12 +131,13 @@ inline void AppendBuffer::new_line_chunk() {
l_offset = 0; 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); memcpy((*t_current) + t_offset, text, length);
const char *p = text; const char *p = text;
const char *end = text + length; const char *end = text + length;
uint32_t start_index = l_offset;
while (p < end) { while (p < end) {
p = (const char *)memchr(p, '\n', end - p); p = (const char *)memchr(p, '\n', end - p);
if (!p) if (!p)
@@ -143,4 +150,6 @@ inline void AppendBuffer::_append(const char *text, uint32_t length) {
t_offset += length; t_offset += length;
current_offset += length; current_offset += length;
return l_offset - start_index;
} }
+30 -46
View File
@@ -1,64 +1,49 @@
#include "vase/shard.h" #include "vase/shard.h"
std::pair<ShardPtr, ShardPtr> split(Shard *n, uint32_t offset) { std::pair<ShardPtr, ShardPtr> split_shard(Shard *n, uint32_t offset) {
if (!n) if (!n)
return {nullptr, nullptr}; return {nullptr, nullptr};
if (offset == 0) if (offset == 0)
return {nullptr, ShardPtr(n)}; return {nullptr, ShardPtr(n)};
if (offset == n->length) if (offset == n->length)
return {ShardPtr(n), nullptr}; return {ShardPtr(n), nullptr};
if (n->kind == Shard::ShardKind::Branch) { if (n->kind == Shard::ShardKind::Branch) {
Branch *b = static_cast<Branch *>(n); Branch *b = (Branch *)n;
if (offset < b->left.ptr->length) { if (offset < b->left.ptr->length) {
auto [a, b2] = split(b->left.ptr, offset); auto [a, b2] = split_shard(b->left.ptr, offset);
return {a, ShardPtr(new Branch(b2.ptr, b->right.ptr))};
return {
a,
ShardPtr(new Branch(
b2.ptr,
b->right.ptr
))
};
} else { } else {
auto [a, b2] = split( auto [a, b2] = split_shard(b->right.ptr, offset - b->left.ptr->length);
b->right.ptr, return {ShardPtr(new Branch(b->left.ptr, a.ptr)), b2};
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<Petal *>(n); ShardPtr concat_shard(ShardPtr left, ShardPtr right) {
if (!left.ptr)
auto left = new Petal( return right;
offset, if (!right.ptr)
p->source->count_lines(0, offset), return left;
p->source, return new Branch(left.ptr, right.ptr);
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)
};
} }
void print_shard(const Shard *shard, int depth) { 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::string indent(depth * 2, ' ');
std::cout << indent; std::cout << indent;
if (shard->kind == Shard::ShardKind::Branch) { if (shard->kind == Shard::ShardKind::Branch) {