minor buffer object optimization

This commit is contained in:
Francesco Cozzuto
2021-12-08 18:15:59 +01:00
parent dbf1c325b0
commit 2a0af0f9bd
3 changed files with 101 additions and 6 deletions
+87
View File
@@ -0,0 +1,87 @@
fun newBytetree(leaf_size)
{
if leaf_size == none:
leaf_size = 64;
return { root: none, size: 0, leaf_size: leaf_size };
}
fun makeBufferIntoTree(buffer)
{
nleafs = 1.0 * count(data) / tree.leaf_size;
assert(type(nleafs) == type(0.0));
print('nleafs = ', nleafs, '\n');
leafs = [];
# Make a big buffer and then split it
# into `nleafs` slices, then store the
# slices into the `leafs` array.
leafs_buffer = newBuffer(nleafs * tree.leaf_size);
while count(leafs) < nleafs:
leafs[count(leafs)] =
sliceBuffer(leafs_buffer, i * tree.leaf_size, tree.leaf_size);
nodes = leafs;
while count(nodes) > 1:
{
temp = [];
npairs = count(nodes) / 2;
while count(temp) < npairs:
temp[count(temp)] = {
left : nodes[count(temp) * 2],
right: nodes[count(temp) * 2 + 1]
};
if npairs * 2 < count(nodes):
# There's an extra node we
# need to handle.
temp[count(temp)-1] = {
left: temp[count(temp)-1],
right: nodes[count(nodes)-1]
};
nodes = temp;
}
assert(count(nodes) == 1);
return nodes[0];
}
fun insertIntoBytetree(tree, data, index)
{
if index == none:
index = tree.size;
subtree = makeBufferIntoTree(data);
if tree.root == none:
{
tree.root = subtree;
return;
}
# Now find where to store this
# subtree.
current = tree.root;
rel_index = index;
while type(current) == type({}):
{
if rel_index < current.left_size:
current = current.left;
else
{
rel_index = rel_index - current.left_size;
current = current.right;
}
}
}
+1 -1
View File
@@ -36,7 +36,7 @@ fun locate(tree, index, path)
path[count(path)] = cursor; path[count(path)] = cursor;
while cursor.is_leaf == false: while not cursor.is_leaf:
{ {
if rindex < _count(cursor.left): if rindex < _count(cursor.left):
cursor = cursor.left; cursor = cursor.left;
+12 -4
View File
@@ -111,15 +111,18 @@ Object *Object_SliceBuffer(Object *buffer, int offset, int length, Heap *heap, E
return NULL; return NULL;
} }
if(buffer->type == &t_buffer)
{
BufferObject *original = (BufferObject*) buffer;
if(offset == 0 && length == original->size)
return buffer;
BufferSliceObject *slice = (BufferSliceObject*) Heap_Malloc(heap, &t_buffer_slice, error); BufferSliceObject *slice = (BufferSliceObject*) Heap_Malloc(heap, &t_buffer_slice, error);
if(slice == NULL) if(slice == NULL)
return NULL; return NULL;
if(buffer->type == &t_buffer)
{
BufferObject *original = (BufferObject*) buffer;
if(offset < 0 || offset >= original->size) if(offset < 0 || offset >= original->size)
{ {
Error_Report(error, 0, "offset out of range"); Error_Report(error, 0, "offset out of range");
@@ -146,6 +149,11 @@ Object *Object_SliceBuffer(Object *buffer, int offset, int length, Heap *heap, E
{ {
assert(buffer->type == &t_buffer_slice); assert(buffer->type == &t_buffer_slice);
BufferSliceObject *slice = (BufferSliceObject*) Heap_Malloc(heap, &t_buffer_slice, error);
if(slice == NULL)
return NULL;
BufferSliceObject *original = (BufferSliceObject*) buffer; BufferSliceObject *original = (BufferSliceObject*) buffer;
if(offset < 0 || offset >= original->length) if(offset < 0 || offset >= original->length)