Mercurial > public > mercurial-scm > hg
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) |