Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/revlog.py @ 16414:e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
This greatly speeds up node->rev lookups, with results that are
often user-perceptible: for instance, "hg --time log" of the node
associated with rev 1000 on a linux-2.6 repo improves from 0.3
seconds to 0.03. I have not found any instances of slowdowns.
The new perfnodelookup command in contrib/perf.py demonstrates the
speedup more dramatically, since it performs no I/O. For a single
lookup, the new code is about 40x faster.
These changes also prepare the ground for the possibility of further
improving the performance of prefix-based node lookups.
author | Bryan O'Sullivan <bryano@fb.com> |
---|---|
date | Thu, 12 Apr 2012 14:05:59 -0700 |
parents | d7d64b89a65c |
children | e5750c6716eb |
comparison
equal
deleted
inserted
replaced
16413:1a420761fcb7 | 16414:e8d37b78acfb |
---|---|
172 self.size = struct.calcsize(indexformatng) | 172 self.size = struct.calcsize(indexformatng) |
173 | 173 |
174 def parseindex(self, data, inline): | 174 def parseindex(self, data, inline): |
175 # call the C implementation to parse the index data | 175 # call the C implementation to parse the index data |
176 index, cache = parsers.parse_index2(data, inline) | 176 index, cache = parsers.parse_index2(data, inline) |
177 return index, None, cache | 177 return index, getattr(index, 'nodemap', None), cache |
178 | 178 |
179 def packentry(self, entry, node, version, rev): | 179 def packentry(self, entry, node, version, rev): |
180 p = _pack(indexformatng, *entry) | 180 p = _pack(indexformatng, *entry) |
181 if rev == 0: | 181 if rev == 0: |
182 p = _pack(versionformat, version) + p[4:] | 182 p = _pack(versionformat, version) + p[4:] |
293 self.rev(node) | 293 self.rev(node) |
294 return True | 294 return True |
295 except KeyError: | 295 except KeyError: |
296 return False | 296 return False |
297 | 297 |
298 def clearcaches(self): | |
299 try: | |
300 self._nodecache.clearcaches() | |
301 except AttributeError: | |
302 self._nodecache = {nullid: nullrev} | |
303 self._nodepos = None | |
304 | |
298 def rev(self, node): | 305 def rev(self, node): |
299 try: | 306 try: |
300 return self._nodecache[node] | 307 return self._nodecache[node] |
308 except RevlogError: | |
309 # parsers.c radix tree lookup failed | |
310 raise LookupError(node, self.indexfile, _('no node')) | |
301 except KeyError: | 311 except KeyError: |
312 # pure python cache lookup failed | |
302 n = self._nodecache | 313 n = self._nodecache |
303 i = self.index | 314 i = self.index |
304 p = self._nodepos | 315 p = self._nodepos |
305 if p is None: | 316 if p is None: |
306 p = len(i) - 2 | 317 p = len(i) - 2 |