Mercurial > public > mercurial-scm > hg
comparison mercurial/revlogutils/deltas.py @ 49226:e6b7c6fbeb48
deltas: add code to display information about the result of `finddeltainfo`
I have been looking into performance issue around pull and getting more
information about the computation and time involved into applying each revision
is very useful. There will be various way to use this new output, so I am
introducing the code first.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Thu, 19 May 2022 23:39:23 +0100 |
parents | 642e31cb55f0 |
children | b909dd35d9ab |
comparison
equal
deleted
inserted
replaced
49225:58a814d062ca | 49226:e6b7c6fbeb48 |
---|---|
18 | 18 |
19 from .constants import ( | 19 from .constants import ( |
20 COMP_MODE_DEFAULT, | 20 COMP_MODE_DEFAULT, |
21 COMP_MODE_INLINE, | 21 COMP_MODE_INLINE, |
22 COMP_MODE_PLAIN, | 22 COMP_MODE_PLAIN, |
23 KIND_CHANGELOG, | |
24 KIND_FILELOG, | |
25 KIND_MANIFESTLOG, | |
23 REVIDX_ISCENSORED, | 26 REVIDX_ISCENSORED, |
24 REVIDX_RAWTEXT_CHANGING_FLAGS, | 27 REVIDX_RAWTEXT_CHANGING_FLAGS, |
25 ) | 28 ) |
26 | 29 |
27 from ..thirdparty import attr | 30 from ..thirdparty import attr |
926 # fulltext. | 929 # fulltext. |
927 yield (prev,) | 930 yield (prev,) |
928 | 931 |
929 | 932 |
930 class deltacomputer: | 933 class deltacomputer: |
931 def __init__(self, revlog): | 934 def __init__(self, revlog, write_debug=None): |
932 self.revlog = revlog | 935 self.revlog = revlog |
936 self._write_debug = write_debug | |
933 | 937 |
934 def buildtext(self, revinfo, fh): | 938 def buildtext(self, revinfo, fh): |
935 """Builds a fulltext version of a revision | 939 """Builds a fulltext version of a revision |
936 | 940 |
937 revinfo: revisioninfo instance that contains all needed info | 941 revinfo: revisioninfo instance that contains all needed info |
1081 # not calling candelta since only one revision needs test, also to | 1085 # not calling candelta since only one revision needs test, also to |
1082 # avoid overhead fetching flags again. | 1086 # avoid overhead fetching flags again. |
1083 if revinfo.flags & REVIDX_RAWTEXT_CHANGING_FLAGS: | 1087 if revinfo.flags & REVIDX_RAWTEXT_CHANGING_FLAGS: |
1084 return self._fullsnapshotinfo(fh, revinfo, target_rev) | 1088 return self._fullsnapshotinfo(fh, revinfo, target_rev) |
1085 | 1089 |
1090 if self._write_debug is not None: | |
1091 start = util.timer() | |
1092 | |
1093 # count the number of different delta we tried (for debug purpose) | |
1094 dbg_try_count = 0 | |
1095 # count the number of "search round" we did. (for debug purpose) | |
1096 dbg_try_rounds = 0 | |
1097 dbg_type = b'unknown' | |
1098 | |
1086 cachedelta = revinfo.cachedelta | 1099 cachedelta = revinfo.cachedelta |
1087 p1 = revinfo.p1 | 1100 p1 = revinfo.p1 |
1088 p2 = revinfo.p2 | 1101 p2 = revinfo.p2 |
1089 revlog = self.revlog | 1102 revlog = self.revlog |
1090 | 1103 |
1091 deltainfo = None | 1104 deltainfo = None |
1092 p1r, p2r = revlog.rev(p1), revlog.rev(p2) | 1105 p1r, p2r = revlog.rev(p1), revlog.rev(p2) |
1106 | |
1107 if self._write_debug is not None: | |
1108 if p1r != nullrev: | |
1109 p1_chain_len = revlog._chaininfo(p1r)[0] | |
1110 else: | |
1111 p1_chain_len = -1 | |
1112 if p2r != nullrev: | |
1113 p2_chain_len = revlog._chaininfo(p2r)[0] | |
1114 else: | |
1115 p2_chain_len = -1 | |
1116 | |
1093 groups = _candidategroups( | 1117 groups = _candidategroups( |
1094 self.revlog, revinfo.textlen, p1r, p2r, cachedelta | 1118 self.revlog, revinfo.textlen, p1r, p2r, cachedelta |
1095 ) | 1119 ) |
1096 candidaterevs = next(groups) | 1120 candidaterevs = next(groups) |
1097 while candidaterevs is not None: | 1121 while candidaterevs is not None: |
1122 dbg_try_rounds += 1 | |
1098 nominateddeltas = [] | 1123 nominateddeltas = [] |
1099 if deltainfo is not None: | 1124 if deltainfo is not None: |
1100 # if we already found a good delta, | 1125 # if we already found a good delta, |
1101 # challenge it against refined candidates | 1126 # challenge it against refined candidates |
1102 nominateddeltas.append(deltainfo) | 1127 nominateddeltas.append(deltainfo) |
1103 for candidaterev in candidaterevs: | 1128 for candidaterev in candidaterevs: |
1104 if candidaterev in excluded_bases: | 1129 if candidaterev in excluded_bases: |
1105 continue | 1130 continue |
1106 if candidaterev >= target_rev: | 1131 if candidaterev >= target_rev: |
1107 continue | 1132 continue |
1133 dbg_try_count += 1 | |
1108 candidatedelta = self._builddeltainfo(revinfo, candidaterev, fh) | 1134 candidatedelta = self._builddeltainfo(revinfo, candidaterev, fh) |
1109 if candidatedelta is not None: | 1135 if candidatedelta is not None: |
1110 if isgooddeltainfo(self.revlog, candidatedelta, revinfo): | 1136 if isgooddeltainfo(self.revlog, candidatedelta, revinfo): |
1111 nominateddeltas.append(candidatedelta) | 1137 nominateddeltas.append(candidatedelta) |
1112 if nominateddeltas: | 1138 if nominateddeltas: |
1115 candidaterevs = groups.send(deltainfo.base) | 1141 candidaterevs = groups.send(deltainfo.base) |
1116 else: | 1142 else: |
1117 candidaterevs = next(groups) | 1143 candidaterevs = next(groups) |
1118 | 1144 |
1119 if deltainfo is None: | 1145 if deltainfo is None: |
1146 dbg_type = b"full" | |
1120 deltainfo = self._fullsnapshotinfo(fh, revinfo, target_rev) | 1147 deltainfo = self._fullsnapshotinfo(fh, revinfo, target_rev) |
1148 elif deltainfo.snapshotdepth: | |
1149 dbg_type = b"snapshot" | |
1150 else: | |
1151 dbg_type = b"delta" | |
1152 | |
1153 if self._write_debug is not None: | |
1154 end = util.timer() | |
1155 dbg = { | |
1156 'duration': end - start, | |
1157 'revision': target_rev, | |
1158 'search_round_count': dbg_try_rounds, | |
1159 'delta_try_count': dbg_try_count, | |
1160 'type': dbg_type, | |
1161 'p1-chain-len': p1_chain_len, | |
1162 'p2-chain-len': p2_chain_len, | |
1163 } | |
1164 if deltainfo.snapshotdepth is not None: | |
1165 dbg['snapshot-depth'] = deltainfo.snapshotdepth | |
1166 else: | |
1167 dbg['snapshot-depth'] = 0 | |
1168 target_revlog = b"UNKNOWN" | |
1169 target_type = self.revlog.target[0] | |
1170 target_key = self.revlog.target[1] | |
1171 if target_type == KIND_CHANGELOG: | |
1172 target_revlog = b'CHANGELOG:' | |
1173 elif target_type == KIND_MANIFESTLOG: | |
1174 target_revlog = b'MANIFESTLOG:' | |
1175 if target_key: | |
1176 target_revlog += b'%s:' % target_key | |
1177 elif target_type == KIND_FILELOG: | |
1178 target_revlog = b'FILELOG:' | |
1179 if target_key: | |
1180 target_revlog += b'%s:' % target_key | |
1181 dbg['target-revlog'] = target_revlog | |
1182 | |
1183 msg = ( | |
1184 b"DBG-DELTAS:" | |
1185 b" %-12s" | |
1186 b" rev=%d:" | |
1187 b" search-rounds=%d" | |
1188 b" try-count=%d" | |
1189 b" - delta-type=%-6s" | |
1190 b" snap-depth=%d" | |
1191 b" - p1-chain-length=%d" | |
1192 b" p2-chain-length=%d" | |
1193 b" - duration=%f" | |
1194 b"\n" | |
1195 ) | |
1196 msg %= ( | |
1197 dbg["target-revlog"], | |
1198 dbg["revision"], | |
1199 dbg["search_round_count"], | |
1200 dbg["delta_try_count"], | |
1201 dbg["type"], | |
1202 dbg["snapshot-depth"], | |
1203 dbg["p1-chain-len"], | |
1204 dbg["p2-chain-len"], | |
1205 dbg["duration"], | |
1206 ) | |
1207 self._write_debug(msg) | |
1121 return deltainfo | 1208 return deltainfo |
1122 | 1209 |
1123 | 1210 |
1124 def delta_compression(default_compression_header, deltainfo): | 1211 def delta_compression(default_compression_header, deltainfo): |
1125 """return (COMPRESSION_MODE, deltainfo) | 1212 """return (COMPRESSION_MODE, deltainfo) |