291 Both pieces of the revlog are written to in an append-only |
291 Both pieces of the revlog are written to in an append-only |
292 fashion, which means we never need to rewrite a file to insert or |
292 fashion, which means we never need to rewrite a file to insert or |
293 remove data, and can use some simple techniques to avoid the need |
293 remove data, and can use some simple techniques to avoid the need |
294 for locking while reading. |
294 for locking while reading. |
295 """ |
295 """ |
296 def __init__(self, opener, indexfile, datafile, defversion=0): |
296 def __init__(self, opener, indexfile, datafile, defversion=REVLOGV0): |
297 """ |
297 """ |
298 create a revlog object |
298 create a revlog object |
299 |
299 |
300 opener is a function that abstracts the file opening operation |
300 opener is a function that abstracts the file opening operation |
301 and can be used to implement COW semantics or the like. |
301 and can be used to implement COW semantics or the like. |
335 self.indexstat = st |
335 self.indexstat = st |
336 if len(i) > 0: |
336 if len(i) > 0: |
337 v = struct.unpack(versionformat, i)[0] |
337 v = struct.unpack(versionformat, i)[0] |
338 flags = v & ~0xFFFF |
338 flags = v & ~0xFFFF |
339 fmt = v & 0xFFFF |
339 fmt = v & 0xFFFF |
340 if fmt == 0: |
340 if fmt == REVLOGV0: |
341 if flags: |
341 if flags: |
342 raise RevlogError(_("index %s invalid flags %x for format v0" % |
342 raise RevlogError(_("index %s invalid flags %x for format v0" % |
343 (self.indexfile, flags))) |
343 (self.indexfile, flags))) |
344 elif fmt == REVLOGNG: |
344 elif fmt == REVLOGNG: |
345 if flags & ~REVLOGNGINLINEDATA: |
345 if flags & ~REVLOGNGINLINEDATA: |
347 (self.indexfile, flags))) |
347 (self.indexfile, flags))) |
348 else: |
348 else: |
349 raise RevlogError(_("index %s invalid format %d" % |
349 raise RevlogError(_("index %s invalid format %d" % |
350 (self.indexfile, fmt))) |
350 (self.indexfile, fmt))) |
351 self.version = v |
351 self.version = v |
352 if v == 0: |
352 if v == REVLOGV0: |
353 self.indexformat = indexformatv0 |
353 self.indexformat = indexformatv0 |
354 shaoffset = v0shaoffset |
354 shaoffset = v0shaoffset |
355 else: |
355 else: |
356 self.indexformat = indexformatng |
356 self.indexformat = indexformatng |
357 shaoffset = ngshaoffset |
357 shaoffset = ngshaoffset |
367 self.parseindex(i) |
367 self.parseindex(i) |
368 if self.inlinedata(): |
368 if self.inlinedata(): |
369 # we've already got the entire data file read in, save it |
369 # we've already got the entire data file read in, save it |
370 # in the chunk data |
370 # in the chunk data |
371 self.chunkcache = (0, i) |
371 self.chunkcache = (0, i) |
372 if self.version != 0: |
372 if self.version != REVLOGV0: |
373 e = list(self.index[0]) |
373 e = list(self.index[0]) |
374 type = self.ngtype(e[0]) |
374 type = self.ngtype(e[0]) |
375 e[0] = self.offset_type(0, type) |
375 e[0] = self.offset_type(0, type) |
376 self.index[0] = e |
376 self.index[0] = e |
377 else: |
377 else: |
439 def linkrev(self, node): return self.index[self.rev(node)][-4] |
439 def linkrev(self, node): return self.index[self.rev(node)][-4] |
440 def parents(self, node): |
440 def parents(self, node): |
441 if node == nullid: return (nullid, nullid) |
441 if node == nullid: return (nullid, nullid) |
442 r = self.rev(node) |
442 r = self.rev(node) |
443 d = self.index[r][-3:-1] |
443 d = self.index[r][-3:-1] |
444 if self.version == 0: |
444 if self.version == REVLOGV0: |
445 return d |
445 return d |
446 return [ self.node(x) for x in d ] |
446 return [ self.node(x) for x in d ] |
447 def start(self, rev): |
447 def start(self, rev): |
448 if rev < 0: |
448 if rev < 0: |
449 return -1 |
449 return -1 |
450 if self.version != 0: |
450 if self.version != REVLOGV0: |
451 return self.ngoffset(self.index[rev][0]) |
451 return self.ngoffset(self.index[rev][0]) |
452 return self.index[rev][0] |
452 return self.index[rev][0] |
453 |
453 |
454 def end(self, rev): return self.start(rev) + self.length(rev) |
454 def end(self, rev): return self.start(rev) + self.length(rev) |
455 |
455 |
456 def size(self, rev): |
456 def size(self, rev): |
457 """return the length of the uncompressed text for a given revision""" |
457 """return the length of the uncompressed text for a given revision""" |
458 l = -1 |
458 l = -1 |
459 if self.version != 0: |
459 if self.version != REVLOGV0: |
460 l = self.index[rev][2] |
460 l = self.index[rev][2] |
461 if l >= 0: |
461 if l >= 0: |
462 return l |
462 return l |
463 |
463 |
464 t = self.revision(self.node(rev)) |
464 t = self.revision(self.node(rev)) |
909 |
909 |
910 offset = 0 |
910 offset = 0 |
911 if t >= 0: |
911 if t >= 0: |
912 offset = self.end(t) |
912 offset = self.end(t) |
913 |
913 |
914 if self.version == 0: |
914 if self.version == REVLOGV0: |
915 e = (offset, l, base, link, p1, p2, node) |
915 e = (offset, l, base, link, p1, p2, node) |
916 else: |
916 else: |
917 e = (self.offset_type(offset, 0), l, len(text), |
917 e = (self.offset_type(offset, 0), l, len(text), |
918 base, link, self.rev(p1), self.rev(p2), node) |
918 base, link, self.rev(p1), self.rev(p2), node) |
919 |
919 |
933 else: |
933 else: |
934 f = self.opener(self.indexfile, "a+") |
934 f = self.opener(self.indexfile, "a+") |
935 f.seek(0, 2) |
935 f.seek(0, 2) |
936 transaction.add(self.indexfile, f.tell(), self.count() - 1) |
936 transaction.add(self.indexfile, f.tell(), self.count() - 1) |
937 |
937 |
938 if len(self.index) == 1 and self.version != 0: |
938 if len(self.index) == 1 and self.version != REVLOGV0: |
939 l = struct.pack(versionformat, self.version) |
939 l = struct.pack(versionformat, self.version) |
940 f.write(l) |
940 f.write(l) |
941 entry = entry[4:] |
941 entry = entry[4:] |
942 |
942 |
943 f.write(entry) |
943 f.write(entry) |
1133 chk = self.addrevision(text, transaction, link, p1, p2) |
1133 chk = self.addrevision(text, transaction, link, p1, p2) |
1134 if chk != node: |
1134 if chk != node: |
1135 raise RevlogError(_("consistency error adding group")) |
1135 raise RevlogError(_("consistency error adding group")) |
1136 textlen = len(text) |
1136 textlen = len(text) |
1137 else: |
1137 else: |
1138 if self.version == 0: |
1138 if self.version == REVLOGV0: |
1139 e = (end, len(cdelta), base, link, p1, p2, node) |
1139 e = (end, len(cdelta), base, link, p1, p2, node) |
1140 else: |
1140 else: |
1141 e = (self.offset_type(end, 0), len(cdelta), textlen, base, |
1141 e = (self.offset_type(end, 0), len(cdelta), textlen, base, |
1142 link, self.rev(p1), self.rev(p2), node) |
1142 link, self.rev(p1), self.rev(p2), node) |
1143 self.index.append(e) |
1143 self.index.append(e) |