Mercurial > public > mercurial-scm > hg
comparison mercurial/revlog.py @ 14296:62e25c63fb3a
revlog: fix bug in chainbase cache
The bug didn't cause corruption, and thus wasn't caught in hg verify or in
tests. It could lead to delta chains longer than normally allowed, by
affecting the code that decides when to add a full revision. This could,
in turn, lead to performance regression.
author | Sune Foldager <cryo@cyanite.org> |
---|---|
date | Thu, 12 May 2011 13:47:17 +0200 |
parents | c97d8485b5fa |
children | f94993769c87 |
comparison
equal
deleted
inserted
replaced
14295:bb7e3b3e6e11 | 14296:62e25c63fb3a |
---|---|
216 """ | 216 """ |
217 self.indexfile = indexfile | 217 self.indexfile = indexfile |
218 self.datafile = indexfile[:-2] + ".d" | 218 self.datafile = indexfile[:-2] + ".d" |
219 self.opener = opener | 219 self.opener = opener |
220 self._cache = None | 220 self._cache = None |
221 self._basecache = None | 221 self._basecache = (0, 0) |
222 self._chunkcache = (0, '') | 222 self._chunkcache = (0, '') |
223 self.index = [] | 223 self.index = [] |
224 self._pcache = {} | 224 self._pcache = {} |
225 self._nodecache = {nullid: nullrev} | 225 self._nodecache = {nullid: nullrev} |
226 self._nodepos = None | 226 self._nodepos = None |
1008 t = buildtext() | 1008 t = buildtext() |
1009 ptext = self.revision(self.node(rev)) | 1009 ptext = self.revision(self.node(rev)) |
1010 delta = mdiff.textdiff(ptext, t) | 1010 delta = mdiff.textdiff(ptext, t) |
1011 data = compress(delta) | 1011 data = compress(delta) |
1012 l = len(data[1]) + len(data[0]) | 1012 l = len(data[1]) + len(data[0]) |
1013 basecache = self._basecache | 1013 if basecache[0] == rev: |
1014 if basecache and basecache[0] == rev: | |
1015 chainbase = basecache[1] | 1014 chainbase = basecache[1] |
1016 else: | 1015 else: |
1017 chainbase = self.chainbase(rev) | 1016 chainbase = self.chainbase(rev) |
1018 dist = l + offset - self.start(chainbase) | 1017 dist = l + offset - self.start(chainbase) |
1019 if self._generaldelta: | 1018 if self._generaldelta: |
1020 base = rev | 1019 base = rev |
1021 else: | 1020 else: |
1022 base = chainbase | 1021 base = chainbase |
1023 return dist, l, data, base | 1022 return dist, l, data, base, chainbase |
1024 | 1023 |
1025 curr = len(self) | 1024 curr = len(self) |
1026 prev = curr - 1 | 1025 prev = curr - 1 |
1027 base = curr | 1026 base = chainbase = curr |
1028 offset = self.end(prev) | 1027 offset = self.end(prev) |
1029 flags = 0 | 1028 flags = 0 |
1030 d = None | 1029 d = None |
1030 basecache = self._basecache | |
1031 p1r, p2r = self.rev(p1), self.rev(p2) | 1031 p1r, p2r = self.rev(p1), self.rev(p2) |
1032 | 1032 |
1033 # should we try to build a delta? | 1033 # should we try to build a delta? |
1034 if prev != nullrev: | 1034 if prev != nullrev: |
1035 if self._generaldelta: | 1035 if self._generaldelta: |
1036 d = builddelta(p1r) | 1036 d = builddelta(p1r) |
1037 else: | 1037 else: |
1038 d = builddelta(prev) | 1038 d = builddelta(prev) |
1039 dist, l, data, base = d | 1039 dist, l, data, base, chainbase = d |
1040 | 1040 |
1041 # full versions are inserted when the needed deltas | 1041 # full versions are inserted when the needed deltas |
1042 # become comparable to the uncompressed text | 1042 # become comparable to the uncompressed text |
1043 if text is None: | 1043 if text is None: |
1044 textlen = mdiff.patchedsize(self.rawsize(cachedelta[0]), | 1044 textlen = mdiff.patchedsize(self.rawsize(cachedelta[0]), |
1047 textlen = len(text) | 1047 textlen = len(text) |
1048 if d is None or dist > textlen * 2: | 1048 if d is None or dist > textlen * 2: |
1049 text = buildtext() | 1049 text = buildtext() |
1050 data = compress(text) | 1050 data = compress(text) |
1051 l = len(data[1]) + len(data[0]) | 1051 l = len(data[1]) + len(data[0]) |
1052 base = curr | 1052 base = chainbase = curr |
1053 | 1053 |
1054 e = (offset_type(offset, flags), l, textlen, | 1054 e = (offset_type(offset, flags), l, textlen, |
1055 base, link, p1r, p2r, node) | 1055 base, link, p1r, p2r, node) |
1056 self.index.insert(-1, e) | 1056 self.index.insert(-1, e) |
1057 self.nodemap[node] = curr | 1057 self.nodemap[node] = curr |
1073 ifh.write(data[1]) | 1073 ifh.write(data[1]) |
1074 self.checkinlinesize(transaction, ifh) | 1074 self.checkinlinesize(transaction, ifh) |
1075 | 1075 |
1076 if type(text) == str: # only accept immutable objects | 1076 if type(text) == str: # only accept immutable objects |
1077 self._cache = (node, curr, text) | 1077 self._cache = (node, curr, text) |
1078 self._basecache = (curr, base) | 1078 self._basecache = (curr, chainbase) |
1079 return node | 1079 return node |
1080 | 1080 |
1081 def group(self, nodelist, bundler): | 1081 def group(self, nodelist, bundler): |
1082 """Calculate a delta group, yielding a sequence of changegroup chunks | 1082 """Calculate a delta group, yielding a sequence of changegroup chunks |
1083 (strings). | 1083 (strings). |