Mercurial > public > mercurial-scm > hg
comparison mercurial/revlog.py @ 33392:ac6446611ad2
revlog: use struct.Struct instances for slight performance wins
Differential Revision: https://phab.mercurial-scm.org/D32
author | Alex Gaynor <agaynor@mozilla.com> |
---|---|
date | Mon, 10 Jul 2017 16:41:13 -0400 |
parents | 943b8c37f49d |
children | 9180f8f593f3 |
comparison
equal
deleted
inserted
replaced
33391:943b8c37f49d | 33392:ac6446611ad2 |
---|---|
42 util, | 42 util, |
43 ) | 43 ) |
44 | 44 |
45 parsers = policy.importmod(r'parsers') | 45 parsers = policy.importmod(r'parsers') |
46 | 46 |
47 _pack = struct.pack | |
48 _unpack = struct.unpack | |
49 # Aliased for performance. | 47 # Aliased for performance. |
50 _zlibdecompress = zlib.decompress | 48 _zlibdecompress = zlib.decompress |
51 | 49 |
52 # revlog header flags | 50 # revlog header flags |
53 REVLOGV0 = 0 | 51 REVLOGV0 = 0 |
169 # 4 bytes: base rev | 167 # 4 bytes: base rev |
170 # 4 bytes: link rev | 168 # 4 bytes: link rev |
171 # 20 bytes: parent 1 nodeid | 169 # 20 bytes: parent 1 nodeid |
172 # 20 bytes: parent 2 nodeid | 170 # 20 bytes: parent 2 nodeid |
173 # 20 bytes: nodeid | 171 # 20 bytes: nodeid |
174 indexformatv0 = ">4l20s20s20s" | 172 indexformatv0 = struct.Struct(">4l20s20s20s") |
173 indexformatv0_pack = indexformatv0.pack | |
174 indexformatv0_unpack = indexformatv0.unpack | |
175 | 175 |
176 class revlogoldio(object): | 176 class revlogoldio(object): |
177 def __init__(self): | 177 def __init__(self): |
178 self.size = struct.calcsize(indexformatv0) | 178 self.size = indexformatv0.size |
179 | 179 |
180 def parseindex(self, data, inline): | 180 def parseindex(self, data, inline): |
181 s = self.size | 181 s = self.size |
182 index = [] | 182 index = [] |
183 nodemap = {nullid: nullrev} | 183 nodemap = {nullid: nullrev} |
184 n = off = 0 | 184 n = off = 0 |
185 l = len(data) | 185 l = len(data) |
186 while off + s <= l: | 186 while off + s <= l: |
187 cur = data[off:off + s] | 187 cur = data[off:off + s] |
188 off += s | 188 off += s |
189 e = _unpack(indexformatv0, cur) | 189 e = indexformatv0_unpack(cur) |
190 # transform to revlogv1 format | 190 # transform to revlogv1 format |
191 e2 = (offset_type(e[0], 0), e[1], -1, e[2], e[3], | 191 e2 = (offset_type(e[0], 0), e[1], -1, e[2], e[3], |
192 nodemap.get(e[4], nullrev), nodemap.get(e[5], nullrev), e[6]) | 192 nodemap.get(e[4], nullrev), nodemap.get(e[5], nullrev), e[6]) |
193 index.append(e2) | 193 index.append(e2) |
194 nodemap[e[6]] = n | 194 nodemap[e[6]] = n |
202 def packentry(self, entry, node, version, rev): | 202 def packentry(self, entry, node, version, rev): |
203 if gettype(entry[0]): | 203 if gettype(entry[0]): |
204 raise RevlogError(_('index entry flags need revlog version 1')) | 204 raise RevlogError(_('index entry flags need revlog version 1')) |
205 e2 = (getoffset(entry[0]), entry[1], entry[3], entry[4], | 205 e2 = (getoffset(entry[0]), entry[1], entry[3], entry[4], |
206 node(entry[5]), node(entry[6]), entry[7]) | 206 node(entry[5]), node(entry[6]), entry[7]) |
207 return _pack(indexformatv0, *e2) | 207 return indexformatv0_pack(*e2) |
208 | 208 |
209 # index ng: | 209 # index ng: |
210 # 6 bytes: offset | 210 # 6 bytes: offset |
211 # 2 bytes: flags | 211 # 2 bytes: flags |
212 # 4 bytes: compressed length | 212 # 4 bytes: compressed length |
214 # 4 bytes: base rev | 214 # 4 bytes: base rev |
215 # 4 bytes: link rev | 215 # 4 bytes: link rev |
216 # 4 bytes: parent 1 rev | 216 # 4 bytes: parent 1 rev |
217 # 4 bytes: parent 2 rev | 217 # 4 bytes: parent 2 rev |
218 # 32 bytes: nodeid | 218 # 32 bytes: nodeid |
219 indexformatng = ">Qiiiiii20s12x" | 219 indexformatng = struct.Struct(">Qiiiiii20s12x") |
220 versionformat = ">I" | 220 indexformatng_pack = indexformatng.pack |
221 versionformat = struct.Struct(">I") | |
222 versionformat_pack = versionformat.pack | |
223 versionformat_unpack = versionformat.unpack | |
221 | 224 |
222 # corresponds to uncompressed length of indexformatng (2 gigs, 4-byte | 225 # corresponds to uncompressed length of indexformatng (2 gigs, 4-byte |
223 # signed integer) | 226 # signed integer) |
224 _maxentrysize = 0x7fffffff | 227 _maxentrysize = 0x7fffffff |
225 | 228 |
226 class revlogio(object): | 229 class revlogio(object): |
227 def __init__(self): | 230 def __init__(self): |
228 self.size = struct.calcsize(indexformatng) | 231 self.size = indexformatng.size |
229 | 232 |
230 def parseindex(self, data, inline): | 233 def parseindex(self, data, inline): |
231 # call the C implementation to parse the index data | 234 # call the C implementation to parse the index data |
232 index, cache = parsers.parse_index2(data, inline) | 235 index, cache = parsers.parse_index2(data, inline) |
233 return index, getattr(index, 'nodemap', None), cache | 236 return index, getattr(index, 'nodemap', None), cache |
234 | 237 |
235 def packentry(self, entry, node, version, rev): | 238 def packentry(self, entry, node, version, rev): |
236 p = _pack(indexformatng, *entry) | 239 p = indexformatng_pack(*entry) |
237 if rev == 0: | 240 if rev == 0: |
238 p = _pack(versionformat, version) + p[4:] | 241 p = versionformat_pack(version) + p[4:] |
239 return p | 242 return p |
240 | 243 |
241 class revlog(object): | 244 class revlog(object): |
242 """ | 245 """ |
243 the underlying revision storage object | 246 the underlying revision storage object |
333 try: | 336 try: |
334 f = self.opener(self.indexfile) | 337 f = self.opener(self.indexfile) |
335 indexdata = f.read() | 338 indexdata = f.read() |
336 f.close() | 339 f.close() |
337 if len(indexdata) > 0: | 340 if len(indexdata) > 0: |
338 v = struct.unpack(versionformat, indexdata[:4])[0] | 341 v = versionformat_unpack(indexdata[:4])[0] |
339 self._initempty = False | 342 self._initempty = False |
340 except IOError as inst: | 343 except IOError as inst: |
341 if inst.errno != errno.ENOENT: | 344 if inst.errno != errno.ENOENT: |
342 raise | 345 raise |
343 | 346 |