comparison mercurial/revlog.py @ 4976:79c39cc9ff69

revlog: only allow lazy parsing with revlogng files This will allow us to store indices in memory in a single entry format
author Matt Mackall <mpm@selenic.com>
date Mon, 23 Jul 2007 20:44:08 -0500
parents 8b7e480a7603
children 6cb30bc4ca32
comparison
equal deleted inserted replaced
4975:8b7e480a7603 4976:79c39cc9ff69
86 # available. it keeps file handle open, which make it not possible 86 # available. it keeps file handle open, which make it not possible
87 # to break hardlinks on local cloned repos. 87 # to break hardlinks on local cloned repos.
88 safe_to_use = os.name != 'nt' or (not util.is_win_9x() and 88 safe_to_use = os.name != 'nt' or (not util.is_win_9x() and
89 hasattr(util, 'win32api')) 89 hasattr(util, 'win32api'))
90 90
91 def __init__(self, dataf, size, indexformat, shaoffset): 91 def __init__(self, dataf, size):
92 self.dataf = dataf 92 self.dataf = dataf
93 self.format = indexformat 93 self.s = struct.calcsize(indexformatng)
94 self.s = struct.calcsize(indexformat)
95 self.indexformat = indexformat
96 self.datasize = size 94 self.datasize = size
97 self.l = size/self.s 95 self.l = size/self.s
98 self.index = [None] * self.l 96 self.index = [None] * self.l
99 self.map = {nullid: nullrev} 97 self.map = {nullid: nullrev}
100 self.allmap = 0 98 self.allmap = 0
101 self.all = 0 99 self.all = 0
102 self.mapfind_count = 0 100 self.mapfind_count = 0
103 self.shaoffset = shaoffset
104 101
105 def loadmap(self): 102 def loadmap(self):
106 """ 103 """
107 during a commit, we need to make sure the rev being added is 104 during a commit, we need to make sure the rev being added is
108 not a duplicate. This requires loading the entire index, 105 not a duplicate. This requires loading the entire index,
118 self.dataf.seek(0) 115 self.dataf.seek(0)
119 while cur < end: 116 while cur < end:
120 data = self.dataf.read(blocksize) 117 data = self.dataf.read(blocksize)
121 off = 0 118 off = 0
122 for x in xrange(256): 119 for x in xrange(256):
123 n = data[off + self.shaoffset:off + self.shaoffset + 20] 120 n = data[off + ngshaoffset:off + ngshaoffset + 20]
124 self.map[n] = count 121 self.map[n] = count
125 count += 1 122 count += 1
126 if count >= self.l: 123 if count >= self.l:
127 break 124 break
128 off += self.s 125 off += self.s
146 lend = len(self.index) - i 143 lend = len(self.index) - i
147 for x in xrange(lend): 144 for x in xrange(lend):
148 if self.index[i + x] == None: 145 if self.index[i + x] == None:
149 b = data[off : off + self.s] 146 b = data[off : off + self.s]
150 self.index[i + x] = b 147 self.index[i + x] = b
151 n = b[self.shaoffset:self.shaoffset + 20] 148 n = b[ngshaoffset:ngshaoffset + 20]
152 self.map[n] = i + x 149 self.map[n] = i + x
153 off += self.s 150 off += self.s
154 151
155 def findnode(self, node): 152 def findnode(self, node):
156 """search backwards through the index file for a specific node""" 153 """search backwards through the index file for a specific node"""
185 off = data.rfind(node, 0, findend) 182 off = data.rfind(node, 0, findend)
186 findend = off 183 findend = off
187 if off >= 0: 184 if off >= 0:
188 i = off / self.s 185 i = off / self.s
189 off = i * self.s 186 off = i * self.s
190 n = data[off + self.shaoffset:off + self.shaoffset + 20] 187 n = data[off + ngshaoffset:off + ngshaoffset + 20]
191 if n == node: 188 if n == node:
192 self.map[n] = i + start / self.s 189 self.map[n] = i + start / self.s
193 return node 190 return node
194 else: 191 else:
195 break 192 break
230 self.p.loadindex(pos) 227 self.p.loadindex(pos)
231 return self.p.index[pos] 228 return self.p.index[pos]
232 def __getitem__(self, pos): 229 def __getitem__(self, pos):
233 ret = self.p.index[pos] or self.load(pos) 230 ret = self.p.index[pos] or self.load(pos)
234 if isinstance(ret, str): 231 if isinstance(ret, str):
235 ret = struct.unpack(self.p.indexformat, ret) 232 ret = struct.unpack(indexformatng, ret)
236 return ret 233 return ret
237 def __setitem__(self, pos, item): 234 def __setitem__(self, pos, item):
238 self.p.index[pos] = item 235 self.p.index[pos] = item
239 def __delitem__(self, pos): 236 def __delitem__(self, pos):
240 del self.p.index[pos] 237 del self.p.index[pos]
260 ret = self.p.index[i] 257 ret = self.p.index[i]
261 if not ret: 258 if not ret:
262 self.p.loadindex(i) 259 self.p.loadindex(i)
263 ret = self.p.index[i] 260 ret = self.p.index[i]
264 if isinstance(ret, str): 261 if isinstance(ret, str):
265 ret = struct.unpack(self.p.indexformat, ret) 262 ret = struct.unpack(indexformatng, ret)
266 yield ret[-1] 263 yield ret[-1]
267 def __getitem__(self, key): 264 def __getitem__(self, key):
268 try: 265 try:
269 return self.p.map[key] 266 return self.p.map[key]
270 except KeyError: 267 except KeyError:
319 316
320 def parseindex(self, fp, st, inline): 317 def parseindex(self, fp, st, inline):
321 if (lazyparser.safe_to_use and not inline and 318 if (lazyparser.safe_to_use and not inline and
322 st and st.st_size > 1000000): 319 st and st.st_size > 1000000):
323 # big index, let's parse it on demand 320 # big index, let's parse it on demand
324 parser = lazyparser(fp, st.st_size, indexformatng, ngshaoffset) 321 parser = lazyparser(fp, st.st_size)
325 index = lazyindex(parser) 322 index = lazyindex(parser)
326 nodemap = lazymap(parser) 323 nodemap = lazymap(parser)
327 e = list(index[0]) 324 e = list(index[0])
328 type = gettype(e[0]) 325 type = gettype(e[0])
329 e[0] = offset_type(0, type) 326 e[0] = offset_type(0, type)