41 return self.mapcache[2] |
41 return self.mapcache[2] |
42 |
42 |
43 def diff(self, a, b): |
43 def diff(self, a, b): |
44 return mdiff.textdiff(str(a), str(b)) |
44 return mdiff.textdiff(str(a), str(b)) |
45 |
45 |
|
46 def _search(self, m, s, lo=0, hi=None): |
|
47 '''return a tuple (start, end) that says where to find s within m. |
|
48 |
|
49 If the string is found m[start:end] are the line containing |
|
50 that string. If start == end the string was not found and |
|
51 they indicate the proper sorted insertion point. This was |
|
52 taken from bisect_left, and modified to find line start/end as |
|
53 it goes along. |
|
54 |
|
55 m should be a buffer or a string |
|
56 s is a string''' |
|
57 def advance(i, c): |
|
58 while i < lenm and m[i] != c: |
|
59 i += 1 |
|
60 return i |
|
61 lenm = len(m) |
|
62 if not hi: |
|
63 hi = lenm |
|
64 while lo < hi: |
|
65 mid = (lo + hi) // 2 |
|
66 start = mid |
|
67 while start > 0 and m[start-1] != '\n': |
|
68 start -= 1 |
|
69 end = advance(start, '\0') |
|
70 if m[start:end] < s: |
|
71 # we know that after the null there are 40 bytes of sha1 |
|
72 # this translates to the bisect lo = mid + 1 |
|
73 lo = advance(end + 40, '\n') + 1 |
|
74 else: |
|
75 # this translates to the bisect hi = mid |
|
76 hi = start |
|
77 end = advance(lo, '\0') |
|
78 found = m[lo:end] |
|
79 if cmp(s, found) == 0: |
|
80 # we know that after the null there are 40 bytes of sha1 |
|
81 end = advance(end + 40, '\n') |
|
82 return (lo, end+1) |
|
83 else: |
|
84 return (lo, lo) |
|
85 |
|
86 def find(self, node, f): |
|
87 '''look up entry for a single file efficiently. |
|
88 return (node, flag) pair if found, (None, None) if not.''' |
|
89 if self.mapcache and node == self.mapcache[0]: |
|
90 return self.mapcache[1].get(f), self.mapcache[2].get(f) |
|
91 text = self.revision(node) |
|
92 start, end = self._search(text, f) |
|
93 if start == end: |
|
94 return None, None |
|
95 l = text[start:end] |
|
96 f, n = l.split('\0') |
|
97 return bin(n[:40]), n[40:-1] == 'x' |
|
98 |
46 def add(self, map, flags, transaction, link, p1=None, p2=None, |
99 def add(self, map, flags, transaction, link, p1=None, p2=None, |
47 changed=None): |
100 changed=None): |
48 |
|
49 # returns a tuple (start, end). If the string is found |
|
50 # m[start:end] are the line containing that string. If start == end |
|
51 # the string was not found and they indicate the proper sorted |
|
52 # insertion point. This was taken from bisect_left, and modified |
|
53 # to find line start/end as it goes along. |
|
54 # |
|
55 # m should be a buffer or a string |
|
56 # s is a string |
|
57 # |
|
58 def manifestsearch(m, s, lo=0, hi=None): |
|
59 def advance(i, c): |
|
60 while i < lenm and m[i] != c: |
|
61 i += 1 |
|
62 return i |
|
63 lenm = len(m) |
|
64 if not hi: |
|
65 hi = lenm |
|
66 while lo < hi: |
|
67 mid = (lo + hi) // 2 |
|
68 start = mid |
|
69 while start > 0 and m[start-1] != '\n': |
|
70 start -= 1 |
|
71 end = advance(start, '\0') |
|
72 if m[start:end] < s: |
|
73 # we know that after the null there are 40 bytes of sha1 |
|
74 # this translates to the bisect lo = mid + 1 |
|
75 lo = advance(end + 40, '\n') + 1 |
|
76 else: |
|
77 # this translates to the bisect hi = mid |
|
78 hi = start |
|
79 end = advance(lo, '\0') |
|
80 found = m[lo:end] |
|
81 if cmp(s, found) == 0: |
|
82 # we know that after the null there are 40 bytes of sha1 |
|
83 end = advance(end + 40, '\n') |
|
84 return (lo, end+1) |
|
85 else: |
|
86 return (lo, lo) |
|
87 |
|
88 # apply the changes collected during the bisect loop to our addlist |
101 # apply the changes collected during the bisect loop to our addlist |
89 # return a delta suitable for addrevision |
102 # return a delta suitable for addrevision |
90 def addlistdelta(addlist, x): |
103 def addlistdelta(addlist, x): |
91 # start from the bottom up |
104 # start from the bottom up |
92 # so changes to the offsets don't mess things up. |
105 # so changes to the offsets don't mess things up. |