From 2a0af0f9bd33a4031ddc15c4be57d377dd849ae5 Mon Sep 17 00:00:00 2001 From: Francesco Cozzuto Date: Wed, 8 Dec 2021 18:15:59 +0100 Subject: [PATCH] minor buffer object optimization --- samples/bytetree.noja | 87 ++++++++++++++++++++++++++++++++++++++++++ samples/tree.noja | 2 +- src/objects/o_buffer.c | 18 ++++++--- 3 files changed, 101 insertions(+), 6 deletions(-) create mode 100644 samples/bytetree.noja diff --git a/samples/bytetree.noja b/samples/bytetree.noja new file mode 100644 index 0000000..3880317 --- /dev/null +++ b/samples/bytetree.noja @@ -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; + } + } + + +} \ No newline at end of file diff --git a/samples/tree.noja b/samples/tree.noja index 8210df9..c18094c 100644 --- a/samples/tree.noja +++ b/samples/tree.noja @@ -36,7 +36,7 @@ fun locate(tree, index, path) path[count(path)] = cursor; - while cursor.is_leaf == false: + while not cursor.is_leaf: { if rindex < _count(cursor.left): cursor = cursor.left; diff --git a/src/objects/o_buffer.c b/src/objects/o_buffer.c index ece8001..92f4302 100644 --- a/src/objects/o_buffer.c +++ b/src/objects/o_buffer.c @@ -111,15 +111,18 @@ Object *Object_SliceBuffer(Object *buffer, int offset, int length, Heap *heap, E return NULL; } - BufferSliceObject *slice = (BufferSliceObject*) Heap_Malloc(heap, &t_buffer_slice, error); - - if(slice == 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); + + if(slice == NULL) + return NULL; + if(offset < 0 || offset >= original->size) { 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); + BufferSliceObject *slice = (BufferSliceObject*) Heap_Malloc(heap, &t_buffer_slice, error); + + if(slice == NULL) + return NULL; + BufferSliceObject *original = (BufferSliceObject*) buffer; if(offset < 0 || offset >= original->length)