From f5649b4ee96abf45d27e225076919c69208f2252 Mon Sep 17 00:00:00 2001 From: humzashahid Date: Thu, 14 Mar 2024 23:29:10 +0000 Subject: [PATCH] change utils.sml to run using rope (with line metadata) instead of tiny_rope, and verify that line metadata is correct --- rope.sml | 22 +++++++++++--- tiny_rope.sml | 6 ++-- utils.sml | 83 ++++++++++++++++++++++++++------------------------- 3 files changed, 63 insertions(+), 48 deletions(-) diff --git a/rope.sml b/rope.sml index 93cbaaf..015203c 100644 --- a/rope.sml +++ b/rope.sml @@ -7,6 +7,8 @@ sig val toString: t -> string val foldr: ('a * string * int vector -> 'a) * 'a * t -> 'a + (* The caller should not insert in the middle of a \r\n pair, + * or else line metadata will become invalid. *) val insert: int * string * t -> t (* The append and appendLine function both add a string to the end. @@ -16,6 +18,8 @@ sig val append: string * t -> t val appendLine: string * int vector * t -> t + (* The caller should not delete only a single character in a \r\n pair, + * because then line metadata will become invalid. *) val delete: int * int * t -> t (* This below function verifies that line metadata is as expected, @@ -546,6 +550,15 @@ struct in endInsert (rope, action) end + fun isDelLessThanTarget (str1, str2, vec, startPoint, endPoint) = + let + val vecLength = Vector.length vec - (endPoint - startPoint) + in + String.size str1 + String.size str2 <= targetLength + andalso vecLength <= targetVecLength + end + + fun delLeaf (startIdx, endIdx, str, vec) = if startIdx <= 0 andalso endIdx >= String.size str @@ -563,7 +576,7 @@ struct val endPoint = binSearch (endIdx, vec, 0, vecLength) val difference = endIdx - startIdx in - if isLessThanTarget (sub1, sub2) then + if isDelLessThanTarget (sub1, sub2, vec, startPoint, endPoint) then let val str = sub1 ^ sub2 val vecDifference = endPoint - startPoint @@ -599,7 +612,7 @@ struct then let val str = String.substring (str, 0, startIdx) - val midPoint = binSearch (startIdx, vec, 0, vecLength) + val midPoint = binSearch (startIdx, vec, 0, Vector.length vec - 1) val vec = if Vector.length vec = 0 then emptyVec else Vector.tabulate (midPoint, fn idx => Vector.sub (vec, idx)) @@ -609,7 +622,7 @@ struct else let val str = String.substring (str, endIdx, String.size str - endIdx) - val midPoint = binSearch (endIdx, vec, 0, vecLength) + val midPoint = binSearch (endIdx, vec, 0, Vector.length vec - 1) val vec = if Vector.length vec = 0 then emptyVec @@ -642,10 +655,11 @@ struct val (l, _) = del (startIdx, endIdx, l) val (r, _) = del (startIdx - lms, endIdx - lms, r) in - makeN2 (l, r) + (makeN2 (l, r), false) end | N1 t => del (startIdx, endIdx, t) | N0 (str, vec) => delLeaf (startIdx, endIdx, str, vec) + | _ => raise AuxConstructor fun delete (start, length, rope) = let val (rope, didIns) = del (start, start + length, rope) diff --git a/tiny_rope.sml b/tiny_rope.sml index d9e57fe..18ab7e1 100644 --- a/tiny_rope.sml +++ b/tiny_rope.sml @@ -305,10 +305,8 @@ struct else (L2 (sub1, sub2), true) end else if startIdx >= 0 andalso endIdx >= String.size str then - let - val str = String.substring (str, 0, startIdx) - in - (N0 str, false) + let val str = String.substring (str, 0, startIdx) + in (N0 str, false) end else let val str = String.substring (str, endIdx, String.size str - endIdx) diff --git a/utils.sml b/utils.sml index 986381a..c4d42aa 100644 --- a/utils.sml +++ b/utils.sml @@ -1,13 +1,13 @@ fun time_func title f = let - val title = String.concat ["Starting " , title , "..."] + val title = String.concat ["Starting ", title, "..."] val _ = (print title) - val start_time = Time.now() + val start_time = Time.now () val start_time = Time.toNanoseconds start_time - val x = f() - val end_time = Time.now() + val x = f () + val end_time = Time.now () val end_time = Time.toNanoseconds end_time - val time_diff = end_time - start_time + val time_diff = end_time - start_time val time_diff = LargeInt.toString time_diff val time_took = String.concat ["took ", time_diff, " nanoseconds\n"] val _ = (print time_took) @@ -16,38 +16,28 @@ fun time_func title f = end fun run_txns arr = - Vector.foldl + Vector.foldl (fn ((pos, del_num, ins_str), rope) => - let - val rope = - if del_num > 0 - then TinyRope.delete(pos, del_num, rope) - else rope - val str_size = String.size ins_str - val rope = - if str_size > 0 - then TinyRope.insert(pos, ins_str, rope) - else rope - in - rope - end) - TinyRope.empty arr + let + val rope = + if del_num > 0 then Rope.delete (pos, del_num, rope) else rope + val str_size = String.size ins_str + val rope = + if str_size > 0 then Rope.insert (pos, ins_str, rope) else rope + in + rope + end) Rope.empty arr -fun run_txns_time title arr = - let - val f = (fn () => run_txns arr) - in - time_func title f +fun run_txns_time title arr = + let val f = (fn () => run_txns arr) + in time_func title f end -fun run_to_string rope = - TinyRope.toString rope +fun run_to_string rope = Rope.toString rope fun run_to_string_time title rope = - let - val f = (fn () => run_to_string rope) - in - time_func title f + let val f = (fn () => run_to_string rope) + in time_func title f end fun run_txns_1000_times (counter, arr, total) = @@ -61,14 +51,14 @@ fun run_txns_1000_times (counter, arr, total) = end else let - val start_time = Time.now() + val start_time = Time.now () val start_time = Time.toNanoseconds start_time val _ = run_txns arr - val end_time = Time.now() + val end_time = Time.now () val end_time = Time.toNanoseconds end_time - val time_diff = end_time - start_time + val time_diff = end_time - start_time val counter = counter + 1 val total = time_diff + total in @@ -76,7 +66,7 @@ fun run_txns_1000_times (counter, arr, total) = end fun write_file filename acc = - let + let val str = String.concatWith "," acc val fd = TextIO.openOut filename val _ = TextIO.output (fd, str) handle e => (TextIO.closeOut fd; raise e) @@ -85,16 +75,29 @@ fun write_file filename acc = () end -val _ = +fun main () = let + (* Timing benchmarks. *) val start_time = LargeInt.fromInt 0 - val svelte = run_txns_1000_times (999 ,svelte_arr, start_time ) + val _ = run_txns_1000_times (999, svelte_arr, start_time) + val _ = run_txns_1000_times (999, rust_arr, start_time) + val _ = run_txns_1000_times (999, seph_arr, start_time) + val _ = run_txns_1000_times (999, automerge_arr, start_time) - val rust = run_txns_1000_times (999 ,rust_arr, start_time ) + (* Tests that line metadata is correct; will fail if incorrect. *) + val svelte = run_txns svelte_arr + val _ = Rope.verifyLines svelte - val seph = run_txns_1000_times (999, seph_arr, start_time) + val rust = run_txns rust_arr + val _ = Rope.verifyLines rust - val automerge = run_txns_1000_times (999, automerge_arr , start_time) + val seph = run_txns seph_arr + val _ = Rope.verifyLines seph + + val automerge = run_txns automerge_arr + val _ = Rope.verifyLines automerge in () end + +val _ = main ()