Rev 2487: Now that we have bisect_dirblock working again, bring back cmp_dirblock_strings. in http://bzr.arbash-meinel.com/branches/bzr/0.17-dev/dirstate_pyrex
John Arbash Meinel
john at arbash-meinel.com
Fri May 4 16:50:27 BST 2007
At http://bzr.arbash-meinel.com/branches/bzr/0.17-dev/dirstate_pyrex
------------------------------------------------------------
revno: 2487
revision-id: john at arbash-meinel.com-20070504155015-l31mrfviixrrf277
parent: john at arbash-meinel.com-20070504154346-fgz2nrtwtd8u9w6a
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: dirstate_pyrex
timestamp: Fri 2007-05-04 10:50:15 -0500
message:
Now that we have bisect_dirblock working again, bring back cmp_dirblock_strings.
modified:
bzrlib/compiled/dirstate_helpers.pyx dirstate_helpers.pyx-20070503201057-u425eni465q4idwn-3
-------------- next part --------------
=== modified file 'bzrlib/compiled/dirstate_helpers.pyx'
--- a/bzrlib/compiled/dirstate_helpers.pyx 2007-05-04 15:43:46 +0000
+++ b/bzrlib/compiled/dirstate_helpers.pyx 2007-05-04 15:50:15 +0000
@@ -22,6 +22,9 @@
from bzrlib.dirstate import DirState
+cdef extern from *:
+ ctypedef int size_t
+
cdef extern from "Python.h":
# GetItem returns a borrowed reference
void *PyDict_GetItem(object p, object key)
@@ -32,9 +35,17 @@
int PyList_CheckExact(object)
int PyTuple_CheckExact(object)
+ char *PyString_AsString(object p)
+ int PyString_Size(object p)
+
void Py_INCREF(object)
void Py_DECREF(object)
+cdef extern from "string.h":
+ int strncmp(char *s1, char *s2, size_t len)
+ int strcmp(char *s1, char *s2)
+ char *strchr(char *s1, char c)
+
cdef object _split_from_path(object cache, object path):
"""get the dirblock tuple for a given path.
@@ -58,6 +69,82 @@
return value
+cdef int _cmp_dirblock_strings(char *path1, int size1, char *path2, int size2):
+ """This compares 2 strings separating on path sections.
+
+ This is equivalent to "cmp(path1.split('/'), path2.split('/'))"
+ However, we don't want to create an extra object for doing the split.
+
+ :param path1: The first path to compare
+ :param size1: The length of the first path
+ :param path2: The second path
+ :param size1: The length of the second path
+ :return: 0 if they are equal, -1 if path1 comes first, 1 if path2 comes
+ first
+ """
+ cdef char *base1
+ cdef char *base2
+ cdef char *tip1
+ cdef char *tip2
+ cdef char *end1
+ cdef char *end2
+ cdef int cur_len1
+ cdef int cur_len2
+ cdef int cmp_len
+ cdef int diff
+
+ base1 = path1
+ base2 = path2
+ end1 = base1 + size1
+ end2 = base2 + size2
+
+ # Ensure that we are pointing to the final NULL terminator on both ends
+ assert end1[0] == c'\x00'
+ assert end2[0] == c'\x00'
+
+ while base1 < end1 and base2 < end2:
+ # Find the next path separator
+ # (This is where you would like strchrnul)
+ tip1 = strchr(base1, c'/')
+ tip2 = strchr(base2, c'/')
+
+ if tip1 == NULL:
+ tip1 = end1
+ if tip2 == NULL:
+ tip2 = end2
+
+ cur_len1 = tip1 - base1
+ cur_len2 = tip2 - base2
+ cmp_len = cur_len1
+ if cur_len2 < cur_len1:
+ cmp_len = cur_len2
+
+ diff = strncmp(base1, base2, cmp_len)
+ # print 'comparing "%s", "%s", %d = %d' % (base1, base2, cmp_len, diff)
+ if diff != 0:
+ return diff
+ if cur_len1 < cur_len2:
+ return -1
+ elif cur_len1 > cur_len2:
+ return 1
+ base1 = tip1+1
+ base2 = tip2+1
+ # Do we still have uncompared characters?
+ if base1 < end1:
+ return 1
+ if base2 < end2:
+ return -1
+ return 0
+
+
+def cmp_dirblock_strings(path1, path2):
+ """Compare to python strings in dirblock fashion."""
+ return _cmp_dirblock_strings(PyString_AsString(path1),
+ PyString_Size(path1),
+ PyString_AsString(path2),
+ PyString_Size(path2))
+
+
def bisect_dirblock(dirblocks, dirname, lo=0, hi=None, cache={}):
"""Return the index where to insert dirname into the dirblocks.
More information about the bazaar-commits
mailing list