From 930669d8773ce51ed9ca7b24f5b9e1c4c86be7a1 Mon Sep 17 00:00:00 2001 From: yoshi~ Date: Wed, 12 Feb 2025 22:15:16 +0100 Subject: [PATCH] first pass split improvements --- src/iv.gleam | 71 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/src/iv.gleam b/src/iv.gleam index 84027a5..db841a0 100644 --- a/src/iv.gleam +++ b/src/iv.gleam @@ -2180,9 +2180,7 @@ pub fn split(array: Array(item), at index: Int) -> #(Array(item), Array(item)) { Split(prefix:, suffix:) -> { #(Array(shift:, root: prefix), Array(shift:, root: suffix)) } - EmptyPrefix(suffix:) -> { - #(Empty, Array(shift:, root: suffix)) - } + EmptyPrefix -> #(Empty, array) } } } @@ -2190,7 +2188,7 @@ pub fn split(array: Array(item), at index: Int) -> #(Array(item), Array(item)) { type SplitResult(item) { Split(prefix: Node(item), suffix: Node(item)) - EmptyPrefix(suffix: Node(item)) + EmptyPrefix } fn split_node(shift: Int, node: Node(item), index: Int) -> SplitResult(item) { @@ -2198,7 +2196,25 @@ fn split_node(shift: Int, node: Node(item), index: Int) -> SplitResult(item) { Balanced(children:, ..) -> { let node_index = bitwise_shift_right(index, shift) let index = index - bitwise_shift_left(node_index, shift) - split_children(shift, node_index, index, children) + + let child = vector.get(node_index + 1, children) + let child_shift = shift - branch_bits + let #(before_children, after_children) = + vector.split(node_index + 1, children) + + case split_node(child_shift, child, index) { + EmptyPrefix if node_index == 0 -> EmptyPrefix + EmptyPrefix -> { + let prefix = balanced(shift, before_children) + let suffix = balanced(shift, after_children) + Split(prefix:, suffix:) + } + Split(prefix:, suffix:) -> { + let prefix = balanced(shift, vector.append(before_children, prefix)) + let suffix = branch(shift, vector.set(1, after_children, suffix)) + Split(prefix:, suffix:) + } + } } Unbalanced(children:, sizes:) -> { let start_search_index = bitwise_shift_right(index, shift) @@ -2208,11 +2224,29 @@ fn split_node(shift: Int, node: Node(item), index: Int) -> SplitResult(item) { // node_index - 1 + 1 _ -> index - vector.get(node_index, sizes) } - split_children(shift, node_index, index, children) + + let child = vector.get(node_index + 1, children) + let child_shift = shift - branch_bits + let #(before_children, after_children) = + vector.split(node_index + 1, children) + + case split_node(child_shift, child, index) { + EmptyPrefix if node_index == 0 -> EmptyPrefix + EmptyPrefix -> { + let prefix = branch(shift, before_children) + let suffix = branch(shift, after_children) + Split(prefix:, suffix:) + } + Split(prefix:, suffix:) -> { + let prefix = branch(shift, vector.append(before_children, prefix)) + let suffix = branch(shift, vector.set(1, after_children, suffix)) + Split(prefix:, suffix:) + } + } } Leaf(children) -> case index { - 0 -> EmptyPrefix(suffix: node) + 0 -> EmptyPrefix _ -> { let #(before, after) = vector.split(index + 1, children) Split(prefix: Leaf(before), suffix: Leaf(after)) @@ -2221,29 +2255,6 @@ fn split_node(shift: Int, node: Node(item), index: Int) -> SplitResult(item) { } } -fn split_children(shift, node_index, index, children) -> SplitResult(item) { - let child = vector.get(node_index + 1, children) - let child_shift = shift - branch_bits - let #(before_children, after_children) = - vector.split(node_index + 1, children) - - case split_node(child_shift, child, index) { - EmptyPrefix(suffix:) if node_index == 0 -> { - EmptyPrefix(suffix: branch(shift, vector.set(1, after_children, suffix))) - } - EmptyPrefix(suffix:) -> { - let prefix = branch(shift, before_children) - let suffix = branch(shift, vector.set(1, after_children, suffix)) - Split(prefix:, suffix:) - } - Split(prefix:, suffix:) -> { - let prefix = branch(shift, vector.append(before_children, prefix)) - let suffix = branch(shift, vector.set(1, after_children, suffix)) - Split(prefix:, suffix:) - } - } -} - /// Remove up to `n` elements from the start of the array. /// /// If the array has less than `n` elements an empty array is returned. -- knotmirror 0.0.1