changelog.sh: also count commits
[nit.git] / lib / standard / ropes.nit
index db635d9..8186ec9 100644 (file)
 #
 # 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.
 #
 # 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
@@ -229,6 +233,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 +246,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
@@ -278,15 +287,7 @@ class RopeBuffer
                var slen = s.length
                length += slen
                var rp = rpos
-               if s isa Rope then
-                       if rp > 0 and dumped != rp then
-                               str += new FlatString.with_infos(ns, rp - dumped, dumped, rp - 1)
-                               dumped = rp
-                       end
-                       str = str + s
-                       return
-               end
-               if slen > maxlen then
+               if s isa Rope or slen > maxlen then
                        if rp > 0 and dumped != rp then
                                str += new FlatString.with_infos(ns, rp - dumped, dumped, rp - 1)
                                dumped = rp
@@ -326,12 +327,11 @@ class RopeBuffer
                        return
                end
                if slen <= remsp then
-                       sits.copy_to(ns, slen, begin, rp)
-                       if rp == buf_size then
-                               rpos = buf_size
+                       if remsp <= 0 then
                                dump_buffer
                                rpos = 0
                        else
+                               sits.copy_to(ns, slen, begin, rp)
                                rpos += slen
                        end
                else
@@ -346,14 +346,13 @@ class RopeBuffer
 
        redef fun add(c) do
                var rp = rpos
-               length += 1
-               ns[rp] = c
-               rp += 1
-               if rp == buf_size then
-                       rpos = rp
+               if rp >= buf_size then
                        dump_buffer
                        rp = 0
                end
+               ns[rp] = c
+               rp += 1
+               length += 1
                rpos = rp
        end
 
@@ -393,15 +392,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