Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/revlog.py @ 323:c6f0673ab7e9
lazyparser speed ups
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
lazyparser speed ups
When we do __contains__ on a map, we might as well load the whole
index. Not doing this was slowing down finding new changesets quite by
a factor of 20. When we do a full load, we also attempt to replace the
revlog's index and nodemap with normal Python objects to avoid the
lazymap overhead.
manifest hash: 9b2b20aacc508f9027d115426c63a381d28e5485
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
iD8DBQFCreYIywK+sNU5EO8RAoNHAJ9+LmXqsTQb9Bh3mZHq0A0VfQOleQCffHmn
jC/O0vnfx5FCRsX2bUFG794=
=BDTz
-----END PGP SIGNATURE-----
author | mpm@selenic.com |
---|---|
date | Mon, 13 Jun 2005 12:01:12 -0800 |
parents | f06a4a3b86a7 |
children | 27d08c0c2a7e |
comparison
equal
deleted
inserted
replaced
322:a0acae914e95 | 323:c6f0673ab7e9 |
---|---|
41 | 41 |
42 nullid = "\0" * 20 | 42 nullid = "\0" * 20 |
43 indexformat = ">4l20s20s20s" | 43 indexformat = ">4l20s20s20s" |
44 | 44 |
45 class lazyparser: | 45 class lazyparser: |
46 def __init__(self, data): | 46 def __init__(self, data, revlog): |
47 self.data = data | 47 self.data = data |
48 self.s = struct.calcsize(indexformat) | 48 self.s = struct.calcsize(indexformat) |
49 self.l = len(data)/self.s | 49 self.l = len(data)/self.s |
50 self.index = [None] * self.l | 50 self.index = [None] * self.l |
51 self.map = {nullid: -1} | 51 self.map = {nullid: -1} |
52 | 52 self.all = 0 |
53 def load(self, pos): | 53 self.revlog = revlog |
54 block = pos / 1000 | 54 |
55 i = block * 1000 | 55 def load(self, pos=None): |
56 end = min(self.l, i + 1000) | 56 if self.all: return |
57 if pos is not None: | |
58 block = pos / 1000 | |
59 i = block * 1000 | |
60 end = min(self.l, i + 1000) | |
61 else: | |
62 self.all = 1 | |
63 i = 0 | |
64 end = self.l | |
65 self.revlog.index = self.index | |
66 self.revlog.nodemap = self.map | |
67 | |
57 while i < end: | 68 while i < end: |
58 d = self.data[i * self.s: (i + 1) * self.s] | 69 d = self.data[i * self.s: (i + 1) * self.s] |
59 e = struct.unpack(indexformat, d) | 70 e = struct.unpack(indexformat, d) |
60 self.index[i] = e | 71 self.index[i] = e |
61 self.map[e[6]] = i | 72 self.map[e[6]] = i |
76 | 87 |
77 class lazymap: | 88 class lazymap: |
78 def __init__(self, parser): | 89 def __init__(self, parser): |
79 self.p = parser | 90 self.p = parser |
80 def load(self, key): | 91 def load(self, key): |
92 if self.p.all: return | |
81 n = self.p.data.find(key) | 93 n = self.p.data.find(key) |
82 if n < 0: raise KeyError("node " + hex(key)) | 94 if n < 0: raise KeyError("node " + hex(key)) |
83 pos = n / self.p.s | 95 pos = n / self.p.s |
84 self.p.load(pos) | 96 self.p.load(pos) |
85 def __contains__(self, key): | 97 def __contains__(self, key): |
86 try: | 98 self.p.load() |
87 self[key] | 99 return key in self.p.map |
88 return True | |
89 except KeyError: | |
90 return False | |
91 def __iter__(self): | 100 def __iter__(self): |
92 for i in xrange(self.p.l): | 101 for i in xrange(self.p.l): |
93 try: | 102 try: |
94 yield self.p.index[i][6] | 103 yield self.p.index[i][6] |
95 except: | 104 except: |
119 except IOError: | 128 except IOError: |
120 i = "" | 129 i = "" |
121 | 130 |
122 if len(i) > 10000: | 131 if len(i) > 10000: |
123 # big index, let's parse it on demand | 132 # big index, let's parse it on demand |
124 parser = lazyparser(i) | 133 parser = lazyparser(i, self) |
125 self.index = lazyindex(parser) | 134 self.index = lazyindex(parser) |
126 self.nodemap = lazymap(parser) | 135 self.nodemap = lazymap(parser) |
127 else: | 136 else: |
128 s = struct.calcsize(indexformat) | 137 s = struct.calcsize(indexformat) |
129 l = len(i) / s | 138 l = len(i) / s |