~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/compiled/dirstate_helpers.pyx

  • Committer: John Arbash Meinel
  • Date: 2007-05-04 03:58:29 UTC
  • mto: This revision was merged to the branch mainline in revision 2643.
  • Revision ID: john@arbash-meinel.com-20070504035829-orbif7nnkim9md1t
Add some tests for a helper function that lets us
compare 2 paths in 'dirblock' mode, without splitting the strings.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
from bzrlib.dirstate import DirState
23
23
 
24
24
 
 
25
cdef extern from *:
 
26
    ctypedef int size_t
 
27
 
25
28
cdef extern from "Python.h":
26
29
    # GetItem returns a borrowed reference
27
30
    void *PyDict_GetItem(object p, object key)
29
32
    object PyList_GetItem(object lst, int index)
30
33
    object PyTuple_GetItem(object tpl, int index)
31
34
 
 
35
    char* PyString_AsString(object p)
 
36
    int PyString_Size(object p)
 
37
 
 
38
 
 
39
cdef extern from "string.h":
 
40
    int strncmp(char *s1, char *s2, size_t len)
 
41
    int strcmp(char *s1, char *s2)
 
42
    char *strchr(char *s1, char c)
 
43
 
32
44
 
33
45
cdef object _split_from_path(object cache, object path):
34
46
    """get the dirblock tuple for a given path.
70
82
    return _lo
71
83
 
72
84
 
 
85
cdef int _cmp_dirblock_strings(char *path1, int size1, char *path2, int size2):
 
86
    """This compares 2 strings separating on path sections.
 
87
 
 
88
    This is equivalent to "cmp(path1.split('/'), path2.split('/'))"
 
89
    However, we don't want to create an extra object for doing the split.
 
90
 
 
91
    :param path1: The first path to compare
 
92
    :param size1: The length of the first path
 
93
    :param path2: The second path
 
94
    :param size1: The length of the second path
 
95
    :return: 0 if they are equal, -1 if path1 comes first, 1 if path2 comes
 
96
        first
 
97
    """
 
98
    cdef char *base1
 
99
    cdef char *base2
 
100
    cdef char *tip1
 
101
    cdef char *tip2
 
102
    cdef char *end1
 
103
    cdef char *end2
 
104
    cdef int cur_len1
 
105
    cdef int cur_len2
 
106
    cdef int cmp_len
 
107
    cdef int diff
 
108
 
 
109
    base1 = path1
 
110
    base2 = path2
 
111
    end1 = base1 + size1
 
112
    end2 = base2 + size2
 
113
 
 
114
    # Ensure that we are pointing to the final NULL terminator on both ends
 
115
    assert end1[0] == c'\x00'
 
116
    assert end2[0] == c'\x00'
 
117
 
 
118
    while base1 < end1 and base2 < end2:
 
119
        # Find the next path separator
 
120
        # (This is where you would like strchrnul)
 
121
        tip1 = strchr(base1, c'/')
 
122
        tip2 = strchr(base2, c'/')
 
123
 
 
124
        if tip1 == NULL:
 
125
            tip1 = end1
 
126
        if tip2 == NULL:
 
127
            tip2 = end2
 
128
 
 
129
        cur_len1 = tip1 - base1
 
130
        cur_len2 = tip2 - base2
 
131
        cmp_len = cur_len1
 
132
        if cur_len2 < cur_len1:
 
133
            cmp_len = cur_len2
 
134
 
 
135
        diff = strncmp(base1, base2, cmp_len)
 
136
        # print 'comparing "%s", "%s", %d = %d' % (base1, base2, cmp_len, diff)
 
137
        if diff != 0:
 
138
            return diff
 
139
        if cur_len1 < cur_len2:
 
140
            return -1
 
141
        elif cur_len1 > cur_len2:
 
142
            return 1
 
143
        base1 = tip1+1
 
144
        base2 = tip2+1
 
145
    # Do we still have uncompared characters?
 
146
    if base1 < end1:
 
147
        return 1
 
148
    if base2 < end2:
 
149
        return -1
 
150
    return 0
 
151
 
 
152
 
 
153
def cmp_dirblock_strings(path1, path2):
 
154
    """Compare to python strings in dirblock fashion."""
 
155
    return _cmp_dirblock_strings(PyString_AsString(path1),
 
156
                                 PyString_Size(path1),
 
157
                                 PyString_AsString(path2),
 
158
                                 PyString_Size(path2))
 
159
 
 
160
 
73
161
def bisect_dirblock(dirblocks, dirname, lo=0, hi=None, cache=None):
74
162
    """Return the index where to insert dirname into the dirblocks.
75
163