From fde27123cf57daccbb764126d90dcb7bb58d6d09 Mon Sep 17 00:00:00 2001 From: Humza Shahid Date: Tue, 2 Dec 2025 08:53:23 +0000 Subject: [PATCH] begin adjusting persistent-vector.sml so that it uses rope-like metadata, meaning relative index offsets to support efficient arbitrary insertion/deletion --- fcore/persistent-vector.sml | 42 ++++++++++++++++++++++++++++++------- temp.txt | 2 +- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/fcore/persistent-vector.sml b/fcore/persistent-vector.sml index 345f817..d5e1524 100644 --- a/fcore/persistent-vector.sml +++ b/fcore/persistent-vector.sml @@ -29,8 +29,14 @@ struct in if searchIdx = ~1 then false - else + else if searchIdx = 0 then isInRange (checkIdx, Vector.sub (nodes, searchIdx)) + else + let + val nextCheckIdx = checkIdx - Vector.sub (sizes, searchIdx - 1) + in + isInRange (nextCheckIdx, Vector.sub (nodes, searchIdx)) + end end | LEAF (values, sizes) => let @@ -56,8 +62,13 @@ struct BRANCH (nodes, sizes) => let val lastNode = Vector.sub (nodes, Vector.length nodes - 1) + val prevSize = + if Vector.length sizes > 1 then + Vector.sub (sizes, Vector.length sizes - 2) + else + 0 in - case helpAppend (start, finish, lastNode) of + case helpAppend (start - prevSize, finish - prevSize, lastNode) of UPDATE newLast => let val lastPos = Vector.length nodes - 1 @@ -68,9 +79,14 @@ struct UPDATE newNode end | APPEND newVec => - if Vector.length nodes + 1 > maxSize then - let val newNode = BRANCH (#[newVec], #[finish]) - in APPEND newNode + if Vector.length nodes = maxSize then + let + (* adjust "finish" so that it does not consider + * offset for "lower" vector *) + val finish = finish - Vector.sub (sizes, Vector.length sizes - 1) + val newNode = BRANCH (#[newVec], #[finish]) + in + APPEND newNode end else let @@ -83,8 +99,17 @@ struct end | LEAF (values, sizes) => if Vector.length values + 1 > maxSize then - let val newNode = LEAF (#[{start = start, finish = finish}], #[finish]) - in APPEND newNode + (* when we split a leaf into two vectors, + * we want to adjust the start and finish parameters + * so that they don't contain the offset relevant to the + * "lower" vector, which was split from *) + let + val prevFinish = Vector.sub (sizes, Vector.length sizes - 1) + val start = start - prevFinish + val finish = finish - prevFinish + val newNode = LEAF (#[{start = start, finish = finish}], #[finish]) + in + APPEND newNode end else let @@ -106,6 +131,9 @@ struct BRANCH (#[tree, newNode], #[maxSize, finish]) end + (* todo: modify below functions so that they also + * use rope-like metadata *) + fun getStart tree = case tree of LEAF (values, _) => Vector.sub (values, 0) diff --git a/temp.txt b/temp.txt index 0dac0f6..b0e341c 100644 --- a/temp.txt +++ b/temp.txt @@ -1 +1 @@ -hey hello +999999999999999999999999999999991111111111111111111111111111111122222222222222222222222222222222