fix calculation of number to decrement by in 'PersistentVector.delete', after additional test showed that calculation resulted in incorrect metadata. (Todo: just implement function to merge left and right subtrees.)
This commit is contained in:
@@ -548,67 +548,77 @@ struct
|
|||||||
fun merge (left, right) = raise Fail "unimplemennted"
|
fun merge (left, right) = raise Fail "unimplemennted"
|
||||||
|
|
||||||
fun delete (start, length, tree) =
|
fun delete (start, length, tree) =
|
||||||
let
|
if isEmpty tree then
|
||||||
val finish = start + length
|
empty
|
||||||
val matchBeforeStart = prevMatch (start, tree, 1)
|
else
|
||||||
val matchAfterFinish = nextMatch (finish, tree, 1)
|
let
|
||||||
in
|
val finish = start + length
|
||||||
if matchBeforeStart = ~1 andalso matchAfterFinish = ~1 then
|
val matchBeforeStart = prevMatch (start, tree, 1)
|
||||||
empty
|
val matchBeforeStart =
|
||||||
else if matchAfterFinish = ~1 then
|
if matchBeforeStart >= start then
|
||||||
(* there is no match after 'finish', so just split left.
|
~1
|
||||||
* No need to decrement or split right,
|
|
||||||
* because the right vector would be empty. *)
|
|
||||||
splitLeft (start, tree)
|
|
||||||
else if matchBeforeStart = ~1 then
|
|
||||||
(* We don't want to use left split
|
|
||||||
* because there are no elements
|
|
||||||
* before the deletion range's 'start'.
|
|
||||||
* So we make a right split and then decrement it. *)
|
|
||||||
let
|
|
||||||
val right = splitRight (finish, tree)
|
|
||||||
in
|
|
||||||
if isEmpty right then
|
|
||||||
empty
|
|
||||||
else
|
else
|
||||||
let
|
matchBeforeStart
|
||||||
val startIdx = getStartIdx right
|
val matchAfterFinish = nextMatch (finish, tree, 1)
|
||||||
val difference = matchAfterFinish - startIdx
|
in
|
||||||
in
|
if matchBeforeStart = ~1 andalso matchAfterFinish = ~1 then
|
||||||
if difference = 0 then
|
empty
|
||||||
right
|
else if matchAfterFinish = ~1 then
|
||||||
else if isEmpty right then
|
(* there is no match after 'finish', so just split left.
|
||||||
empty
|
* No need to decrement or split right,
|
||||||
else
|
* because the right vector would be empty. *)
|
||||||
decrementBy (difference, right)
|
splitLeft (start, tree)
|
||||||
end
|
else if matchBeforeStart = ~1 then
|
||||||
end
|
(* We don't want to use left split
|
||||||
else
|
* because there are no elements
|
||||||
let
|
* before the deletion range's 'start'.
|
||||||
val left = splitLeft (start, tree)
|
* So we make a right split and then decrement it. *)
|
||||||
val right = splitRight (finish, tree)
|
let
|
||||||
in
|
val right = splitRight (finish, tree)
|
||||||
if isEmpty right then
|
in
|
||||||
left
|
if isEmpty right then
|
||||||
else
|
empty
|
||||||
let
|
else
|
||||||
val leftSize = getFinishIdx left
|
let
|
||||||
val rightStartRelative = getStartIdx right
|
val startIdx = getStartIdx right
|
||||||
|
val shouldBeStartIdx = matchAfterFinish - length
|
||||||
|
val difference = startIdx - shouldBeStartIdx
|
||||||
|
in
|
||||||
|
if difference = 0 then
|
||||||
|
right
|
||||||
|
else if isEmpty right then
|
||||||
|
empty
|
||||||
|
else
|
||||||
|
decrementBy (difference, right)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
let
|
||||||
|
val left = splitLeft (start, tree)
|
||||||
|
val right = splitRight (finish, tree)
|
||||||
|
in
|
||||||
|
if isEmpty right then
|
||||||
|
left
|
||||||
|
else
|
||||||
|
let
|
||||||
|
val leftSize = getFinishIdx left
|
||||||
|
val rightStartRelative = getStartIdx right
|
||||||
|
val rightStartAbsolute = leftSize + rightStartRelative
|
||||||
|
|
||||||
val rightStartAbsolute = leftSize + rightStartRelative
|
val shouldBeStartIdx = matchAfterFinish - length
|
||||||
val difference = matchAfterFinish - rightStartAbsolute
|
val difference = rightStartAbsolute - shouldBeStartIdx
|
||||||
in
|
in
|
||||||
if difference = 0 then
|
if difference = 0 then
|
||||||
merge (left, right)
|
|
||||||
else
|
|
||||||
let
|
|
||||||
val right = decrementBy (difference, right)
|
|
||||||
in
|
|
||||||
merge (left, right)
|
merge (left, right)
|
||||||
end
|
else
|
||||||
end
|
let
|
||||||
end
|
val right = decrementBy (difference, right)
|
||||||
end
|
in
|
||||||
|
merge (left, right)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
(* functions only for testing *)
|
(* functions only for testing *)
|
||||||
fun fromListLoop (lst, acc) =
|
fun fromListLoop (lst, acc) =
|
||||||
|
|||||||
@@ -342,6 +342,39 @@ struct
|
|||||||
in
|
in
|
||||||
Expect.isTrue (outputList = expectedOutput)
|
Expect.isTrue (outputList = expectedOutput)
|
||||||
end)
|
end)
|
||||||
|
, test
|
||||||
|
"decrements subsequent elements correctly \
|
||||||
|
\when deletion range is before first element to middle element"
|
||||||
|
(fn _ =>
|
||||||
|
let
|
||||||
|
(* arrange *)
|
||||||
|
val inputList =
|
||||||
|
[ {start = 1, finish = 1}
|
||||||
|
, {start = 2, finish = 2}
|
||||||
|
, {start = 3, finish = 3}
|
||||||
|
, {start = 4, finish = 4}
|
||||||
|
, {start = 50, finish = 50}
|
||||||
|
, {start = 60, finish = 60}
|
||||||
|
, {start = 70, finish = 70}
|
||||||
|
, {start = 80, finish = 80}
|
||||||
|
]
|
||||||
|
val pv = PersistentVector.fromList inputList
|
||||||
|
|
||||||
|
(* act *)
|
||||||
|
val pv = PersistentVector.delete (0, 3, pv)
|
||||||
|
|
||||||
|
(* assert *)
|
||||||
|
val outputList = PersistentVector.toList pv
|
||||||
|
val expectedOutput =
|
||||||
|
[ {start = 1, finish = 1}
|
||||||
|
, {start = 47, finish = 47}
|
||||||
|
, {start = 57, finish = 57}
|
||||||
|
, {start = 67, finish = 67}
|
||||||
|
, {start = 77, finish = 77}
|
||||||
|
]
|
||||||
|
in
|
||||||
|
Expect.isTrue (outputList = expectedOutput)
|
||||||
|
end)
|
||||||
]
|
]
|
||||||
|
|
||||||
val tests = [appendTests, toListTests, splitLeftTests, deleteTests]
|
val tests = [appendTests, toListTests, splitLeftTests, deleteTests]
|
||||||
|
|||||||
3
todo.md
3
todo.md
@@ -1,3 +1,4 @@
|
|||||||
# To-do list
|
# To-do list
|
||||||
- Implement `PersistentVector.delete` and test it
|
- Implement function to merge left and right subtrees for `PersistentVector.delete` function
|
||||||
|
- Test `PersistentVector.delete` function
|
||||||
- Implement 'yj' motion and add tests for it
|
- Implement 'yj' motion and add tests for it
|
||||||
|
|||||||
Reference in New Issue
Block a user