Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/revlog.py @ 4980:fc44c8df9d99
revlog: some codingstyle cleanups
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Mon, 23 Jul 2007 20:44:08 -0500 |
parents | 06abdaf78788 |
children | e7131935fbb3 |
comparison
equal
deleted
inserted
replaced
4979:06abdaf78788 | 4980:fc44c8df9d99 |
---|---|
40 s.update(text) | 40 s.update(text) |
41 return s.digest() | 41 return s.digest() |
42 | 42 |
43 def compress(text): | 43 def compress(text): |
44 """ generate a possibly-compressed representation of text """ | 44 """ generate a possibly-compressed representation of text """ |
45 if not text: return ("", text) | 45 if not text: |
46 return ("", text) | |
46 if len(text) < 44: | 47 if len(text) < 44: |
47 if text[0] == '\0': return ("", text) | 48 if text[0] == '\0': |
49 return ("", text) | |
48 return ('u', text) | 50 return ('u', text) |
49 bin = zlib.compress(text) | 51 bin = zlib.compress(text) |
50 if len(bin) > len(text): | 52 if len(bin) > len(text): |
51 if text[0] == '\0': return ("", text) | 53 if text[0] == '\0': |
54 return ("", text) | |
52 return ('u', text) | 55 return ('u', text) |
53 return ("", bin) | 56 return ("", bin) |
54 | 57 |
55 def decompress(bin): | 58 def decompress(bin): |
56 """ decompress the given input """ | 59 """ decompress the given input """ |
57 if not bin: return bin | 60 if not bin: |
61 return bin | |
58 t = bin[0] | 62 t = bin[0] |
59 if t == '\0': return bin | 63 if t == '\0': |
60 if t == 'x': return zlib.decompress(bin) | 64 return bin |
61 if t == 'u': return bin[1:] | 65 if t == 'x': |
66 return zlib.decompress(bin) | |
67 if t == 'u': | |
68 return bin[1:] | |
62 raise RevlogError(_("unknown compression type %r") % t) | 69 raise RevlogError(_("unknown compression type %r") % t) |
63 | 70 |
64 indexformatv0 = ">4l20s20s20s" | 71 indexformatv0 = ">4l20s20s20s" |
65 v0shaoffset = 56 | 72 v0shaoffset = 56 |
66 # index ng: | 73 # index ng: |
104 during a commit, we need to make sure the rev being added is | 111 during a commit, we need to make sure the rev being added is |
105 not a duplicate. This requires loading the entire index, | 112 not a duplicate. This requires loading the entire index, |
106 which is fairly slow. loadmap can load up just the node map, | 113 which is fairly slow. loadmap can load up just the node map, |
107 which takes much less time. | 114 which takes much less time. |
108 """ | 115 """ |
109 if self.allmap: return | 116 if self.allmap: |
117 return | |
110 end = self.datasize | 118 end = self.datasize |
111 self.allmap = 1 | 119 self.allmap = 1 |
112 cur = 0 | 120 cur = 0 |
113 count = 0 | 121 count = 0 |
114 blocksize = self.s * 256 | 122 blocksize = self.s * 256 |
124 break | 132 break |
125 off += self.s | 133 off += self.s |
126 cur += blocksize | 134 cur += blocksize |
127 | 135 |
128 def loadblock(self, blockstart, blocksize, data=None): | 136 def loadblock(self, blockstart, blocksize, data=None): |
129 if self.all: return | 137 if self.all: |
138 return | |
130 if data is None: | 139 if data is None: |
131 self.dataf.seek(blockstart) | 140 self.dataf.seek(blockstart) |
132 if blockstart + blocksize > self.datasize: | 141 if blockstart + blocksize > self.datasize: |
133 # the revlog may have grown since we've started running, | 142 # the revlog may have grown since we've started running, |
134 # but we don't have space in self.index for more entries. | 143 # but we don't have space in self.index for more entries. |
149 self.map[n] = i + x | 158 self.map[n] = i + x |
150 off += self.s | 159 off += self.s |
151 | 160 |
152 def findnode(self, node): | 161 def findnode(self, node): |
153 """search backwards through the index file for a specific node""" | 162 """search backwards through the index file for a specific node""" |
154 if self.allmap: return None | 163 if self.allmap: |
164 return None | |
155 | 165 |
156 # hg log will cause many many searches for the manifest | 166 # hg log will cause many many searches for the manifest |
157 # nodes. After we get called a few times, just load the whole | 167 # nodes. After we get called a few times, just load the whole |
158 # thing. | 168 # thing. |
159 if self.mapfind_count > 8: | 169 if self.mapfind_count > 8: |
192 break | 202 break |
193 end -= blocksize | 203 end -= blocksize |
194 return None | 204 return None |
195 | 205 |
196 def loadindex(self, i=None, end=None): | 206 def loadindex(self, i=None, end=None): |
197 if self.all: return | 207 if self.all: |
208 return | |
198 all = False | 209 all = False |
199 if i == None: | 210 if i == None: |
200 blockstart = 0 | 211 blockstart = 0 |
201 blocksize = (512 / self.s) * self.s | 212 blocksize = (512 / self.s) * self.s |
202 end = self.datasize | 213 end = self.datasize |
211 blocksize = self.s * 64 | 222 blocksize = self.s * 64 |
212 end = blockstart + blocksize | 223 end = blockstart + blocksize |
213 while blockstart < end: | 224 while blockstart < end: |
214 self.loadblock(blockstart, blocksize) | 225 self.loadblock(blockstart, blocksize) |
215 blockstart += blocksize | 226 blockstart += blocksize |
216 if all: self.all = True | 227 if all: |
228 self.all = True | |
217 | 229 |
218 class lazyindex(object): | 230 class lazyindex(object): |
219 """a lazy version of the index array""" | 231 """a lazy version of the index array""" |
220 def __init__(self, parser): | 232 def __init__(self, parser): |
221 self.p = parser | 233 self.p = parser |
275 def __setitem__(self, key, val): | 287 def __setitem__(self, key, val): |
276 self.p.map[key] = val | 288 self.p.map[key] = val |
277 def __delitem__(self, key): | 289 def __delitem__(self, key): |
278 del self.p.map[key] | 290 del self.p.map[key] |
279 | 291 |
280 class RevlogError(Exception): pass | 292 class RevlogError(Exception): |
281 class LookupError(RevlogError): pass | 293 pass |
294 class LookupError(RevlogError): | |
295 pass | |
282 | 296 |
283 def getoffset(q): | 297 def getoffset(q): |
284 if q & 0xFFFF: | 298 if q & 0xFFFF: |
285 raise RevlogError(_('incompatible revision flag %x') % q) | 299 raise RevlogError(_('incompatible revision flag %x') % q) |
286 return int(q >> 16) | 300 return int(q >> 16) |
472 """loads the map from the lazy parser""" | 486 """loads the map from the lazy parser""" |
473 if isinstance(self.nodemap, lazymap): | 487 if isinstance(self.nodemap, lazymap): |
474 self.nodemap.p.loadmap() | 488 self.nodemap.p.loadmap() |
475 self.nodemap = self.nodemap.p.map | 489 self.nodemap = self.nodemap.p.map |
476 | 490 |
477 def _inline(self): return self.version & REVLOGNGINLINEDATA | 491 def _inline(self): |
478 | 492 return self.version & REVLOGNGINLINEDATA |
479 def tip(self): return self.node(len(self.index) - 2) | 493 def tip(self): |
480 def count(self): return len(self.index) - 1 | 494 return self.node(len(self.index) - 2) |
481 def node(self, rev): | 495 def count(self): |
482 return self.index[rev][7] | 496 return len(self.index) - 1 |
497 | |
483 def rev(self, node): | 498 def rev(self, node): |
484 try: | 499 try: |
485 return self.nodemap[node] | 500 return self.nodemap[node] |
486 except KeyError: | 501 except KeyError: |
487 raise LookupError(_('%s: no node %s') % (self.indexfile, hex(node))) | 502 raise LookupError(_('%s: no node %s') % (self.indexfile, hex(node))) |
503 def node(self, rev): | |
504 return self.index[rev][7] | |
488 def linkrev(self, node): | 505 def linkrev(self, node): |
489 return self.index[self.rev(node)][4] | 506 return self.index[self.rev(node)][4] |
490 def parents(self, node): | 507 def parents(self, node): |
491 d = self.index[self.rev(node)][5:7] | 508 d = self.index[self.rev(node)][5:7] |
492 return (self.node(d[0]), self.node(d[1])) | 509 return (self.node(d[0]), self.node(d[1])) |
493 def parentrevs(self, rev): | 510 def parentrevs(self, rev): |
494 return self.index[rev][5:7] | 511 return self.index[rev][5:7] |
495 def start(self, rev): | 512 def start(self, rev): |
496 return getoffset(self.index[rev][0]) | 513 return getoffset(self.index[rev][0]) |
497 def end(self, rev): return self.start(rev) + self.length(rev) | 514 def end(self, rev): |
515 return self.start(rev) + self.length(rev) | |
516 def length(self, rev): | |
517 return self.index[rev][1] | |
518 def base(self, rev): | |
519 return self.index[rev][3] | |
498 | 520 |
499 def size(self, rev): | 521 def size(self, rev): |
500 """return the length of the uncompressed text for a given revision""" | 522 """return the length of the uncompressed text for a given revision""" |
501 l = self.index[rev][2] | 523 l = self.index[rev][2] |
502 if l >= 0: | 524 if l >= 0: |
522 l = len(text) | 544 l = len(text) |
523 for x in xrange(base + 1, rev + 1): | 545 for x in xrange(base + 1, rev + 1): |
524 l = mdiff.patchedsize(l, self.chunk(x)) | 546 l = mdiff.patchedsize(l, self.chunk(x)) |
525 return l | 547 return l |
526 """ | 548 """ |
527 | |
528 def length(self, rev): | |
529 return self.index[rev][1] | |
530 def base(self, rev): | |
531 return self.index[rev][3] | |
532 | 549 |
533 def reachable(self, node, stop=None): | 550 def reachable(self, node, stop=None): |
534 """return a hash of all nodes ancestral to a given node, including | 551 """return a hash of all nodes ancestral to a given node, including |
535 the node itself, stopping when stop is matched""" | 552 the node itself, stopping when stop is matched""" |
536 reachable = {} | 553 reachable = {} |
762 except LookupError: | 779 except LookupError: |
763 pass # may be partial hex id | 780 pass # may be partial hex id |
764 try: | 781 try: |
765 # str(rev) | 782 # str(rev) |
766 rev = int(id) | 783 rev = int(id) |
767 if str(rev) != id: raise ValueError | 784 if str(rev) != id: |
768 if rev < 0: rev = self.count() + rev | 785 raise ValueError |
769 if rev < 0 or rev >= self.count(): raise ValueError | 786 if rev < 0: |
787 rev = self.count() + rev | |
788 if rev < 0 or rev >= self.count(): | |
789 raise ValueError | |
770 return self.node(rev) | 790 return self.node(rev) |
771 except (ValueError, OverflowError): | 791 except (ValueError, OverflowError): |
772 pass | 792 pass |
773 if len(id) == 40: | 793 if len(id) == 40: |
774 try: | 794 try: |
798 def lookup(self, id): | 818 def lookup(self, id): |
799 """locate a node based on: | 819 """locate a node based on: |
800 - revision number or str(revision number) | 820 - revision number or str(revision number) |
801 - nodeid or subset of hex nodeid | 821 - nodeid or subset of hex nodeid |
802 """ | 822 """ |
803 | |
804 n = self._match(id) | 823 n = self._match(id) |
805 if n is not None: | 824 if n is not None: |
806 return n | 825 return n |
807 n = self._partialmatch(id) | 826 n = self._partialmatch(id) |
808 if n: | 827 if n: |
849 offset = start - cache_start | 868 offset = start - cache_start |
850 else: | 869 else: |
851 loadcache(df) | 870 loadcache(df) |
852 offset = 0 | 871 offset = 0 |
853 | 872 |
854 #def checkchunk(): | |
855 # df = self.opener(self.datafile) | |
856 # df.seek(start) | |
857 # return df.read(length) | |
858 #assert s == checkchunk() | |
859 return decompress(self._io.chunkcache[1][offset:offset + length]) | 873 return decompress(self._io.chunkcache[1][offset:offset + length]) |
860 | 874 |
861 def delta(self, node): | 875 def delta(self, node): |
862 """return or calculate a delta between a node and its predecessor""" | 876 """return or calculate a delta between a node and its predecessor""" |
863 r = self.rev(node) | 877 r = self.rev(node) |
873 return self.diff(self.revision(self.node(rev1)), | 887 return self.diff(self.revision(self.node(rev1)), |
874 self.revision(self.node(rev2))) | 888 self.revision(self.node(rev2))) |
875 | 889 |
876 def revision(self, node): | 890 def revision(self, node): |
877 """return an uncompressed revision of a given""" | 891 """return an uncompressed revision of a given""" |
878 if node == nullid: return "" | 892 if node == nullid: |
879 if self.cache and self.cache[0] == node: return self.cache[2] | 893 return "" |
894 if self.cache and self.cache[0] == node: | |
895 return self.cache[2] | |
880 | 896 |
881 # look up what we need to read | 897 # look up what we need to read |
882 text = None | 898 text = None |
883 rev = self.rev(node) | 899 rev = self.rev(node) |
884 base = self.base(rev) | 900 base = self.base(rev) |
976 dfh = None | 992 dfh = None |
977 ifh = self.opener(self.indexfile, "a+") | 993 ifh = self.opener(self.indexfile, "a+") |
978 return self._addrevision(text, transaction, link, p1, p2, d, ifh, dfh) | 994 return self._addrevision(text, transaction, link, p1, p2, d, ifh, dfh) |
979 | 995 |
980 def _addrevision(self, text, transaction, link, p1, p2, d, ifh, dfh): | 996 def _addrevision(self, text, transaction, link, p1, p2, d, ifh, dfh): |
981 if text is None: text = "" | 997 if text is None: |
982 if p1 is None: p1 = self.tip() | 998 text = "" |
983 if p2 is None: p2 = nullid | 999 if p1 is None: |
1000 p1 = self.tip() | |
1001 if p2 is None: | |
1002 p2 = nullid | |
984 | 1003 |
985 node = hash(text, p1, p2) | 1004 node = hash(text, p1, p2) |
986 | 1005 |
987 if node in self.nodemap: | 1006 if node in self.nodemap: |
988 return node | 1007 return node |