modify next/prev match functions to index using rope-like metadata
This commit is contained in:
@@ -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)
|
||||||
in
|
val {start, finish} =
|
||||||
if cursorIdx > #start current then current
|
if cursorIdx > #start current then current
|
||||||
else Vector.sub (values, idx - 1)
|
else Vector.sub (values, idx - 1)
|
||||||
|
in
|
||||||
|
{start = start + acc, finish = finish + acc}
|
||||||
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 =
|
||||||
|
|||||||
Reference in New Issue
Block a user