X-Git-Url: http://nitlanguage.org diff --git a/lib/standard/ropes.nit b/lib/standard/ropes.nit index d41c021..644e3dc 100644 --- a/lib/standard/ropes.nit +++ b/lib/standard/ropes.nit @@ -16,8 +16,12 @@ # # Ropes are a data structure introduced in a 1995 paper from # Hans J. Boehm, Russ Atkinson and Michael Plass. -# See : `Ropes : an Alternative to Strings`, `Software - Practice and Experience, -# Vol. 25(12), 1315-1330 (December 1995)`. +# +# See: +# +# > Ropes: an Alternative to Strings, +# > *Software - Practice and Experience*, +# > Vol. 25(12), 1315-1330 (December 1995). # # The implementation developed here provides an automatic change # of data structure depending on the length of the leaves. @@ -32,11 +36,11 @@ # # Example : # -# ` Concat ` -# ` / \ ` -# ` Concat Concat ` -# ` / \ / \ ` -# `"My" " Name" " is" " Simon." ` +# Concat +# / \ +# Concat Concat +# / \ / \ +# "My" " Name" " is" " Simon." # # Note that the above example is not representative of the actual implementation # of `Ropes`, since short leaves are merged to keep the rope at an acceptable @@ -63,20 +67,20 @@ private abstract class RopeString super Rope super String - redef fun chars is cached do return new RopeChars(self) + redef var chars is lazy do return new RopeChars(self) end # Node that represents a concatenation between two `String` private class Concat super RopeString - redef var length: Int + redef var length: Int is noinit redef fun substrings do return new RopeSubstrings(self) redef fun empty do return "" - redef fun to_cstring is cached do + redef var to_cstring is lazy do var len = length var ns = new NativeString(len + 1) ns[len] = '\0' @@ -94,10 +98,8 @@ private class Concat # Right child of the node var right: String - init(l: String, r: String) is old_style_init do - left = l - right = r - length = l.length + r.length + init do + length = left.length + right.length end redef fun output do @@ -151,7 +153,7 @@ private class Concat else var r = right var rlen = r.length - if rlen + slen > maxlen then return new Concat(left, new Concat(r, s)) + if rlen + slen > maxlen then return new Concat(self, s) return new Concat(left, r + s) end end @@ -175,7 +177,7 @@ class RopeBuffer super Rope super Buffer - redef fun chars: Sequence[Char] is cached do return new RopeBufferChars(self) + redef var chars: Sequence[Char] is lazy do return new RopeBufferChars(self) # The final string being built on the fly private var str: String is noinit @@ -229,6 +231,7 @@ class RopeBuffer var nns = new NativeString(buf_size) var blen = rpos - dumped ns.copy_to(nns, blen, dumped, 0) + ns = nns dumped = 0 rpos = blen written = false @@ -241,6 +244,10 @@ class RopeBuffer length = 0 rpos = 0 dumped = 0 + if written then + ns = new NativeString(buf_size) + written = false + end end redef fun substring(from, count) do @@ -383,15 +390,12 @@ class RopeBuffer end redef fun reverse do - str = str.reversed - var nns = new NativeString(buf_size) - var j = rpos - var mits = ns - for i in [0 .. rpos[ do - nns[i] = mits[j] - j -= 1 + # Flush the buffer in order to only have to reverse `str`. + if rpos > 0 and dumped != rpos then + str += new FlatString.with_infos(ns, rpos - dumped, dumped, rpos - 1) + dumped = rpos end - ns = nns + str = str.reversed end redef fun upper do @@ -774,17 +778,15 @@ end private class RopeChars super StringCharView - var tgt: RopeString - - init(s: RopeString) is old_style_init do tgt = s + redef type SELFTYPE: RopeString redef fun [](i) do - return tgt[i] + return target[i] end - redef fun iterator_from(i) do return new RopeIter.from(tgt, i) + redef fun iterator_from(i) do return new RopeIter.from(target, i) - redef fun reverse_iterator_from(i) do return new RopeReviter.from(tgt, i) + redef fun reverse_iterator_from(i) do return new RopeReviter.from(target, i) end