Rev 2543: Thanks to Jan 'RedBully' Seiffert, some review cleanups in http://bzr.arbash-meinel.com/branches/bzr/0.17-dev/dirstate_pyrex
John Arbash Meinel
john at arbash-meinel.com
Fri Jul 13 22:31:35 BST 2007
At http://bzr.arbash-meinel.com/branches/bzr/0.17-dev/dirstate_pyrex
------------------------------------------------------------
revno: 2543
revision-id: john at arbash-meinel.com-20070713212835-m330r85zq4xwgipi
parent: john at arbash-meinel.com-20070713175009-sylhp1kst6145v0f
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: dirstate_pyrex
timestamp: Fri 2007-07-13 16:28:35 -0500
message:
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
modified:
bzrlib/_dirstate_helpers_c.pyx dirstate_helpers.pyx-20070503201057-u425eni465q4idwn-3
-------------- next part --------------
=== modified file 'bzrlib/_dirstate_helpers_c.pyx'
--- a/bzrlib/_dirstate_helpers_c.pyx 2007-07-12 16:34:02 +0000
+++ b/bzrlib/_dirstate_helpers_c.pyx 2007-07-13 21:28:35 +0000
@@ -23,7 +23,10 @@
cdef extern from *:
- ctypedef int size_t
+ ctypedef unsigned size_t
+
+cdef extern from "stdint.h":
+ ctypedef int intptr_t
cdef extern from "stdlib.h":
@@ -56,19 +59,16 @@
cdef void* _my_memrchr(void *s, int c, size_t n):
# memrchr seems to be a GNU extension, so we have to implement it ourselves
- # We semi-cheat, and just call memchr repeatedly until we run out of path.
- # And then return the last match.
- cdef void *pos
- cdef void *end
- cdef void *last_pos
+ cdef char *pos
+ cdef char *start
- last_pos = NULL
- end = <void*>((<char*>s) + n)
- pos = memchr(s, c, n)
- while pos != NULL and pos < end:
- last_pos = pos
- pos = memchr(pos+1, c, end-pos)
- return last_pos
+ start = <char*>s
+ pos = start + n - 1
+ while pos >= start:
+ if pos[0] == c:
+ return <void*>pos
+ pos = pos - 1
+ return NULL
def _py_memrchr(s, c):
@@ -95,6 +95,14 @@
return found - _s
+cdef int _is_aligned(void *ptr):
+ """Is this pointer aligned to an integer size offset?
+
+ :return: 1 if this pointer is aligned, 0 otherwise.
+ """
+ return ((<intptr_t>ptr) & ((sizeof(int))-1)) == 0
+
+
cdef int _cmp_by_dirs(char *path1, int size1, char *path2, int size2):
cdef char *cur1
cdef char *cur2
@@ -108,27 +116,31 @@
if path1 == path2:
return 0
- cur_int1 = <int*>path1
- cur_int2 = <int*>path2
- end_int1 = <int*>(path1 + size1 - (size1%4))
- end_int2 = <int*>(path2 + size2 - (size2%4))
end1 = path1+size1
end2 = path2+size2
# Use 32-bit comparisons for the matching portion of the string.
# Almost all CPU's are faster at loading and comparing 32-bit integers,
# than they are at 8-bit integers.
- # TODO: jam 2007-05-07 Do we need to change this so we always start at an
- # integer offset in memory? I seem to remember that being done in
- # some C libraries for strcmp()
- while cur_int1 < end_int1 and cur_int2 < end_int2:
- if cur_int1[0] != cur_int2[0]:
- break
- cur_int1 = cur_int1 + 1
- cur_int2 = cur_int2 + 1
-
- cur1 = <char*>cur_int1
- cur2 = <char*>cur_int2
+ # 99% of the time, these will be aligned, but in case they aren't just skip
+ # this loop
+ if _is_aligned(path1) and _is_aligned(path2):
+ cur_int1 = <int*>path1
+ cur_int2 = <int*>path2
+ end_int1 = <int*>(path1 + size1 - (size1%4))
+ end_int2 = <int*>(path2 + size2 - (size2%4))
+
+ while cur_int1 < end_int1 and cur_int2 < end_int2:
+ if cur_int1[0] != cur_int2[0]:
+ break
+ cur_int1 = cur_int1 + 1
+ cur_int2 = cur_int2 + 1
+
+ cur1 = <char*>cur_int1
+ cur2 = <char*>cur_int2
+ else:
+ cur1 = path1
+ cur2 = path2
while cur1 < end1 and cur2 < end2:
if cur1[0] == cur2[0]:
More information about the bazaar-commits
mailing list