modify next/prev match functions to index using rope-like metadata

This commit is contained in:
2025-12-03 11:00:02 +00:00
parent 22aa18699e
commit 0625c33bec
2 changed files with 49 additions and 20 deletions

View File

@@ -225,19 +225,34 @@ struct
let val {start, finish} = getStart tree let val {start, finish} = getStart tree
in loopNextMatch (start, finish, tree, count - 1) in loopNextMatch (start, finish, tree, count - 1)
end end
else if cursorIdx >= start andalso cursorIdx <= finish then else
let
in
if cursorIdx >= start andalso cursorIdx <= finish then
loopNextMatch (start, finish, tree, count) loopNextMatch (start, finish, tree, count)
else else
loopNextMatch (start, finish, tree, count - 1) loopNextMatch (start, finish, tree, count - 1)
end
end end
(* todo: modify below functions so that they also fun getLast (tree, acc) =
* use rope-like metadata *)
fun getLast tree =
case tree of case tree of
LEAF (values, _) => Vector.sub (values, Vector.length values - 1) LEAF (values, _) =>
| BRANCH (nodes, _) => getLast (Vector.sub (nodes, Vector.length nodes - 1)) let
val {start, finish} = Vector.sub (values, Vector.length values - 1)
in
{start = start + acc, finish = finish + acc}
end
| BRANCH (nodes, sizes) =>
let
val acc =
if Vector.length sizes > 1 then
acc + Vector.sub (sizes, Vector.length sizes - 1)
else
acc
in
getLast (Vector.sub (nodes, Vector.length nodes - 1), acc)
end
(* slightly tricky. (* slightly tricky.
* The `sizes` vector contains the last/finish position of the item * The `sizes` vector contains the last/finish position of the item
@@ -254,7 +269,7 @@ struct
* There might not be a previous index because the current index is 0. * There might not be a previous index because the current index is 0.
* In this case, either the call stack will handle it, * In this case, either the call stack will handle it,
* or the caller to `helpPrevMatch` will. *) * or the caller to `helpPrevMatch` will. *)
fun helpPrevMatch (cursorIdx, tree) = fun helpPrevMatch (cursorIdx, tree, acc) =
case tree of case tree of
LEAF (values, sizes) => LEAF (values, sizes) =>
let let
@@ -266,15 +281,18 @@ struct
let let
val result = Vector.sub (values, 0) val result = Vector.sub (values, 0)
in in
if #start result < cursorIdx then result if #start result < cursorIdx then
{start = #start result + acc, finish = #finish result + acc}
else {start = ~1, finish = ~1} else {start = ~1, finish = ~1}
end end
else else
let let
val current = Vector.sub (values, idx) val current = Vector.sub (values, idx)
val {start, finish} =
if cursorIdx > #start current then current
else Vector.sub (values, idx - 1)
in in
if cursorIdx > #start current then current {start = start + acc, finish = finish + acc}
else Vector.sub (values, idx - 1)
end end
end end
| BRANCH (nodes, sizes) => | BRANCH (nodes, sizes) =>
@@ -284,13 +302,23 @@ struct
if idx < 0 then if idx < 0 then
{start = ~1, finish = ~1} {start = ~1, finish = ~1}
else if idx = 0 then else if idx = 0 then
helpPrevMatch (cursorIdx, Vector.sub (nodes, idx)) helpPrevMatch (cursorIdx, Vector.sub (nodes, idx), acc)
else else
let let
val node = Vector.sub (nodes, idx) val node = Vector.sub (nodes, idx)
val result = helpPrevMatch (cursorIdx, node) val prevSize = Vector.sub (sizes, idx - 1)
val result = helpPrevMatch (cursorIdx - prevSize, node, acc + prevSize)
in in
if #start result = ~1 then getLast (Vector.sub (nodes, idx - 1)) if #start result = ~1 then
let
val prevPrevSize =
if idx - 2 < 0 then
0
else
Vector.sub (sizes, idx - 2)
in
getLast (Vector.sub (nodes, idx - 1), acc + prevPrevSize)
end
else result else result
end end
end end
@@ -300,10 +328,10 @@ struct
prevStart prevStart
else else
let let
val {start, finish} = helpPrevMatch (prevFinish - 1, tree) val {start, finish} = helpPrevMatch (prevFinish - 1, tree, 0)
in in
if start = ~1 then if start = ~1 then
let val {start, finish} = getLast tree let val {start, finish} = getLast (tree, ~1)
in loopPrevMatch (start, finish, tree, count - 1) in loopPrevMatch (start, finish, tree, count - 1)
end end
else else
@@ -315,10 +343,10 @@ struct
~1 ~1
else else
let let
val {start, finish} = helpPrevMatch (cursorIdx, tree) val {start, finish} = helpPrevMatch (cursorIdx, tree, 0)
in in
if start = ~1 then if start = ~1 then
let val {start, finish} = getLast tree let val {start, finish} = getLast (tree, ~1)
in loopPrevMatch (start, finish, tree, count - 1) in loopPrevMatch (start, finish, tree, count - 1)
end end
else if cursorIdx >= start andalso cursorIdx <= finish then else if cursorIdx >= start andalso cursorIdx <= finish then
@@ -327,6 +355,9 @@ struct
loopPrevMatch (start, finish, tree, count - 1) loopPrevMatch (start, finish, tree, count - 1)
end end
(* todo: modify below functions so that they also
* use rope-like metadata *)
datatype insert_result = INSERT_UPDATE of t | INSERT_SPLIT of t * t datatype insert_result = INSERT_UPDATE of t | INSERT_SPLIT of t * t
fun getMaxSize tree = fun getMaxSize tree =

View File

@@ -1,3 +1 @@
99999999999999999999999999999999 99999999999999999999999999999999
11111111111111111111111111111111
22222222222222222222222222222222