~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/_dirstate_helpers_c.pyx

  • Committer: John Arbash Meinel
  • Date: 2007-07-13 21:28:35 UTC
  • mto: This revision was merged to the branch mainline in revision 2643.
  • Revision ID: john@arbash-meinel.com-20070713212835-m330r85zq4xwgipi
Thanks to Jan 'RedBully' Seiffert, some review cleanups
changes size_t to unsigned.
Check alignment on strings before using integer loops.
Just use a simple backwards checking loop for _memrchr

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
 
25
25
cdef extern from *:
26
 
    ctypedef int size_t
 
26
    ctypedef unsigned size_t
 
27
 
 
28
cdef extern from "stdint.h":
 
29
    ctypedef int intptr_t
27
30
 
28
31
 
29
32
cdef extern from "stdlib.h":
56
59
 
57
60
cdef void* _my_memrchr(void *s, int c, size_t n):
58
61
    # memrchr seems to be a GNU extension, so we have to implement it ourselves
59
 
    # We semi-cheat, and just call memchr repeatedly until we run out of path.
60
 
    # And then return the last match.
61
 
    cdef void *pos
62
 
    cdef void *end
63
 
    cdef void *last_pos
 
62
    cdef char *pos
 
63
    cdef char *start
64
64
 
65
 
    last_pos = NULL
66
 
    end = <void*>((<char*>s) + n)
67
 
    pos = memchr(s, c, n)
68
 
    while pos != NULL and pos < end:
69
 
        last_pos = pos
70
 
        pos = memchr(pos+1, c, end-pos)
71
 
    return last_pos
 
65
    start = <char*>s
 
66
    pos = start + n - 1
 
67
    while pos >= start:
 
68
        if pos[0] == c:
 
69
            return <void*>pos
 
70
        pos = pos - 1
 
71
    return NULL
72
72
 
73
73
 
74
74
def _py_memrchr(s, c):
95
95
    return found - _s
96
96
 
97
97
 
 
98
cdef int _is_aligned(void *ptr):
 
99
    """Is this pointer aligned to an integer size offset?
 
100
 
 
101
    :return: 1 if this pointer is aligned, 0 otherwise.
 
102
    """
 
103
    return ((<intptr_t>ptr) & ((sizeof(int))-1)) == 0
 
104
 
 
105
 
98
106
cdef int _cmp_by_dirs(char *path1, int size1, char *path2, int size2):
99
107
    cdef char *cur1
100
108
    cdef char *cur2
108
116
    if path1 == path2:
109
117
        return 0
110
118
 
111
 
    cur_int1 = <int*>path1
112
 
    cur_int2 = <int*>path2
113
 
    end_int1 = <int*>(path1 + size1 - (size1%4))
114
 
    end_int2 = <int*>(path2 + size2 - (size2%4))
115
119
    end1 = path1+size1
116
120
    end2 = path2+size2
117
121
 
118
122
    # Use 32-bit comparisons for the matching portion of the string.
119
123
    # Almost all CPU's are faster at loading and comparing 32-bit integers,
120
124
    # than they are at 8-bit integers.
121
 
    # TODO: jam 2007-05-07 Do we need to change this so we always start at an
122
 
    #       integer offset in memory? I seem to remember that being done in
123
 
    #       some C libraries for strcmp()
124
 
    while cur_int1 < end_int1 and cur_int2 < end_int2:
125
 
        if cur_int1[0] != cur_int2[0]:
126
 
            break
127
 
        cur_int1 = cur_int1 + 1
128
 
        cur_int2 = cur_int2 + 1
129
 
 
130
 
    cur1 = <char*>cur_int1
131
 
    cur2 = <char*>cur_int2
 
125
    # 99% of the time, these will be aligned, but in case they aren't just skip
 
126
    # this loop
 
127
    if _is_aligned(path1) and _is_aligned(path2):
 
128
        cur_int1 = <int*>path1
 
129
        cur_int2 = <int*>path2
 
130
        end_int1 = <int*>(path1 + size1 - (size1%4))
 
131
        end_int2 = <int*>(path2 + size2 - (size2%4))
 
132
 
 
133
        while cur_int1 < end_int1 and cur_int2 < end_int2:
 
134
            if cur_int1[0] != cur_int2[0]:
 
135
                break
 
136
            cur_int1 = cur_int1 + 1
 
137
            cur_int2 = cur_int2 + 1
 
138
 
 
139
        cur1 = <char*>cur_int1
 
140
        cur2 = <char*>cur_int2
 
141
    else:
 
142
        cur1 = path1
 
143
        cur2 = path2
132
144
 
133
145
    while cur1 < end1 and cur2 < end2:
134
146
        if cur1[0] == cur2[0]: