Rev 3661: We have a single malloc for the final output. in http://bzr.arbash-meinel.com/branches/bzr/1.7-dev/btree

John Arbash Meinel john at arbash-meinel.com
Thu Aug 21 22:26:19 BST 2008


At http://bzr.arbash-meinel.com/branches/bzr/1.7-dev/btree

------------------------------------------------------------
revno: 3661
revision-id: john at arbash-meinel.com-20080821212617-gng6c2akl8985wcm
parent: john at arbash-meinel.com-20080821205458-cjk22p6p5yqfhmv7
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: btree
timestamp: Thu 2008-08-21 16:26:17 -0500
message:
  We have a single malloc for the final output.
  We just need to collapse the intermediates.
modified:
  bzrlib/_parse_btree_c.pyx      _parse_btree_c.pyx-20080703034413-3q25bklkenti3p8p-2
-------------- next part --------------
=== modified file 'bzrlib/_parse_btree_c.pyx'
--- a/bzrlib/_parse_btree_c.pyx	2008-08-21 20:54:58 +0000
+++ b/bzrlib/_parse_btree_c.pyx	2008-08-21 21:26:17 +0000
@@ -259,7 +259,9 @@
     cdef Py_ssize_t key_len
     cdef char * value
     cdef Py_ssize_t value_len
-    cdef char * s
+    cdef char * out
+    cdef Py_ssize_t ref_len
+    cdef Py_ssize_t next_len
 
     # I don't expect that we can do faster than string.join()
     string_key = '\x00'.join(node[1])
@@ -276,28 +278,55 @@
     # ref_list := ref (CR ref)*
     # ref := BYTES (NULL BYTES)*
     # value := BYTES
-    if not reference_lists:
-        # Simple case, we only have the key and the value
-        # So we have the (key NULL NULL value LF)
-        key_len = PyString_Size(string_key)
-        value = PyString_AsString(node[2])
-        value_len = PyString_Size(node[2])
-        flat_len = (key_len + 1 + 1 + value_len + 1)
-        line = PyString_FromStringAndSize(NULL, flat_len)
-        # Get a pointer to the new buffer
-        s = PyString_AsString(line)
-        memcpy(s, PyString_AsString(string_key), key_len)
-        s[key_len] = c'\0'
-        s[key_len + 1] = c'\0'
-        memcpy(s + key_len + 2, value, value_len)
-        s[key_len + 2 + value_len] = c'\n'
-    else:
+    ref_len = 0
+    if reference_lists:
+        # Figure out how many bytes it will take to store the references
+        next_len = len(node[3]) # TODO: use a Py function
+        if next_len > 0:
+            # If there are no nodes, we don't need to do any work
+            # Otherwise we will need (len - 1) '\t' characters to separate
+            # the reference lists
+            ref_len = ref_len + (next_len - 1)
+            for ref_list in node[3]:
+                next_len = len(ref_list)
+                if next_len > 0:
+                    # We will need (len - 1) '\r' characters to separate the
+                    # references
+                    ref_len = ref_len + (next_len - 1)
+                    for reference in ref_list:
+                        next_len = len(reference)
+                        if next_len > 0:
+                            # We will need (len - 1) '\x00' characters to
+                            # separate the reference key
+                            ref_len = ref_len + (next_len - 1)
+                            for ref in reference:
+                                ref_len = ref_len + len(ref)
         flattened_references = []
         for ref_list in node[3]:
             ref_keys = []
             for reference in ref_list:
                 ref_keys.append('\x00'.join(reference))
             flattened_references.append('\r'.join(ref_keys))
-        line = ("%s\x00%s\x00%s\n" % (string_key,
-            '\t'.join(flattened_references), node[2]))
+        refs = '\t'.join(flattened_references)
+
+    # So we have the (key NULL refs NULL value LF)
+    key_len = PyString_Size(string_key)
+    value = PyString_AsString(node[2])
+    value_len = PyString_Size(node[2])
+    flat_len = (key_len + 1 + ref_len + 1 + value_len + 1)
+    line = PyString_FromStringAndSize(NULL, flat_len)
+    # Get a pointer to the new buffer
+    out = PyString_AsString(line)
+    memcpy(out, PyString_AsString(string_key), key_len)
+    out = out + key_len
+    out[0] = c'\0'
+    out = out + 1
+    if ref_len > 0:
+        memcpy(out, PyString_AsString(refs), ref_len)
+        out = out + ref_len
+    out[0] = c'\0'
+    out = out + 1
+    memcpy(out, value, value_len)
+    out = out + value_len
+    out[0] = c'\n'
     return string_key, line



More information about the bazaar-commits mailing list