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