add function to extend an existing match, and add tests for it
This commit is contained in:
@@ -807,7 +807,7 @@ struct
|
|||||||
val matchAfterFinish = nextMatch (finish, tree, 1)
|
val matchAfterFinish = nextMatch (finish, tree, 1)
|
||||||
in
|
in
|
||||||
if matchAfterFinish <= finish then
|
if matchAfterFinish <= finish then
|
||||||
(* no match after the 'finish', so we just append *)
|
(* no match after the 'finish', so we can just append to 'tree' *)
|
||||||
append (start, finish, tree)
|
append (start, finish, tree)
|
||||||
else
|
else
|
||||||
let
|
let
|
||||||
@@ -825,6 +825,31 @@ struct
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
fun extendExistingMatch (start, newFinish, tree) =
|
||||||
|
let
|
||||||
|
val matchAfterFinish = nextMatch (newFinish, tree, 1)
|
||||||
|
val left = splitLeft (start, tree)
|
||||||
|
val left = append (start, newFinish, left)
|
||||||
|
in
|
||||||
|
if matchAfterFinish <= newFinish then
|
||||||
|
(* no match after newFinish, so we can return 'left'
|
||||||
|
* which has the newFinish appended *)
|
||||||
|
left
|
||||||
|
else
|
||||||
|
let
|
||||||
|
val right = splitRight (newFinish, tree)
|
||||||
|
|
||||||
|
val leftFinish = getFinishIdx left
|
||||||
|
val rightStartRelative = getStartIdx right
|
||||||
|
|
||||||
|
val rightStartAbsolute = rightStartRelative + leftFinish
|
||||||
|
val difference = rightStartAbsolute - matchAfterFinish
|
||||||
|
val right = decrementBy (difference, right)
|
||||||
|
in
|
||||||
|
merge (left, right)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
(* functions only for testing *)
|
(* functions only for testing *)
|
||||||
fun childrenHaveSameDepth (pos, nodes, expectedDepth) =
|
fun childrenHaveSameDepth (pos, nodes, expectedDepth) =
|
||||||
if pos = Vector.length nodes then
|
if pos = Vector.length nodes then
|
||||||
|
|||||||
@@ -45,6 +45,19 @@ struct
|
|||||||
loopInRange lst
|
loopInRange lst
|
||||||
end
|
end
|
||||||
|
|
||||||
|
fun printVec pv =
|
||||||
|
let
|
||||||
|
val outputList = PersistentVector.toList pv
|
||||||
|
val str =
|
||||||
|
List.map
|
||||||
|
(fn {start, finish} =>
|
||||||
|
"{start = " ^ Int.toString start ^ ", finish = "
|
||||||
|
^ Int.toString finish ^ "}") outputList
|
||||||
|
val str = String.concatWith "\n " str ^ "\n"
|
||||||
|
in
|
||||||
|
print str
|
||||||
|
end
|
||||||
|
|
||||||
val appendTests = describe "PersistentVector.append"
|
val appendTests = describe "PersistentVector.append"
|
||||||
[ test "contains appended values in range" (fn _ =>
|
[ test "contains appended values in range" (fn _ =>
|
||||||
let
|
let
|
||||||
@@ -508,5 +521,84 @@ struct
|
|||||||
end)
|
end)
|
||||||
]
|
]
|
||||||
|
|
||||||
val tests = [appendTests, toListTests, splitLeftTests, deleteTests]
|
val extendExistingMatchTests = describe "PersistentVector.extendExistingMatch"
|
||||||
|
[ test
|
||||||
|
"leaves subsequent matches untouched \
|
||||||
|
\if their 'finish' is greater than the extended finish"
|
||||||
|
(fn _ =>
|
||||||
|
let
|
||||||
|
(* arrange *)
|
||||||
|
val inputList =
|
||||||
|
[ {start = 1, finish = 1}
|
||||||
|
, {start = 2, finish = 2}
|
||||||
|
, {start = 3, finish = 3}
|
||||||
|
, {start = 4, finish = 4}
|
||||||
|
, {start = 5, finish = 5}
|
||||||
|
, {start = 60, finish = 60}
|
||||||
|
, {start = 70, finish = 70}
|
||||||
|
, {start = 80, finish = 80}
|
||||||
|
]
|
||||||
|
val pv = PersistentVector.fromList inputList
|
||||||
|
|
||||||
|
(* act *)
|
||||||
|
val pv = PersistentVector.extendExistingMatch (5, 50, pv)
|
||||||
|
|
||||||
|
(* assert *)
|
||||||
|
val outputList = PersistentVector.toList pv
|
||||||
|
val expectedOutput =
|
||||||
|
[ {start = 1, finish = 1}
|
||||||
|
, {start = 2, finish = 2}
|
||||||
|
, {start = 3, finish = 3}
|
||||||
|
, {start = 4, finish = 4}
|
||||||
|
, {start = 5, finish = 50}
|
||||||
|
, {start = 60, finish = 60}
|
||||||
|
, {start = 70, finish = 70}
|
||||||
|
, {start = 80, finish = 80}
|
||||||
|
]
|
||||||
|
in
|
||||||
|
Expect.isTrue (outputList = expectedOutput)
|
||||||
|
end)
|
||||||
|
, test
|
||||||
|
"removes subsequent matches whose 'finish' is less than \
|
||||||
|
\the newly extended element's 'finish'"
|
||||||
|
(fn _ =>
|
||||||
|
let
|
||||||
|
(* arrange *)
|
||||||
|
val inputList =
|
||||||
|
[ {start = 1, finish = 1}
|
||||||
|
, {start = 2, finish = 2}
|
||||||
|
, {start = 3, finish = 3}
|
||||||
|
, {start = 4, finish = 4}
|
||||||
|
, {start = 5, finish = 5}
|
||||||
|
, {start = 60, finish = 60}
|
||||||
|
, {start = 70, finish = 70}
|
||||||
|
, {start = 80, finish = 80}
|
||||||
|
]
|
||||||
|
val pv = PersistentVector.fromList inputList
|
||||||
|
|
||||||
|
(* act *)
|
||||||
|
val pv = PersistentVector.extendExistingMatch (5, 75, pv)
|
||||||
|
|
||||||
|
(* assert *)
|
||||||
|
val outputList = PersistentVector.toList pv
|
||||||
|
val expectedOutput =
|
||||||
|
[ {start = 1, finish = 1}
|
||||||
|
, {start = 2, finish = 2}
|
||||||
|
, {start = 3, finish = 3}
|
||||||
|
, {start = 4, finish = 4}
|
||||||
|
, {start = 5, finish = 75}
|
||||||
|
, {start = 80, finish = 80}
|
||||||
|
]
|
||||||
|
in
|
||||||
|
Expect.isTrue (outputList = expectedOutput)
|
||||||
|
end)
|
||||||
|
]
|
||||||
|
|
||||||
|
val tests =
|
||||||
|
[ appendTests
|
||||||
|
, toListTests
|
||||||
|
, splitLeftTests
|
||||||
|
, deleteTests
|
||||||
|
, extendExistingMatchTests
|
||||||
|
]
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user