Make basic (unbalanced) insertion work.
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
Diagnostics:
|
Diagnostics:
|
||||||
Suppress:
|
Suppress:
|
||||||
- unused-includes
|
- unused-includes
|
||||||
|
Completion:
|
||||||
|
HeaderInsertion: Never
|
||||||
|
|||||||
@@ -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);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-34
@@ -1,45 +1,25 @@
|
|||||||
#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;
|
||||||
Petal *p = static_cast<Petal *>(n);
|
|
||||||
|
|
||||||
auto left = new Petal(
|
auto left = new Petal(
|
||||||
offset,
|
offset,
|
||||||
@@ -47,7 +27,6 @@ std::pair<ShardPtr, ShardPtr> split(Shard *n, uint32_t offset) {
|
|||||||
p->source,
|
p->source,
|
||||||
p->pos
|
p->pos
|
||||||
);
|
);
|
||||||
|
|
||||||
auto right = new Petal(
|
auto right = new Petal(
|
||||||
p->length - offset,
|
p->length - offset,
|
||||||
p->source->count_lines(offset, p->length),
|
p->source->count_lines(offset, p->length),
|
||||||
@@ -55,10 +34,16 @@ std::pair<ShardPtr, ShardPtr> split(Shard *n, uint32_t offset) {
|
|||||||
p->pos + offset
|
p->pos + offset
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {ShardPtr(left), ShardPtr(right)};
|
||||||
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) {
|
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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user