##// END OF EJS Templates
debug-revlog-stats: make it use the new store entry API...
marmoute -
r51574:47b44d80 default
parent child Browse files
Show More
@@ -1,721 +1,710 b''
1 # revlogutils/debug.py - utility used for revlog debuging
1 # revlogutils/debug.py - utility used for revlog debuging
2 #
2 #
3 # Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
3 # Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
4 # Copyright 2022 Octobus <contact@octobus.net>
4 # Copyright 2022 Octobus <contact@octobus.net>
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 import collections
9 import collections
10 import string
10 import string
11
11
12 from .. import (
12 from .. import (
13 mdiff,
13 mdiff,
14 node as nodemod,
14 node as nodemod,
15 revlogutils,
15 revlogutils,
16 util,
16 util,
17 )
17 )
18
18
19 from . import (
19 from . import (
20 constants,
20 constants,
21 deltas as deltautil,
21 deltas as deltautil,
22 )
22 )
23
23
24 INDEX_ENTRY_DEBUG_COLUMN = []
24 INDEX_ENTRY_DEBUG_COLUMN = []
25
25
26 NODE_SIZE = object()
26 NODE_SIZE = object()
27
27
28
28
29 class _column_base:
29 class _column_base:
30 """constains the definition of a revlog column
30 """constains the definition of a revlog column
31
31
32 name: the column header,
32 name: the column header,
33 value_func: the function called to get a value,
33 value_func: the function called to get a value,
34 size: the width of the column,
34 size: the width of the column,
35 verbose_only: only include the column in verbose mode.
35 verbose_only: only include the column in verbose mode.
36 """
36 """
37
37
38 def __init__(self, name, value_func, size=None, verbose=False):
38 def __init__(self, name, value_func, size=None, verbose=False):
39 self.name = name
39 self.name = name
40 self.value_func = value_func
40 self.value_func = value_func
41 if size is not NODE_SIZE:
41 if size is not NODE_SIZE:
42 if size is None:
42 if size is None:
43 size = 8 # arbitrary default
43 size = 8 # arbitrary default
44 size = max(len(name), size)
44 size = max(len(name), size)
45 self._size = size
45 self._size = size
46 self.verbose_only = verbose
46 self.verbose_only = verbose
47
47
48 def get_size(self, node_size):
48 def get_size(self, node_size):
49 if self._size is NODE_SIZE:
49 if self._size is NODE_SIZE:
50 return node_size
50 return node_size
51 else:
51 else:
52 return self._size
52 return self._size
53
53
54
54
55 def debug_column(name, size=None, verbose=False):
55 def debug_column(name, size=None, verbose=False):
56 """decorated function is registered as a column
56 """decorated function is registered as a column
57
57
58 name: the name of the column,
58 name: the name of the column,
59 size: the expected size of the column.
59 size: the expected size of the column.
60 """
60 """
61
61
62 def register(func):
62 def register(func):
63 entry = _column_base(
63 entry = _column_base(
64 name=name,
64 name=name,
65 value_func=func,
65 value_func=func,
66 size=size,
66 size=size,
67 verbose=verbose,
67 verbose=verbose,
68 )
68 )
69 INDEX_ENTRY_DEBUG_COLUMN.append(entry)
69 INDEX_ENTRY_DEBUG_COLUMN.append(entry)
70 return entry
70 return entry
71
71
72 return register
72 return register
73
73
74
74
75 @debug_column(b"rev", size=6)
75 @debug_column(b"rev", size=6)
76 def _rev(index, rev, entry, hexfn):
76 def _rev(index, rev, entry, hexfn):
77 return b"%d" % rev
77 return b"%d" % rev
78
78
79
79
80 @debug_column(b"rank", size=6, verbose=True)
80 @debug_column(b"rank", size=6, verbose=True)
81 def rank(index, rev, entry, hexfn):
81 def rank(index, rev, entry, hexfn):
82 return b"%d" % entry[constants.ENTRY_RANK]
82 return b"%d" % entry[constants.ENTRY_RANK]
83
83
84
84
85 @debug_column(b"linkrev", size=6)
85 @debug_column(b"linkrev", size=6)
86 def _linkrev(index, rev, entry, hexfn):
86 def _linkrev(index, rev, entry, hexfn):
87 return b"%d" % entry[constants.ENTRY_LINK_REV]
87 return b"%d" % entry[constants.ENTRY_LINK_REV]
88
88
89
89
90 @debug_column(b"nodeid", size=NODE_SIZE)
90 @debug_column(b"nodeid", size=NODE_SIZE)
91 def _nodeid(index, rev, entry, hexfn):
91 def _nodeid(index, rev, entry, hexfn):
92 return hexfn(entry[constants.ENTRY_NODE_ID])
92 return hexfn(entry[constants.ENTRY_NODE_ID])
93
93
94
94
95 @debug_column(b"p1-rev", size=6, verbose=True)
95 @debug_column(b"p1-rev", size=6, verbose=True)
96 def _p1_rev(index, rev, entry, hexfn):
96 def _p1_rev(index, rev, entry, hexfn):
97 return b"%d" % entry[constants.ENTRY_PARENT_1]
97 return b"%d" % entry[constants.ENTRY_PARENT_1]
98
98
99
99
100 @debug_column(b"p1-nodeid", size=NODE_SIZE)
100 @debug_column(b"p1-nodeid", size=NODE_SIZE)
101 def _p1_node(index, rev, entry, hexfn):
101 def _p1_node(index, rev, entry, hexfn):
102 parent = entry[constants.ENTRY_PARENT_1]
102 parent = entry[constants.ENTRY_PARENT_1]
103 p_entry = index[parent]
103 p_entry = index[parent]
104 return hexfn(p_entry[constants.ENTRY_NODE_ID])
104 return hexfn(p_entry[constants.ENTRY_NODE_ID])
105
105
106
106
107 @debug_column(b"p2-rev", size=6, verbose=True)
107 @debug_column(b"p2-rev", size=6, verbose=True)
108 def _p2_rev(index, rev, entry, hexfn):
108 def _p2_rev(index, rev, entry, hexfn):
109 return b"%d" % entry[constants.ENTRY_PARENT_2]
109 return b"%d" % entry[constants.ENTRY_PARENT_2]
110
110
111
111
112 @debug_column(b"p2-nodeid", size=NODE_SIZE)
112 @debug_column(b"p2-nodeid", size=NODE_SIZE)
113 def _p2_node(index, rev, entry, hexfn):
113 def _p2_node(index, rev, entry, hexfn):
114 parent = entry[constants.ENTRY_PARENT_2]
114 parent = entry[constants.ENTRY_PARENT_2]
115 p_entry = index[parent]
115 p_entry = index[parent]
116 return hexfn(p_entry[constants.ENTRY_NODE_ID])
116 return hexfn(p_entry[constants.ENTRY_NODE_ID])
117
117
118
118
119 @debug_column(b"full-size", size=20, verbose=True)
119 @debug_column(b"full-size", size=20, verbose=True)
120 def full_size(index, rev, entry, hexfn):
120 def full_size(index, rev, entry, hexfn):
121 return b"%d" % entry[constants.ENTRY_DATA_UNCOMPRESSED_LENGTH]
121 return b"%d" % entry[constants.ENTRY_DATA_UNCOMPRESSED_LENGTH]
122
122
123
123
124 @debug_column(b"delta-base", size=6, verbose=True)
124 @debug_column(b"delta-base", size=6, verbose=True)
125 def delta_base(index, rev, entry, hexfn):
125 def delta_base(index, rev, entry, hexfn):
126 return b"%d" % entry[constants.ENTRY_DELTA_BASE]
126 return b"%d" % entry[constants.ENTRY_DELTA_BASE]
127
127
128
128
129 @debug_column(b"flags", size=2, verbose=True)
129 @debug_column(b"flags", size=2, verbose=True)
130 def flags(index, rev, entry, hexfn):
130 def flags(index, rev, entry, hexfn):
131 field = entry[constants.ENTRY_DATA_OFFSET]
131 field = entry[constants.ENTRY_DATA_OFFSET]
132 field &= 0xFFFF
132 field &= 0xFFFF
133 return b"%d" % field
133 return b"%d" % field
134
134
135
135
136 @debug_column(b"comp-mode", size=4, verbose=True)
136 @debug_column(b"comp-mode", size=4, verbose=True)
137 def compression_mode(index, rev, entry, hexfn):
137 def compression_mode(index, rev, entry, hexfn):
138 return b"%d" % entry[constants.ENTRY_DATA_COMPRESSION_MODE]
138 return b"%d" % entry[constants.ENTRY_DATA_COMPRESSION_MODE]
139
139
140
140
141 @debug_column(b"data-offset", size=20, verbose=True)
141 @debug_column(b"data-offset", size=20, verbose=True)
142 def data_offset(index, rev, entry, hexfn):
142 def data_offset(index, rev, entry, hexfn):
143 field = entry[constants.ENTRY_DATA_OFFSET]
143 field = entry[constants.ENTRY_DATA_OFFSET]
144 field >>= 16
144 field >>= 16
145 return b"%d" % field
145 return b"%d" % field
146
146
147
147
148 @debug_column(b"chunk-size", size=10, verbose=True)
148 @debug_column(b"chunk-size", size=10, verbose=True)
149 def data_chunk_size(index, rev, entry, hexfn):
149 def data_chunk_size(index, rev, entry, hexfn):
150 return b"%d" % entry[constants.ENTRY_DATA_COMPRESSED_LENGTH]
150 return b"%d" % entry[constants.ENTRY_DATA_COMPRESSED_LENGTH]
151
151
152
152
153 @debug_column(b"sd-comp-mode", size=7, verbose=True)
153 @debug_column(b"sd-comp-mode", size=7, verbose=True)
154 def sidedata_compression_mode(index, rev, entry, hexfn):
154 def sidedata_compression_mode(index, rev, entry, hexfn):
155 compression = entry[constants.ENTRY_SIDEDATA_COMPRESSION_MODE]
155 compression = entry[constants.ENTRY_SIDEDATA_COMPRESSION_MODE]
156 if compression == constants.COMP_MODE_PLAIN:
156 if compression == constants.COMP_MODE_PLAIN:
157 return b"plain"
157 return b"plain"
158 elif compression == constants.COMP_MODE_DEFAULT:
158 elif compression == constants.COMP_MODE_DEFAULT:
159 return b"default"
159 return b"default"
160 elif compression == constants.COMP_MODE_INLINE:
160 elif compression == constants.COMP_MODE_INLINE:
161 return b"inline"
161 return b"inline"
162 else:
162 else:
163 return b"%d" % compression
163 return b"%d" % compression
164
164
165
165
166 @debug_column(b"sidedata-offset", size=20, verbose=True)
166 @debug_column(b"sidedata-offset", size=20, verbose=True)
167 def sidedata_offset(index, rev, entry, hexfn):
167 def sidedata_offset(index, rev, entry, hexfn):
168 return b"%d" % entry[constants.ENTRY_SIDEDATA_OFFSET]
168 return b"%d" % entry[constants.ENTRY_SIDEDATA_OFFSET]
169
169
170
170
171 @debug_column(b"sd-chunk-size", size=10, verbose=True)
171 @debug_column(b"sd-chunk-size", size=10, verbose=True)
172 def sidedata_chunk_size(index, rev, entry, hexfn):
172 def sidedata_chunk_size(index, rev, entry, hexfn):
173 return b"%d" % entry[constants.ENTRY_SIDEDATA_COMPRESSED_LENGTH]
173 return b"%d" % entry[constants.ENTRY_SIDEDATA_COMPRESSED_LENGTH]
174
174
175
175
176 def debug_index(
176 def debug_index(
177 ui,
177 ui,
178 repo,
178 repo,
179 formatter,
179 formatter,
180 revlog,
180 revlog,
181 full_node,
181 full_node,
182 ):
182 ):
183 """display index data for a revlog"""
183 """display index data for a revlog"""
184 if full_node:
184 if full_node:
185 hexfn = nodemod.hex
185 hexfn = nodemod.hex
186 else:
186 else:
187 hexfn = nodemod.short
187 hexfn = nodemod.short
188
188
189 idlen = 12
189 idlen = 12
190 for i in revlog:
190 for i in revlog:
191 idlen = len(hexfn(revlog.node(i)))
191 idlen = len(hexfn(revlog.node(i)))
192 break
192 break
193
193
194 fm = formatter
194 fm = formatter
195
195
196 header_pieces = []
196 header_pieces = []
197 for column in INDEX_ENTRY_DEBUG_COLUMN:
197 for column in INDEX_ENTRY_DEBUG_COLUMN:
198 if column.verbose_only and not ui.verbose:
198 if column.verbose_only and not ui.verbose:
199 continue
199 continue
200 size = column.get_size(idlen)
200 size = column.get_size(idlen)
201 name = column.name
201 name = column.name
202 header_pieces.append(name.rjust(size))
202 header_pieces.append(name.rjust(size))
203
203
204 fm.plain(b' '.join(header_pieces) + b'\n')
204 fm.plain(b' '.join(header_pieces) + b'\n')
205
205
206 index = revlog.index
206 index = revlog.index
207
207
208 for rev in revlog:
208 for rev in revlog:
209 fm.startitem()
209 fm.startitem()
210 entry = index[rev]
210 entry = index[rev]
211 first = True
211 first = True
212 for column in INDEX_ENTRY_DEBUG_COLUMN:
212 for column in INDEX_ENTRY_DEBUG_COLUMN:
213 if column.verbose_only and not ui.verbose:
213 if column.verbose_only and not ui.verbose:
214 continue
214 continue
215 if not first:
215 if not first:
216 fm.plain(b' ')
216 fm.plain(b' ')
217 first = False
217 first = False
218
218
219 size = column.get_size(idlen)
219 size = column.get_size(idlen)
220 value = column.value_func(index, rev, entry, hexfn)
220 value = column.value_func(index, rev, entry, hexfn)
221 display = b"%%%ds" % size
221 display = b"%%%ds" % size
222 fm.write(column.name, display, value)
222 fm.write(column.name, display, value)
223 fm.plain(b'\n')
223 fm.plain(b'\n')
224
224
225 fm.end()
225 fm.end()
226
226
227
227
228 def dump(ui, revlog):
228 def dump(ui, revlog):
229 """perform the work for `hg debugrevlog --dump"""
229 """perform the work for `hg debugrevlog --dump"""
230 # XXX seems redundant with debug index ?
230 # XXX seems redundant with debug index ?
231 r = revlog
231 r = revlog
232 numrevs = len(r)
232 numrevs = len(r)
233 ui.write(
233 ui.write(
234 (
234 (
235 b"# rev p1rev p2rev start end deltastart base p1 p2"
235 b"# rev p1rev p2rev start end deltastart base p1 p2"
236 b" rawsize totalsize compression heads chainlen\n"
236 b" rawsize totalsize compression heads chainlen\n"
237 )
237 )
238 )
238 )
239 ts = 0
239 ts = 0
240 heads = set()
240 heads = set()
241
241
242 for rev in range(numrevs):
242 for rev in range(numrevs):
243 dbase = r.deltaparent(rev)
243 dbase = r.deltaparent(rev)
244 if dbase == -1:
244 if dbase == -1:
245 dbase = rev
245 dbase = rev
246 cbase = r.chainbase(rev)
246 cbase = r.chainbase(rev)
247 clen = r.chainlen(rev)
247 clen = r.chainlen(rev)
248 p1, p2 = r.parentrevs(rev)
248 p1, p2 = r.parentrevs(rev)
249 rs = r.rawsize(rev)
249 rs = r.rawsize(rev)
250 ts = ts + rs
250 ts = ts + rs
251 heads -= set(r.parentrevs(rev))
251 heads -= set(r.parentrevs(rev))
252 heads.add(rev)
252 heads.add(rev)
253 try:
253 try:
254 compression = ts / r.end(rev)
254 compression = ts / r.end(rev)
255 except ZeroDivisionError:
255 except ZeroDivisionError:
256 compression = 0
256 compression = 0
257 ui.write(
257 ui.write(
258 b"%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
258 b"%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
259 b"%11d %5d %8d\n"
259 b"%11d %5d %8d\n"
260 % (
260 % (
261 rev,
261 rev,
262 p1,
262 p1,
263 p2,
263 p2,
264 r.start(rev),
264 r.start(rev),
265 r.end(rev),
265 r.end(rev),
266 r.start(dbase),
266 r.start(dbase),
267 r.start(cbase),
267 r.start(cbase),
268 r.start(p1),
268 r.start(p1),
269 r.start(p2),
269 r.start(p2),
270 rs,
270 rs,
271 ts,
271 ts,
272 compression,
272 compression,
273 len(heads),
273 len(heads),
274 clen,
274 clen,
275 )
275 )
276 )
276 )
277
277
278
278
279 def debug_revlog(ui, revlog):
279 def debug_revlog(ui, revlog):
280 """code for `hg debugrevlog`"""
280 """code for `hg debugrevlog`"""
281 r = revlog
281 r = revlog
282 format = r._format_version
282 format = r._format_version
283 v = r._format_flags
283 v = r._format_flags
284 flags = []
284 flags = []
285 gdelta = False
285 gdelta = False
286 if v & constants.FLAG_INLINE_DATA:
286 if v & constants.FLAG_INLINE_DATA:
287 flags.append(b'inline')
287 flags.append(b'inline')
288 if v & constants.FLAG_GENERALDELTA:
288 if v & constants.FLAG_GENERALDELTA:
289 gdelta = True
289 gdelta = True
290 flags.append(b'generaldelta')
290 flags.append(b'generaldelta')
291 if not flags:
291 if not flags:
292 flags = [b'(none)']
292 flags = [b'(none)']
293
293
294 ### the total size of stored content if incompressed.
294 ### the total size of stored content if incompressed.
295 full_text_total_size = 0
295 full_text_total_size = 0
296 ### tracks merge vs single parent
296 ### tracks merge vs single parent
297 nummerges = 0
297 nummerges = 0
298
298
299 ### tracks ways the "delta" are build
299 ### tracks ways the "delta" are build
300 # nodelta
300 # nodelta
301 numempty = 0
301 numempty = 0
302 numemptytext = 0
302 numemptytext = 0
303 numemptydelta = 0
303 numemptydelta = 0
304 # full file content
304 # full file content
305 numfull = 0
305 numfull = 0
306 # intermediate snapshot against a prior snapshot
306 # intermediate snapshot against a prior snapshot
307 numsemi = 0
307 numsemi = 0
308 # snapshot count per depth
308 # snapshot count per depth
309 numsnapdepth = collections.defaultdict(lambda: 0)
309 numsnapdepth = collections.defaultdict(lambda: 0)
310 # number of snapshots with a non-ancestor delta
310 # number of snapshots with a non-ancestor delta
311 numsnapdepth_nad = collections.defaultdict(lambda: 0)
311 numsnapdepth_nad = collections.defaultdict(lambda: 0)
312 # delta against previous revision
312 # delta against previous revision
313 numprev = 0
313 numprev = 0
314 # delta against prev, where prev is a non-ancestor
314 # delta against prev, where prev is a non-ancestor
315 numprev_nad = 0
315 numprev_nad = 0
316 # delta against first or second parent (not prev)
316 # delta against first or second parent (not prev)
317 nump1 = 0
317 nump1 = 0
318 nump2 = 0
318 nump2 = 0
319 # delta against neither prev nor parents
319 # delta against neither prev nor parents
320 numother = 0
320 numother = 0
321 # delta against other that is a non-ancestor
321 # delta against other that is a non-ancestor
322 numother_nad = 0
322 numother_nad = 0
323 # delta against prev that are also first or second parent
323 # delta against prev that are also first or second parent
324 # (details of `numprev`)
324 # (details of `numprev`)
325 nump1prev = 0
325 nump1prev = 0
326 nump2prev = 0
326 nump2prev = 0
327
327
328 # data about delta chain of each revs
328 # data about delta chain of each revs
329 chainlengths = []
329 chainlengths = []
330 chainbases = []
330 chainbases = []
331 chainspans = []
331 chainspans = []
332
332
333 # data about each revision
333 # data about each revision
334 datasize = [None, 0, 0]
334 datasize = [None, 0, 0]
335 fullsize = [None, 0, 0]
335 fullsize = [None, 0, 0]
336 semisize = [None, 0, 0]
336 semisize = [None, 0, 0]
337 # snapshot count per depth
337 # snapshot count per depth
338 snapsizedepth = collections.defaultdict(lambda: [None, 0, 0])
338 snapsizedepth = collections.defaultdict(lambda: [None, 0, 0])
339 deltasize = [None, 0, 0]
339 deltasize = [None, 0, 0]
340 chunktypecounts = {}
340 chunktypecounts = {}
341 chunktypesizes = {}
341 chunktypesizes = {}
342
342
343 def addsize(size, l):
343 def addsize(size, l):
344 if l[0] is None or size < l[0]:
344 if l[0] is None or size < l[0]:
345 l[0] = size
345 l[0] = size
346 if size > l[1]:
346 if size > l[1]:
347 l[1] = size
347 l[1] = size
348 l[2] += size
348 l[2] += size
349
349
350 numrevs = len(r)
350 numrevs = len(r)
351 for rev in range(numrevs):
351 for rev in range(numrevs):
352 p1, p2 = r.parentrevs(rev)
352 p1, p2 = r.parentrevs(rev)
353 delta = r.deltaparent(rev)
353 delta = r.deltaparent(rev)
354 if format > 0:
354 if format > 0:
355 s = r.rawsize(rev)
355 s = r.rawsize(rev)
356 full_text_total_size += s
356 full_text_total_size += s
357 addsize(s, datasize)
357 addsize(s, datasize)
358 if p2 != nodemod.nullrev:
358 if p2 != nodemod.nullrev:
359 nummerges += 1
359 nummerges += 1
360 size = r.length(rev)
360 size = r.length(rev)
361 if delta == nodemod.nullrev:
361 if delta == nodemod.nullrev:
362 chainlengths.append(0)
362 chainlengths.append(0)
363 chainbases.append(r.start(rev))
363 chainbases.append(r.start(rev))
364 chainspans.append(size)
364 chainspans.append(size)
365 if size == 0:
365 if size == 0:
366 numempty += 1
366 numempty += 1
367 numemptytext += 1
367 numemptytext += 1
368 else:
368 else:
369 numfull += 1
369 numfull += 1
370 numsnapdepth[0] += 1
370 numsnapdepth[0] += 1
371 addsize(size, fullsize)
371 addsize(size, fullsize)
372 addsize(size, snapsizedepth[0])
372 addsize(size, snapsizedepth[0])
373 else:
373 else:
374 nad = (
374 nad = (
375 delta != p1 and delta != p2 and not r.isancestorrev(delta, rev)
375 delta != p1 and delta != p2 and not r.isancestorrev(delta, rev)
376 )
376 )
377 chainlengths.append(chainlengths[delta] + 1)
377 chainlengths.append(chainlengths[delta] + 1)
378 baseaddr = chainbases[delta]
378 baseaddr = chainbases[delta]
379 revaddr = r.start(rev)
379 revaddr = r.start(rev)
380 chainbases.append(baseaddr)
380 chainbases.append(baseaddr)
381 chainspans.append((revaddr - baseaddr) + size)
381 chainspans.append((revaddr - baseaddr) + size)
382 if size == 0:
382 if size == 0:
383 numempty += 1
383 numempty += 1
384 numemptydelta += 1
384 numemptydelta += 1
385 elif r.issnapshot(rev):
385 elif r.issnapshot(rev):
386 addsize(size, semisize)
386 addsize(size, semisize)
387 numsemi += 1
387 numsemi += 1
388 depth = r.snapshotdepth(rev)
388 depth = r.snapshotdepth(rev)
389 numsnapdepth[depth] += 1
389 numsnapdepth[depth] += 1
390 if nad:
390 if nad:
391 numsnapdepth_nad[depth] += 1
391 numsnapdepth_nad[depth] += 1
392 addsize(size, snapsizedepth[depth])
392 addsize(size, snapsizedepth[depth])
393 else:
393 else:
394 addsize(size, deltasize)
394 addsize(size, deltasize)
395 if delta == rev - 1:
395 if delta == rev - 1:
396 numprev += 1
396 numprev += 1
397 if delta == p1:
397 if delta == p1:
398 nump1prev += 1
398 nump1prev += 1
399 elif delta == p2:
399 elif delta == p2:
400 nump2prev += 1
400 nump2prev += 1
401 elif nad:
401 elif nad:
402 numprev_nad += 1
402 numprev_nad += 1
403 elif delta == p1:
403 elif delta == p1:
404 nump1 += 1
404 nump1 += 1
405 elif delta == p2:
405 elif delta == p2:
406 nump2 += 1
406 nump2 += 1
407 elif delta != nodemod.nullrev:
407 elif delta != nodemod.nullrev:
408 numother += 1
408 numother += 1
409 numother_nad += 1
409 numother_nad += 1
410
410
411 # Obtain data on the raw chunks in the revlog.
411 # Obtain data on the raw chunks in the revlog.
412 if util.safehasattr(r, '_getsegmentforrevs'):
412 if util.safehasattr(r, '_getsegmentforrevs'):
413 segment = r._getsegmentforrevs(rev, rev)[1]
413 segment = r._getsegmentforrevs(rev, rev)[1]
414 else:
414 else:
415 segment = r._revlog._getsegmentforrevs(rev, rev)[1]
415 segment = r._revlog._getsegmentforrevs(rev, rev)[1]
416 if segment:
416 if segment:
417 chunktype = bytes(segment[0:1])
417 chunktype = bytes(segment[0:1])
418 else:
418 else:
419 chunktype = b'empty'
419 chunktype = b'empty'
420
420
421 if chunktype not in chunktypecounts:
421 if chunktype not in chunktypecounts:
422 chunktypecounts[chunktype] = 0
422 chunktypecounts[chunktype] = 0
423 chunktypesizes[chunktype] = 0
423 chunktypesizes[chunktype] = 0
424
424
425 chunktypecounts[chunktype] += 1
425 chunktypecounts[chunktype] += 1
426 chunktypesizes[chunktype] += size
426 chunktypesizes[chunktype] += size
427
427
428 # Adjust size min value for empty cases
428 # Adjust size min value for empty cases
429 for size in (datasize, fullsize, semisize, deltasize):
429 for size in (datasize, fullsize, semisize, deltasize):
430 if size[0] is None:
430 if size[0] is None:
431 size[0] = 0
431 size[0] = 0
432
432
433 numdeltas = numrevs - numfull - numempty - numsemi
433 numdeltas = numrevs - numfull - numempty - numsemi
434 numoprev = numprev - nump1prev - nump2prev - numprev_nad
434 numoprev = numprev - nump1prev - nump2prev - numprev_nad
435 num_other_ancestors = numother - numother_nad
435 num_other_ancestors = numother - numother_nad
436 totalrawsize = datasize[2]
436 totalrawsize = datasize[2]
437 datasize[2] /= numrevs
437 datasize[2] /= numrevs
438 fulltotal = fullsize[2]
438 fulltotal = fullsize[2]
439 if numfull == 0:
439 if numfull == 0:
440 fullsize[2] = 0
440 fullsize[2] = 0
441 else:
441 else:
442 fullsize[2] /= numfull
442 fullsize[2] /= numfull
443 semitotal = semisize[2]
443 semitotal = semisize[2]
444 snaptotal = {}
444 snaptotal = {}
445 if numsemi > 0:
445 if numsemi > 0:
446 semisize[2] /= numsemi
446 semisize[2] /= numsemi
447 for depth in snapsizedepth:
447 for depth in snapsizedepth:
448 snaptotal[depth] = snapsizedepth[depth][2]
448 snaptotal[depth] = snapsizedepth[depth][2]
449 snapsizedepth[depth][2] /= numsnapdepth[depth]
449 snapsizedepth[depth][2] /= numsnapdepth[depth]
450
450
451 deltatotal = deltasize[2]
451 deltatotal = deltasize[2]
452 if numdeltas > 0:
452 if numdeltas > 0:
453 deltasize[2] /= numdeltas
453 deltasize[2] /= numdeltas
454 totalsize = fulltotal + semitotal + deltatotal
454 totalsize = fulltotal + semitotal + deltatotal
455 avgchainlen = sum(chainlengths) / numrevs
455 avgchainlen = sum(chainlengths) / numrevs
456 maxchainlen = max(chainlengths)
456 maxchainlen = max(chainlengths)
457 maxchainspan = max(chainspans)
457 maxchainspan = max(chainspans)
458 compratio = 1
458 compratio = 1
459 if totalsize:
459 if totalsize:
460 compratio = totalrawsize / totalsize
460 compratio = totalrawsize / totalsize
461
461
462 basedfmtstr = b'%%%dd\n'
462 basedfmtstr = b'%%%dd\n'
463 basepcfmtstr = b'%%%dd %s(%%5.2f%%%%)\n'
463 basepcfmtstr = b'%%%dd %s(%%5.2f%%%%)\n'
464
464
465 def dfmtstr(max):
465 def dfmtstr(max):
466 return basedfmtstr % len(str(max))
466 return basedfmtstr % len(str(max))
467
467
468 def pcfmtstr(max, padding=0):
468 def pcfmtstr(max, padding=0):
469 return basepcfmtstr % (len(str(max)), b' ' * padding)
469 return basepcfmtstr % (len(str(max)), b' ' * padding)
470
470
471 def pcfmt(value, total):
471 def pcfmt(value, total):
472 if total:
472 if total:
473 return (value, 100 * float(value) / total)
473 return (value, 100 * float(value) / total)
474 else:
474 else:
475 return value, 100.0
475 return value, 100.0
476
476
477 ui.writenoi18n(b'format : %d\n' % format)
477 ui.writenoi18n(b'format : %d\n' % format)
478 ui.writenoi18n(b'flags : %s\n' % b', '.join(flags))
478 ui.writenoi18n(b'flags : %s\n' % b', '.join(flags))
479
479
480 ui.write(b'\n')
480 ui.write(b'\n')
481 fmt = pcfmtstr(totalsize)
481 fmt = pcfmtstr(totalsize)
482 fmt2 = dfmtstr(totalsize)
482 fmt2 = dfmtstr(totalsize)
483 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
483 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
484 ui.writenoi18n(b' merges : ' + fmt % pcfmt(nummerges, numrevs))
484 ui.writenoi18n(b' merges : ' + fmt % pcfmt(nummerges, numrevs))
485 ui.writenoi18n(
485 ui.writenoi18n(
486 b' normal : ' + fmt % pcfmt(numrevs - nummerges, numrevs)
486 b' normal : ' + fmt % pcfmt(numrevs - nummerges, numrevs)
487 )
487 )
488 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
488 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
489 ui.writenoi18n(b' empty : ' + fmt % pcfmt(numempty, numrevs))
489 ui.writenoi18n(b' empty : ' + fmt % pcfmt(numempty, numrevs))
490 ui.writenoi18n(
490 ui.writenoi18n(
491 b' text : '
491 b' text : '
492 + fmt % pcfmt(numemptytext, numemptytext + numemptydelta)
492 + fmt % pcfmt(numemptytext, numemptytext + numemptydelta)
493 )
493 )
494 ui.writenoi18n(
494 ui.writenoi18n(
495 b' delta : '
495 b' delta : '
496 + fmt % pcfmt(numemptydelta, numemptytext + numemptydelta)
496 + fmt % pcfmt(numemptydelta, numemptytext + numemptydelta)
497 )
497 )
498 ui.writenoi18n(
498 ui.writenoi18n(
499 b' snapshot : ' + fmt % pcfmt(numfull + numsemi, numrevs)
499 b' snapshot : ' + fmt % pcfmt(numfull + numsemi, numrevs)
500 )
500 )
501 for depth in sorted(numsnapdepth):
501 for depth in sorted(numsnapdepth):
502 base = b' lvl-%-3d : ' % depth
502 base = b' lvl-%-3d : ' % depth
503 count = fmt % pcfmt(numsnapdepth[depth], numrevs)
503 count = fmt % pcfmt(numsnapdepth[depth], numrevs)
504 pieces = [base, count]
504 pieces = [base, count]
505 if numsnapdepth_nad[depth]:
505 if numsnapdepth_nad[depth]:
506 pieces[-1] = count = count[:-1] # drop the final '\n'
506 pieces[-1] = count = count[:-1] # drop the final '\n'
507 more = b' non-ancestor-bases: '
507 more = b' non-ancestor-bases: '
508 anc_count = fmt
508 anc_count = fmt
509 anc_count %= pcfmt(numsnapdepth_nad[depth], numsnapdepth[depth])
509 anc_count %= pcfmt(numsnapdepth_nad[depth], numsnapdepth[depth])
510 pieces.append(more)
510 pieces.append(more)
511 pieces.append(anc_count)
511 pieces.append(anc_count)
512 ui.write(b''.join(pieces))
512 ui.write(b''.join(pieces))
513 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(numdeltas, numrevs))
513 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(numdeltas, numrevs))
514 ui.writenoi18n(b'revision size : ' + fmt2 % totalsize)
514 ui.writenoi18n(b'revision size : ' + fmt2 % totalsize)
515 ui.writenoi18n(
515 ui.writenoi18n(
516 b' snapshot : ' + fmt % pcfmt(fulltotal + semitotal, totalsize)
516 b' snapshot : ' + fmt % pcfmt(fulltotal + semitotal, totalsize)
517 )
517 )
518 for depth in sorted(numsnapdepth):
518 for depth in sorted(numsnapdepth):
519 ui.write(
519 ui.write(
520 (b' lvl-%-3d : ' % depth)
520 (b' lvl-%-3d : ' % depth)
521 + fmt % pcfmt(snaptotal[depth], totalsize)
521 + fmt % pcfmt(snaptotal[depth], totalsize)
522 )
522 )
523 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(deltatotal, totalsize))
523 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(deltatotal, totalsize))
524
524
525 letters = string.ascii_letters.encode('ascii')
525 letters = string.ascii_letters.encode('ascii')
526
526
527 def fmtchunktype(chunktype):
527 def fmtchunktype(chunktype):
528 if chunktype == b'empty':
528 if chunktype == b'empty':
529 return b' %s : ' % chunktype
529 return b' %s : ' % chunktype
530 elif chunktype in letters:
530 elif chunktype in letters:
531 return b' 0x%s (%s) : ' % (nodemod.hex(chunktype), chunktype)
531 return b' 0x%s (%s) : ' % (nodemod.hex(chunktype), chunktype)
532 else:
532 else:
533 return b' 0x%s : ' % nodemod.hex(chunktype)
533 return b' 0x%s : ' % nodemod.hex(chunktype)
534
534
535 ui.write(b'\n')
535 ui.write(b'\n')
536 ui.writenoi18n(b'chunks : ' + fmt2 % numrevs)
536 ui.writenoi18n(b'chunks : ' + fmt2 % numrevs)
537 for chunktype in sorted(chunktypecounts):
537 for chunktype in sorted(chunktypecounts):
538 ui.write(fmtchunktype(chunktype))
538 ui.write(fmtchunktype(chunktype))
539 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
539 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
540 ui.writenoi18n(b'chunks size : ' + fmt2 % totalsize)
540 ui.writenoi18n(b'chunks size : ' + fmt2 % totalsize)
541 for chunktype in sorted(chunktypecounts):
541 for chunktype in sorted(chunktypecounts):
542 ui.write(fmtchunktype(chunktype))
542 ui.write(fmtchunktype(chunktype))
543 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
543 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
544
544
545 ui.write(b'\n')
545 ui.write(b'\n')
546 b_total = b"%d" % full_text_total_size
546 b_total = b"%d" % full_text_total_size
547 p_total = []
547 p_total = []
548 while len(b_total) > 3:
548 while len(b_total) > 3:
549 p_total.append(b_total[-3:])
549 p_total.append(b_total[-3:])
550 b_total = b_total[:-3]
550 b_total = b_total[:-3]
551 p_total.append(b_total)
551 p_total.append(b_total)
552 p_total.reverse()
552 p_total.reverse()
553 b_total = b' '.join(p_total)
553 b_total = b' '.join(p_total)
554
554
555 ui.write(b'\n')
555 ui.write(b'\n')
556 ui.writenoi18n(b'total-stored-content: %s bytes\n' % b_total)
556 ui.writenoi18n(b'total-stored-content: %s bytes\n' % b_total)
557 ui.write(b'\n')
557 ui.write(b'\n')
558 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
558 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
559 ui.writenoi18n(b'avg chain length : ' + fmt % avgchainlen)
559 ui.writenoi18n(b'avg chain length : ' + fmt % avgchainlen)
560 ui.writenoi18n(b'max chain length : ' + fmt % maxchainlen)
560 ui.writenoi18n(b'max chain length : ' + fmt % maxchainlen)
561 ui.writenoi18n(b'max chain reach : ' + fmt % maxchainspan)
561 ui.writenoi18n(b'max chain reach : ' + fmt % maxchainspan)
562 ui.writenoi18n(b'compression ratio : ' + fmt % compratio)
562 ui.writenoi18n(b'compression ratio : ' + fmt % compratio)
563
563
564 if format > 0:
564 if format > 0:
565 ui.write(b'\n')
565 ui.write(b'\n')
566 ui.writenoi18n(
566 ui.writenoi18n(
567 b'uncompressed data size (min/max/avg) : %d / %d / %d\n'
567 b'uncompressed data size (min/max/avg) : %d / %d / %d\n'
568 % tuple(datasize)
568 % tuple(datasize)
569 )
569 )
570 ui.writenoi18n(
570 ui.writenoi18n(
571 b'full revision size (min/max/avg) : %d / %d / %d\n'
571 b'full revision size (min/max/avg) : %d / %d / %d\n'
572 % tuple(fullsize)
572 % tuple(fullsize)
573 )
573 )
574 ui.writenoi18n(
574 ui.writenoi18n(
575 b'inter-snapshot size (min/max/avg) : %d / %d / %d\n'
575 b'inter-snapshot size (min/max/avg) : %d / %d / %d\n'
576 % tuple(semisize)
576 % tuple(semisize)
577 )
577 )
578 for depth in sorted(snapsizedepth):
578 for depth in sorted(snapsizedepth):
579 if depth == 0:
579 if depth == 0:
580 continue
580 continue
581 ui.writenoi18n(
581 ui.writenoi18n(
582 b' level-%-3d (min/max/avg) : %d / %d / %d\n'
582 b' level-%-3d (min/max/avg) : %d / %d / %d\n'
583 % ((depth,) + tuple(snapsizedepth[depth]))
583 % ((depth,) + tuple(snapsizedepth[depth]))
584 )
584 )
585 ui.writenoi18n(
585 ui.writenoi18n(
586 b'delta size (min/max/avg) : %d / %d / %d\n'
586 b'delta size (min/max/avg) : %d / %d / %d\n'
587 % tuple(deltasize)
587 % tuple(deltasize)
588 )
588 )
589
589
590 if numdeltas > 0:
590 if numdeltas > 0:
591 ui.write(b'\n')
591 ui.write(b'\n')
592 fmt = pcfmtstr(numdeltas)
592 fmt = pcfmtstr(numdeltas)
593 fmt2 = pcfmtstr(numdeltas, 4)
593 fmt2 = pcfmtstr(numdeltas, 4)
594 ui.writenoi18n(
594 ui.writenoi18n(
595 b'deltas against prev : ' + fmt % pcfmt(numprev, numdeltas)
595 b'deltas against prev : ' + fmt % pcfmt(numprev, numdeltas)
596 )
596 )
597 if numprev > 0:
597 if numprev > 0:
598 ui.writenoi18n(
598 ui.writenoi18n(
599 b' where prev = p1 : ' + fmt2 % pcfmt(nump1prev, numprev)
599 b' where prev = p1 : ' + fmt2 % pcfmt(nump1prev, numprev)
600 )
600 )
601 ui.writenoi18n(
601 ui.writenoi18n(
602 b' where prev = p2 : ' + fmt2 % pcfmt(nump2prev, numprev)
602 b' where prev = p2 : ' + fmt2 % pcfmt(nump2prev, numprev)
603 )
603 )
604 ui.writenoi18n(
604 ui.writenoi18n(
605 b' other-ancestor : ' + fmt2 % pcfmt(numoprev, numprev)
605 b' other-ancestor : ' + fmt2 % pcfmt(numoprev, numprev)
606 )
606 )
607 ui.writenoi18n(
607 ui.writenoi18n(
608 b' unrelated : ' + fmt2 % pcfmt(numoprev, numprev)
608 b' unrelated : ' + fmt2 % pcfmt(numoprev, numprev)
609 )
609 )
610 if gdelta:
610 if gdelta:
611 ui.writenoi18n(
611 ui.writenoi18n(
612 b'deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas)
612 b'deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas)
613 )
613 )
614 ui.writenoi18n(
614 ui.writenoi18n(
615 b'deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas)
615 b'deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas)
616 )
616 )
617 ui.writenoi18n(
617 ui.writenoi18n(
618 b'deltas against ancs : '
618 b'deltas against ancs : '
619 + fmt % pcfmt(num_other_ancestors, numdeltas)
619 + fmt % pcfmt(num_other_ancestors, numdeltas)
620 )
620 )
621 ui.writenoi18n(
621 ui.writenoi18n(
622 b'deltas against other : '
622 b'deltas against other : '
623 + fmt % pcfmt(numother_nad, numdeltas)
623 + fmt % pcfmt(numother_nad, numdeltas)
624 )
624 )
625
625
626
626
627 def debug_delta_find(ui, revlog, rev, base_rev=nodemod.nullrev):
627 def debug_delta_find(ui, revlog, rev, base_rev=nodemod.nullrev):
628 """display the search process for a delta"""
628 """display the search process for a delta"""
629 deltacomputer = deltautil.deltacomputer(
629 deltacomputer = deltautil.deltacomputer(
630 revlog,
630 revlog,
631 write_debug=ui.write,
631 write_debug=ui.write,
632 debug_search=not ui.quiet,
632 debug_search=not ui.quiet,
633 )
633 )
634
634
635 node = revlog.node(rev)
635 node = revlog.node(rev)
636 p1r, p2r = revlog.parentrevs(rev)
636 p1r, p2r = revlog.parentrevs(rev)
637 p1 = revlog.node(p1r)
637 p1 = revlog.node(p1r)
638 p2 = revlog.node(p2r)
638 p2 = revlog.node(p2r)
639 full_text = revlog.revision(rev)
639 full_text = revlog.revision(rev)
640 btext = [full_text]
640 btext = [full_text]
641 textlen = len(btext[0])
641 textlen = len(btext[0])
642 cachedelta = None
642 cachedelta = None
643 flags = revlog.flags(rev)
643 flags = revlog.flags(rev)
644
644
645 if base_rev != nodemod.nullrev:
645 if base_rev != nodemod.nullrev:
646 base_text = revlog.revision(base_rev)
646 base_text = revlog.revision(base_rev)
647 delta = mdiff.textdiff(base_text, full_text)
647 delta = mdiff.textdiff(base_text, full_text)
648
648
649 cachedelta = (base_rev, delta, constants.DELTA_BASE_REUSE_TRY)
649 cachedelta = (base_rev, delta, constants.DELTA_BASE_REUSE_TRY)
650 btext = [None]
650 btext = [None]
651
651
652 revinfo = revlogutils.revisioninfo(
652 revinfo = revlogutils.revisioninfo(
653 node,
653 node,
654 p1,
654 p1,
655 p2,
655 p2,
656 btext,
656 btext,
657 textlen,
657 textlen,
658 cachedelta,
658 cachedelta,
659 flags,
659 flags,
660 )
660 )
661
661
662 fh = revlog._datafp()
662 fh = revlog._datafp()
663 deltacomputer.finddeltainfo(revinfo, fh, target_rev=rev)
663 deltacomputer.finddeltainfo(revinfo, fh, target_rev=rev)
664
664
665
665
666 def _get_revlogs(repo, changelog: bool, manifest: bool, filelogs: bool):
667 """yield revlogs from this repository"""
668 if changelog:
669 yield repo.changelog
670
671 if manifest:
672 # XXX: Handle tree manifest
673 root_mf = repo.manifestlog.getstorage(b'')
674 assert not root_mf._treeondisk
675 yield root_mf._revlog
676
677 if filelogs:
678 files = set()
679 for rev in repo:
680 ctx = repo[rev]
681 files |= set(ctx.files())
682
683 for f in sorted(files):
684 yield repo.file(f)._revlog
685
686
687 def debug_revlog_stats(
666 def debug_revlog_stats(
688 repo, fm, changelog: bool, manifest: bool, filelogs: bool
667 repo, fm, changelog: bool, manifest: bool, filelogs: bool
689 ):
668 ):
690 """Format revlog statistics for debugging purposes
669 """Format revlog statistics for debugging purposes
691
670
692 fm: the output formatter.
671 fm: the output formatter.
693 """
672 """
694 fm.plain(b'rev-count data-size inl type target \n')
673 fm.plain(b'rev-count data-size inl type target \n')
695
674
696 for rlog in _get_revlogs(repo, changelog, manifest, filelogs):
675 revlog_entries = [e for e in repo.store.walk() if e.is_revlog]
676 revlog_entries.sort(key=lambda e: (e.revlog_type, e.target_id))
677
678 for entry in revlog_entries:
679 if not changelog and entry.is_changelog:
680 continue
681 elif not manifest and entry.is_manifestlog:
682 continue
683 elif not filelogs and entry.is_filelog:
684 continue
685 rlog = entry.get_revlog_instance(repo).get_revlog()
697 fm.startitem()
686 fm.startitem()
698 nb_rev = len(rlog)
687 nb_rev = len(rlog)
699 inline = rlog._inline
688 inline = rlog._inline
700 data_size = rlog._get_data_offset(nb_rev - 1)
689 data_size = rlog._get_data_offset(nb_rev - 1)
701
690
702 target = rlog.target
691 target = rlog.target
703 revlog_type = b'unknown'
692 revlog_type = b'unknown'
704 revlog_target = b''
693 revlog_target = b''
705 if target[0] == constants.KIND_CHANGELOG:
694 if target[0] == constants.KIND_CHANGELOG:
706 revlog_type = b'changelog'
695 revlog_type = b'changelog'
707 elif target[0] == constants.KIND_MANIFESTLOG:
696 elif target[0] == constants.KIND_MANIFESTLOG:
708 revlog_type = b'manifest'
697 revlog_type = b'manifest'
709 revlog_target = target[1]
698 revlog_target = target[1]
710 elif target[0] == constants.KIND_FILELOG:
699 elif target[0] == constants.KIND_FILELOG:
711 revlog_type = b'file'
700 revlog_type = b'file'
712 revlog_target = target[1]
701 revlog_target = target[1]
713
702
714 fm.write(b'revlog.rev-count', b'%9d', nb_rev)
703 fm.write(b'revlog.rev-count', b'%9d', nb_rev)
715 fm.write(b'revlog.data-size', b'%12d', data_size)
704 fm.write(b'revlog.data-size', b'%12d', data_size)
716
705
717 fm.write(b'revlog.inline', b' %-3s', b'yes' if inline else b'no')
706 fm.write(b'revlog.inline', b' %-3s', b'yes' if inline else b'no')
718 fm.write(b'revlog.type', b' %-9s', revlog_type)
707 fm.write(b'revlog.type', b' %-9s', revlog_type)
719 fm.write(b'revlog.target', b' %s', revlog_target)
708 fm.write(b'revlog.target', b' %s', revlog_target)
720
709
721 fm.plain(b'\n')
710 fm.plain(b'\n')
@@ -1,77 +1,75 b''
1 Force revlog max inline value to be smaller than default
1 Force revlog max inline value to be smaller than default
2
2
3 $ mkdir $TESTTMP/ext
3 $ mkdir $TESTTMP/ext
4 $ cat << EOF > $TESTTMP/ext/small_inline.py
4 $ cat << EOF > $TESTTMP/ext/small_inline.py
5 > from mercurial import revlog
5 > from mercurial import revlog
6 > revlog._maxinline = 8
6 > revlog._maxinline = 8
7 > EOF
7 > EOF
8
8
9 $ cat << EOF >> $HGRCPATH
9 $ cat << EOF >> $HGRCPATH
10 > [extensions]
10 > [extensions]
11 > small_inline=$TESTTMP/ext/small_inline.py
11 > small_inline=$TESTTMP/ext/small_inline.py
12 > EOF
12 > EOF
13
13
14 $ hg init repo
14 $ hg init repo
15 $ cd repo
15 $ cd repo
16
16
17 Try on an empty repository
17 Try on an empty repository
18
18
19 $ hg debug-revlog-stats
19 $ hg debug-revlog-stats
20 rev-count data-size inl type target
20 rev-count data-size inl type target
21 0 0 yes changelog
22 0 0 yes manifest
23
21
24 $ mkdir folder
22 $ mkdir folder
25 $ touch a b folder/c folder/d
23 $ touch a b folder/c folder/d
26 $ hg commit -Aqm 0
24 $ hg commit -Aqm 0
27 $ echo "text" > a
25 $ echo "text" > a
28 $ hg rm b
26 $ hg rm b
29 $ echo "longer string" > folder/d
27 $ echo "longer string" > folder/d
30 $ hg commit -Aqm 1
28 $ hg commit -Aqm 1
31
29
32 Differences in data size observed with pure is due to different compression
30 Differences in data size observed with pure is due to different compression
33 algorithms
31 algorithms
34
32
35 $ hg debug-revlog-stats
33 $ hg debug-revlog-stats
36 rev-count data-size inl type target
34 rev-count data-size inl type target
37 2 138 no changelog (no-pure !)
35 2 138 no changelog (no-pure !)
38 2 137 no changelog (pure !)
36 2 137 no changelog (pure !)
39 2 177 no manifest (no-pure !)
37 2 177 no manifest (no-pure !)
40 2 168 no manifest (pure !)
38 2 168 no manifest (pure !)
41 2 6 yes file a
39 2 6 yes file a
42 1 0 yes file b
40 1 0 yes file b
43 1 0 yes file folder/c
41 1 0 yes file folder/c
44 2 15 no file folder/d
42 2 15 no file folder/d
45
43
46 Test 'changelog' command argument
44 Test 'changelog' command argument
47
45
48 $ hg debug-revlog-stats -c
46 $ hg debug-revlog-stats -c
49 rev-count data-size inl type target
47 rev-count data-size inl type target
50 2 138 no changelog (no-pure !)
48 2 138 no changelog (no-pure !)
51 2 137 no changelog (pure !)
49 2 137 no changelog (pure !)
52
50
53 Test 'manifest' command argument
51 Test 'manifest' command argument
54
52
55 $ hg debug-revlog-stats -m
53 $ hg debug-revlog-stats -m
56 rev-count data-size inl type target
54 rev-count data-size inl type target
57 2 177 no manifest (no-pure !)
55 2 177 no manifest (no-pure !)
58 2 168 no manifest (pure !)
56 2 168 no manifest (pure !)
59
57
60 Test 'file' command argument
58 Test 'file' command argument
61
59
62 $ hg debug-revlog-stats -f
60 $ hg debug-revlog-stats -f
63 rev-count data-size inl type target
61 rev-count data-size inl type target
64 2 6 yes file a
62 2 6 yes file a
65 1 0 yes file b
63 1 0 yes file b
66 1 0 yes file folder/c
64 1 0 yes file folder/c
67 2 15 no file folder/d
65 2 15 no file folder/d
68
66
69 Test multiple command arguments
67 Test multiple command arguments
70
68
71 $ hg debug-revlog-stats -cm
69 $ hg debug-revlog-stats -cm
72 rev-count data-size inl type target
70 rev-count data-size inl type target
73 2 138 no changelog (no-pure !)
71 2 138 no changelog (no-pure !)
74 2 137 no changelog (pure !)
72 2 137 no changelog (pure !)
75 2 177 no manifest (no-pure !)
73 2 177 no manifest (no-pure !)
76 2 168 no manifest (pure !)
74 2 168 no manifest (pure !)
77
75
General Comments 0
You need to be logged in to leave comments. Login now