Mercurial > public > mercurial-scm > hg
comparison mercurial/manifest.py @ 22930:1acb81d10eaf
manifest: move _search to module level and rename to _msearch
The rename is intended to provide a slight hint that it is
manifest-specific.
author | Augie Fackler <raf@durin42.com> |
---|---|
date | Wed, 08 Oct 2014 15:21:59 -0400 |
parents | bf69cb09a6c9 |
children | 48c0b101a9de |
comparison
equal
deleted
inserted
replaced
22929:bf69cb09a6c9 | 22930:1acb81d10eaf |
---|---|
47 hex, flags = revlog.hex, self.flags | 47 hex, flags = revlog.hex, self.flags |
48 # if this is changed to support newlines in filenames, | 48 # if this is changed to support newlines in filenames, |
49 # be sure to check the templates/ dir again (especially *-raw.tmpl) | 49 # be sure to check the templates/ dir again (especially *-raw.tmpl) |
50 return ''.join("%s\0%s%s\n" % (f, hex(self[f]), flags(f)) for f in fl) | 50 return ''.join("%s\0%s%s\n" % (f, hex(self[f]), flags(f)) for f in fl) |
51 | 51 |
52 def _msearch(m, s, lo=0, hi=None): | |
53 '''return a tuple (start, end) that says where to find s within m. | |
54 | |
55 If the string is found m[start:end] are the line containing | |
56 that string. If start == end the string was not found and | |
57 they indicate the proper sorted insertion point. | |
58 | |
59 m should be a buffer or a string | |
60 s is a string''' | |
61 def advance(i, c): | |
62 while i < lenm and m[i] != c: | |
63 i += 1 | |
64 return i | |
65 if not s: | |
66 return (lo, lo) | |
67 lenm = len(m) | |
68 if not hi: | |
69 hi = lenm | |
70 while lo < hi: | |
71 mid = (lo + hi) // 2 | |
72 start = mid | |
73 while start > 0 and m[start - 1] != '\n': | |
74 start -= 1 | |
75 end = advance(start, '\0') | |
76 if m[start:end] < s: | |
77 # we know that after the null there are 40 bytes of sha1 | |
78 # this translates to the bisect lo = mid + 1 | |
79 lo = advance(end + 40, '\n') + 1 | |
80 else: | |
81 # this translates to the bisect hi = mid | |
82 hi = start | |
83 end = advance(lo, '\0') | |
84 found = m[lo:end] | |
85 if s == found: | |
86 # we know that after the null there are 40 bytes of sha1 | |
87 end = advance(end + 40, '\n') | |
88 return (lo, end + 1) | |
89 else: | |
90 return (lo, lo) | |
91 | |
52 def _checkforbidden(l): | 92 def _checkforbidden(l): |
53 """Check filenames for illegal characters.""" | 93 """Check filenames for illegal characters.""" |
54 for f in l: | 94 for f in l: |
55 if '\n' in f or '\r' in f: | 95 if '\n' in f or '\r' in f: |
56 raise error.RevlogError( | 96 raise error.RevlogError( |
111 arraytext = array.array('c', text) | 151 arraytext = array.array('c', text) |
112 mapping = _parse(text) | 152 mapping = _parse(text) |
113 self._mancache[node] = (mapping, arraytext) | 153 self._mancache[node] = (mapping, arraytext) |
114 return mapping | 154 return mapping |
115 | 155 |
116 def _search(self, m, s, lo=0, hi=None): | |
117 '''return a tuple (start, end) that says where to find s within m. | |
118 | |
119 If the string is found m[start:end] are the line containing | |
120 that string. If start == end the string was not found and | |
121 they indicate the proper sorted insertion point. | |
122 | |
123 m should be a buffer or a string | |
124 s is a string''' | |
125 def advance(i, c): | |
126 while i < lenm and m[i] != c: | |
127 i += 1 | |
128 return i | |
129 if not s: | |
130 return (lo, lo) | |
131 lenm = len(m) | |
132 if not hi: | |
133 hi = lenm | |
134 while lo < hi: | |
135 mid = (lo + hi) // 2 | |
136 start = mid | |
137 while start > 0 and m[start - 1] != '\n': | |
138 start -= 1 | |
139 end = advance(start, '\0') | |
140 if m[start:end] < s: | |
141 # we know that after the null there are 40 bytes of sha1 | |
142 # this translates to the bisect lo = mid + 1 | |
143 lo = advance(end + 40, '\n') + 1 | |
144 else: | |
145 # this translates to the bisect hi = mid | |
146 hi = start | |
147 end = advance(lo, '\0') | |
148 found = m[lo:end] | |
149 if s == found: | |
150 # we know that after the null there are 40 bytes of sha1 | |
151 end = advance(end + 40, '\n') | |
152 return (lo, end + 1) | |
153 else: | |
154 return (lo, lo) | |
155 | |
156 def find(self, node, f): | 156 def find(self, node, f): |
157 '''look up entry for a single file efficiently. | 157 '''look up entry for a single file efficiently. |
158 return (node, flags) pair if found, (None, None) if not.''' | 158 return (node, flags) pair if found, (None, None) if not.''' |
159 if node in self._mancache: | 159 if node in self._mancache: |
160 mapping = self._mancache[node][0] | 160 mapping = self._mancache[node][0] |
161 return mapping.get(f), mapping.flags(f) | 161 return mapping.get(f), mapping.flags(f) |
162 text = self.revision(node) | 162 text = self.revision(node) |
163 start, end = self._search(text, f) | 163 start, end = _msearch(text, f) |
164 if start == end: | 164 if start == end: |
165 return None, None | 165 return None, None |
166 l = text[start:end] | 166 l = text[start:end] |
167 f, n = l.split('\0') | 167 f, n = l.split('\0') |
168 return revlog.bin(n[:40]), n[40:-1] | 168 return revlog.bin(n[:40]), n[40:-1] |
193 | 193 |
194 # start with a readonly loop that finds the offset of | 194 # start with a readonly loop that finds the offset of |
195 # each line and creates the deltas | 195 # each line and creates the deltas |
196 for f, todelete in work: | 196 for f, todelete in work: |
197 # bs will either be the index of the item or the insert point | 197 # bs will either be the index of the item or the insert point |
198 start, end = self._search(addbuf, f, start) | 198 start, end = _msearch(addbuf, f, start) |
199 if not todelete: | 199 if not todelete: |
200 l = "%s\0%s%s\n" % (f, revlog.hex(map[f]), map.flags(f)) | 200 l = "%s\0%s%s\n" % (f, revlog.hex(map[f]), map.flags(f)) |
201 else: | 201 else: |
202 if start == end: | 202 if start == end: |
203 # item we want to delete was not found, error out | 203 # item we want to delete was not found, error out |