scripts: dbgbmap.py tweaks
- Create a grid with dashes even in -%/--usage mode. This was surprisingly annoying since it breaks the existing 1 block = 1 char assumption. - Derive percentages from in-use blocks, not all blocks. This matches behavior of tracebd.py's percentages (% read/prog/erase). Though not tracebd.py's percent wear... - Added mdir/btree/data counts/percentages to dbgbmapd3.py, for use in custom --title strings and the newly added --title-usage. Because why not. Unlike dbgbmap.py, performance is not a concern at all, and the consistency between these two scripts helps maintainability. Case in point: also fixed a typo from copying the block_count inference between scripts.
This commit is contained in:
+54
-26
@@ -4299,6 +4299,7 @@ def main_(f, disk, mroots=None, *,
|
|||||||
tiny=False,
|
tiny=False,
|
||||||
title=None,
|
title=None,
|
||||||
title_littlefs=False,
|
title_littlefs=False,
|
||||||
|
title_usage=False,
|
||||||
padding=0,
|
padding=0,
|
||||||
**args):
|
**args):
|
||||||
# give f an writeln function
|
# give f an writeln function
|
||||||
@@ -4415,6 +4416,7 @@ def main_(f, disk, mroots=None, *,
|
|||||||
mdir_count = 0
|
mdir_count = 0
|
||||||
btree_count = 0
|
btree_count = 0
|
||||||
data_count = 0
|
data_count = 0
|
||||||
|
total_count = 0
|
||||||
for child in lfs.traverse(
|
for child in lfs.traverse(
|
||||||
mtree_only=mtree_only):
|
mtree_only=mtree_only):
|
||||||
# track each block in our window
|
# track each block in our window
|
||||||
@@ -4430,6 +4432,7 @@ def main_(f, disk, mroots=None, *,
|
|||||||
else:
|
else:
|
||||||
usage = range(0)
|
usage = range(0)
|
||||||
mdir_count += 1
|
mdir_count += 1
|
||||||
|
total_count += 1
|
||||||
|
|
||||||
# btree node?
|
# btree node?
|
||||||
elif isinstance(child, Rbyd):
|
elif isinstance(child, Rbyd):
|
||||||
@@ -4439,12 +4442,14 @@ def main_(f, disk, mroots=None, *,
|
|||||||
else:
|
else:
|
||||||
usage = range(0)
|
usage = range(0)
|
||||||
btree_count += 1
|
btree_count += 1
|
||||||
|
total_count += 1
|
||||||
|
|
||||||
# bptr?
|
# bptr?
|
||||||
elif isinstance(child, Bptr):
|
elif isinstance(child, Bptr):
|
||||||
type = 'data'
|
type = 'data'
|
||||||
usage = range(child.off, child.off+child.size)
|
usage = range(child.off, child.off+child.size)
|
||||||
data_count += 1
|
data_count += 1
|
||||||
|
total_count += 1
|
||||||
|
|
||||||
else:
|
else:
|
||||||
assert False, "%r?" % b
|
assert False, "%r?" % b
|
||||||
@@ -4575,21 +4580,25 @@ def main_(f, disk, mroots=None, *,
|
|||||||
|
|
||||||
# assign chars based on block type
|
# assign chars based on block type
|
||||||
for b in bmap.values():
|
for b in bmap.values():
|
||||||
char__ = chars_[b.block, (b.type, '0x%x' % b.block)]
|
b.chars = {}
|
||||||
|
for type in [b.type] + (['unused'] if args.get('usage') else []):
|
||||||
|
char__ = chars_[b.block, (type, '0x%x' % b.block)]
|
||||||
if char__ is not None:
|
if char__ is not None:
|
||||||
# don't punescape unless we have to
|
# don't punescape unless we have to
|
||||||
if '%' in char__:
|
if '%' in char__:
|
||||||
char__ = punescape(char__, b.attrs)
|
char__ = punescape(char__, b.attrs)
|
||||||
b.char = char__[0] # limit to 1 char
|
b.chars[type] = char__[0] # limit to 1 char
|
||||||
|
|
||||||
# assign colors based on block type
|
# assign colors based on block type
|
||||||
for b in bmap.values():
|
for b in bmap.values():
|
||||||
color__ = colors_[b.block, (b.type, '0x%x' % b.block)]
|
b.colors = {}
|
||||||
|
for type in [b.type] + (['unused'] if args.get('usage') else []):
|
||||||
|
color__ = colors_[b.block, (type, '0x%x' % b.block)]
|
||||||
if color__ is not None:
|
if color__ is not None:
|
||||||
# don't punescape unless we have to
|
# don't punescape unless we have to
|
||||||
if '%' in color__:
|
if '%' in color__:
|
||||||
color__ = punescape(color__, b.attrs)
|
color__ = punescape(color__, b.attrs)
|
||||||
b.color = color__
|
b.colors[type] = color__
|
||||||
|
|
||||||
# render to canvas in a specific z-order that prioritizes
|
# render to canvas in a specific z-order that prioritizes
|
||||||
# interesting blocks
|
# interesting blocks
|
||||||
@@ -4599,7 +4608,16 @@ def main_(f, disk, mroots=None, *,
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
for b in bmap.values():
|
for b in bmap.values():
|
||||||
if b.type != type:
|
# a bit of a hack, but render all blocks as unused
|
||||||
|
# in the first pass in usage mode
|
||||||
|
if args.get('usage') and type == 'unused':
|
||||||
|
type__ = 'unused'
|
||||||
|
usage__ = range(block_size_)
|
||||||
|
else:
|
||||||
|
type__ = b.type
|
||||||
|
usage__ = b.usage
|
||||||
|
|
||||||
|
if type__ != type:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# contiguous?
|
# contiguous?
|
||||||
@@ -4607,14 +4625,14 @@ def main_(f, disk, mroots=None, *,
|
|||||||
# where are we in the curve?
|
# where are we in the curve?
|
||||||
if args.get('usage'):
|
if args.get('usage'):
|
||||||
# skip blocks with no usage
|
# skip blocks with no usage
|
||||||
if not b.usage:
|
if not usage__:
|
||||||
continue
|
continue
|
||||||
block__ = b.block - global_block
|
block__ = b.block - global_block
|
||||||
usage__ = range(
|
usage__ = range(
|
||||||
mt.floor(((block__*block_size_ + b.usage.start)
|
mt.floor(((block__*block_size_ + usage__.start)
|
||||||
/ (block_size_ * len(bmap)))
|
/ (block_size_ * len(bmap)))
|
||||||
* len(global_curve)),
|
* len(global_curve)),
|
||||||
mt.ceil(((block__*block_size_ + b.usage.stop)
|
mt.ceil(((block__*block_size_ + usage__.stop)
|
||||||
/ (block_size_ * len(bmap)))
|
/ (block_size_ * len(bmap)))
|
||||||
* len(global_curve)))
|
* len(global_curve)))
|
||||||
else:
|
else:
|
||||||
@@ -4633,8 +4651,8 @@ def main_(f, disk, mroots=None, *,
|
|||||||
y__ = canvas.height - (y__+1)
|
y__ = canvas.height - (y__+1)
|
||||||
|
|
||||||
canvas.point(x__, y__,
|
canvas.point(x__, y__,
|
||||||
char=True if braille or dots else b.char,
|
char=True if braille or dots else b.chars[type],
|
||||||
color=b.color)
|
color=b.colors[type])
|
||||||
|
|
||||||
# blocky?
|
# blocky?
|
||||||
else:
|
else:
|
||||||
@@ -4649,27 +4667,28 @@ def main_(f, disk, mroots=None, *,
|
|||||||
# render byte-level usage?
|
# render byte-level usage?
|
||||||
if args.get('usage'):
|
if args.get('usage'):
|
||||||
# skip blocks with no usage
|
# skip blocks with no usage
|
||||||
if not b.usage:
|
if not usage__:
|
||||||
continue
|
continue
|
||||||
# scale from bytes -> pixels
|
# scale from bytes -> pixels
|
||||||
usage__ = range(
|
usage__ = range(
|
||||||
mt.floor((b.usage.start/block_size_)
|
mt.floor((usage__.start/block_size_)
|
||||||
* (width__*height__)),
|
* (width__*height__)),
|
||||||
mt.ceil((b.usage.stop/block_size_)
|
mt.ceil((usage__.stop/block_size_)
|
||||||
* (width__*height__)))
|
* (width__*height__)))
|
||||||
# map to in-block curve
|
# map to in-block curve
|
||||||
for i, (dx, dy) in enumerate(curve(width__, height__)):
|
for i, (dx, dy) in enumerate(curve(width__, height__)):
|
||||||
if i in usage__:
|
if i in usage__:
|
||||||
# flip y
|
# flip y
|
||||||
canvas.point(x__+dx, y__+(height__-(dy+1)),
|
canvas.point(x__+dx, y__+(height__-(dy+1)),
|
||||||
char=True if braille or dots else b.char,
|
char=True if braille or dots
|
||||||
color=b.color)
|
else b.chars[type],
|
||||||
|
color=b.colors[type])
|
||||||
|
|
||||||
# render simple blocks
|
# render simple blocks
|
||||||
else:
|
else:
|
||||||
canvas.rect(x__, y__, width__, height__,
|
canvas.rect(x__, y__, width__, height__,
|
||||||
char=True if braille or dots else b.char,
|
char=True if braille or dots else b.chars[type],
|
||||||
color=b.color)
|
color=b.colors[type])
|
||||||
|
|
||||||
# print some summary info
|
# print some summary info
|
||||||
if not no_header:
|
if not no_header:
|
||||||
@@ -4704,12 +4723,16 @@ def main_(f, disk, mroots=None, *,
|
|||||||
'cksum': '%08x%s' % (
|
'cksum': '%08x%s' % (
|
||||||
lfs.cksum,
|
lfs.cksum,
|
||||||
'' if lfs.ckgcksum() else '?'),
|
'' if lfs.ckgcksum() else '?'),
|
||||||
'mdir_count': mdir_count,
|
'total': total_count,
|
||||||
'mdir_percent': '%.1f%%' % (100*(mdir_count / len(bmap))),
|
'mdir': mdir_count,
|
||||||
'btree_count': btree_count,
|
'mdir_percent': '%.1f%%' % (
|
||||||
'btree_percent': '%.1f%%' % (100*(btree_count / len(bmap))),
|
100*(mdir_count / max(total_count, 1))),
|
||||||
'data_count': data_count,
|
'btree': btree_count,
|
||||||
'data_percent': '%.1f%%' % (100*(data_count / len(bmap))),
|
'btree_percent': '%.1f%%' % (
|
||||||
|
100*(btree_count / max(total_count, 1))),
|
||||||
|
'data': data_count,
|
||||||
|
'data_percent': '%.1f%%' % (
|
||||||
|
100*(data_count / max(total_count, 1))),
|
||||||
}))
|
}))
|
||||||
elif title_littlefs:
|
elif title_littlefs:
|
||||||
f.writeln('littlefs%s v%s.%s %sx%s %s w%s.%s, cksum %08x%s' % (
|
f.writeln('littlefs%s v%s.%s %sx%s %s w%s.%s, cksum %08x%s' % (
|
||||||
@@ -4726,9 +4749,9 @@ def main_(f, disk, mroots=None, *,
|
|||||||
f.writeln('bd %sx%s, %6s mdir, %6s btree, %6s data' % (
|
f.writeln('bd %sx%s, %6s mdir, %6s btree, %6s data' % (
|
||||||
lfs.block_size if lfs.block_size is not None else '?',
|
lfs.block_size if lfs.block_size is not None else '?',
|
||||||
lfs.block_count if lfs.block_count is not None else '?',
|
lfs.block_count if lfs.block_count is not None else '?',
|
||||||
'%.1f%%' % (100*(mdir_count / len(bmap))),
|
'%.1f%%' % (100*(mdir_count / max(total_count, 1))),
|
||||||
'%.1f%%' % (100*(btree_count / len(bmap))),
|
'%.1f%%' % (100*(btree_count / max(total_count, 1))),
|
||||||
'%.1f%%' % (100*(data_count / len(bmap)))))
|
'%.1f%%' % (100*(data_count / max(total_count, 1)))))
|
||||||
|
|
||||||
# draw canvas
|
# draw canvas
|
||||||
for row in range(canvas.height//canvas.yscale):
|
for row in range(canvas.height//canvas.yscale):
|
||||||
@@ -4980,6 +5003,11 @@ if __name__ == "__main__":
|
|||||||
'--title-littlefs',
|
'--title-littlefs',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help="Use the littlefs mount string as the title.")
|
help="Use the littlefs mount string as the title.")
|
||||||
|
parser.add_argument(
|
||||||
|
'--title-usage',
|
||||||
|
action='store_true',
|
||||||
|
help="Use the mdir/btree/data usage as the title. This is the "
|
||||||
|
"default.")
|
||||||
# TODO drop padding in ascii scripts, no one is ever going to use this
|
# TODO drop padding in ascii scripts, no one is ever going to use this
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--padding',
|
'--padding',
|
||||||
|
|||||||
+41
-2
@@ -16,6 +16,7 @@ import functools as ft
|
|||||||
import itertools as it
|
import itertools as it
|
||||||
import json
|
import json
|
||||||
import math as mt
|
import math as mt
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
import shlex
|
import shlex
|
||||||
import struct
|
import struct
|
||||||
@@ -4628,6 +4629,8 @@ def main(disk, output, mroots=None, *,
|
|||||||
aspect_ratio=(1,1),
|
aspect_ratio=(1,1),
|
||||||
tiny=False,
|
tiny=False,
|
||||||
title=None,
|
title=None,
|
||||||
|
title_littlefs=False,
|
||||||
|
title_usage=False,
|
||||||
padding=None,
|
padding=None,
|
||||||
no_label=False,
|
no_label=False,
|
||||||
dark=False,
|
dark=False,
|
||||||
@@ -4728,7 +4731,7 @@ def main(disk, output, mroots=None, *,
|
|||||||
block_count_ = lfs.config.geometry.block_count
|
block_count_ = lfs.config.geometry.block_count
|
||||||
else:
|
else:
|
||||||
f.seek(0, os.SEEK_END)
|
f.seek(0, os.SEEK_END)
|
||||||
block_count_ = mt.ceil(f_.tell() / block_size)
|
block_count_ = mt.ceil(f.tell() / block_size)
|
||||||
|
|
||||||
# flatten blocks, default to all blocks
|
# flatten blocks, default to all blocks
|
||||||
blocks_ = list(
|
blocks_ = list(
|
||||||
@@ -4740,6 +4743,10 @@ def main(disk, output, mroots=None, *,
|
|||||||
|
|
||||||
# traverse the filesystem and create a block map
|
# traverse the filesystem and create a block map
|
||||||
bmap = {b: BmapBlock(b, 'unused') for b in blocks_}
|
bmap = {b: BmapBlock(b, 'unused') for b in blocks_}
|
||||||
|
mdir_count = 0
|
||||||
|
btree_count = 0
|
||||||
|
data_count = 0
|
||||||
|
total_count = 0
|
||||||
for child, path in lfs.traverse(
|
for child, path in lfs.traverse(
|
||||||
mtree_only=mtree_only,
|
mtree_only=mtree_only,
|
||||||
path=True):
|
path=True):
|
||||||
@@ -4755,6 +4762,8 @@ def main(disk, output, mroots=None, *,
|
|||||||
usage = range(child.eoff)
|
usage = range(child.eoff)
|
||||||
else:
|
else:
|
||||||
usage = range(0)
|
usage = range(0)
|
||||||
|
mdir_count += 1
|
||||||
|
total_count += 1
|
||||||
|
|
||||||
# btree node?
|
# btree node?
|
||||||
elif isinstance(child, Rbyd):
|
elif isinstance(child, Rbyd):
|
||||||
@@ -4763,11 +4772,15 @@ def main(disk, output, mroots=None, *,
|
|||||||
usage = range(child.eoff)
|
usage = range(child.eoff)
|
||||||
else:
|
else:
|
||||||
usage = range(0)
|
usage = range(0)
|
||||||
|
btree_count += 1
|
||||||
|
total_count += 1
|
||||||
|
|
||||||
# bptr?
|
# bptr?
|
||||||
elif isinstance(child, Bptr):
|
elif isinstance(child, Bptr):
|
||||||
type = 'data'
|
type = 'data'
|
||||||
usage = range(child.off, child.off+child.size)
|
usage = range(child.off, child.off+child.size)
|
||||||
|
data_count += 1
|
||||||
|
total_count += 1
|
||||||
|
|
||||||
else:
|
else:
|
||||||
assert False, "%r?" % b
|
assert False, "%r?" % b
|
||||||
@@ -4993,8 +5006,18 @@ def main(disk, output, mroots=None, *,
|
|||||||
'cksum': '%08x%s' % (
|
'cksum': '%08x%s' % (
|
||||||
lfs.cksum,
|
lfs.cksum,
|
||||||
'' if lfs.ckgcksum() else '?'),
|
'' if lfs.ckgcksum() else '?'),
|
||||||
|
'total': total_count,
|
||||||
|
'mdir': mdir_count,
|
||||||
|
'mdir_percent': '%.1f%%' % (
|
||||||
|
100*(mdir_count / max(total_count, 1))),
|
||||||
|
'btree': btree_count,
|
||||||
|
'btree_percent': '%.1f%%' % (
|
||||||
|
100*(btree_count / max(total_count, 1))),
|
||||||
|
'data': data_count,
|
||||||
|
'data_percent': '%.1f%%' % (
|
||||||
|
100*(data_count / max(total_count, 1))),
|
||||||
}))
|
}))
|
||||||
else:
|
elif not title_usage:
|
||||||
f.write('littlefs%s v%s.%s %sx%s %s w%s.%s, cksum %08x%s' % (
|
f.write('littlefs%s v%s.%s %sx%s %s w%s.%s, cksum %08x%s' % (
|
||||||
'' if lfs.ckmagic() else '?',
|
'' if lfs.ckmagic() else '?',
|
||||||
lfs.version.major if lfs.version is not None else '?',
|
lfs.version.major if lfs.version is not None else '?',
|
||||||
@@ -5005,6 +5028,13 @@ def main(disk, output, mroots=None, *,
|
|||||||
lfs.mbweightrepr(), lfs.mrweightrepr(),
|
lfs.mbweightrepr(), lfs.mrweightrepr(),
|
||||||
lfs.cksum,
|
lfs.cksum,
|
||||||
'' if lfs.ckgcksum() else '?'))
|
'' if lfs.ckgcksum() else '?'))
|
||||||
|
else:
|
||||||
|
f.writeln('bd %sx%s, %s mdir, %s btree, %s data' % (
|
||||||
|
lfs.block_size if lfs.block_size is not None else '?',
|
||||||
|
lfs.block_count if lfs.block_count is not None else '?',
|
||||||
|
'%.1f%%' % (100*(mdir_count / max(total_count, 1))),
|
||||||
|
'%.1f%%' % (100*(btree_count / max(total_count, 1))),
|
||||||
|
'%.1f%%' % (100*(data_count / max(total_count, 1)))))
|
||||||
f.write('</tspan>')
|
f.write('</tspan>')
|
||||||
if not no_mode and not no_javascript:
|
if not no_mode and not no_javascript:
|
||||||
f.write('<tspan id="mode" x="%(x)d" y="1.1em" '
|
f.write('<tspan id="mode" x="%(x)d" y="1.1em" '
|
||||||
@@ -5894,6 +5924,15 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--title',
|
'--title',
|
||||||
help="Add a title. Accepts %% modifiers.")
|
help="Add a title. Accepts %% modifiers.")
|
||||||
|
parser.add_argument(
|
||||||
|
'--title-littlefs',
|
||||||
|
action='store_true',
|
||||||
|
help="Use the littlefs mount string as the title. This is the "
|
||||||
|
"default.")
|
||||||
|
parser.add_argument(
|
||||||
|
'--title-usage',
|
||||||
|
action='store_true',
|
||||||
|
help="Use the mdir/btree/data usage as the title.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--padding',
|
'--padding',
|
||||||
type=float,
|
type=float,
|
||||||
|
|||||||
+31
-23
@@ -1665,7 +1665,7 @@ def main(path='-', *,
|
|||||||
if block not in bmap:
|
if block not in bmap:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
bmap[block].erase(0, block_count_,
|
bmap[block].erase(0, block_size_,
|
||||||
wear=+1 if wear else 0)
|
wear=+1 if wear else 0)
|
||||||
erased += block_count_
|
erased += block_count_
|
||||||
return True
|
return True
|
||||||
@@ -1691,6 +1691,25 @@ def main(path='-', *,
|
|||||||
if bmap is None:
|
if bmap is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# compute total ops
|
||||||
|
total = readed + proged + erased
|
||||||
|
|
||||||
|
# if we're showing wear, find min/max/avg/etc
|
||||||
|
if wear:
|
||||||
|
wear_min = min(b.wear for b in bmap.values())
|
||||||
|
wear_max = max(b.wear for b in bmap.values())
|
||||||
|
wear_avg = (sum(b.wear for b in bmap.values())
|
||||||
|
/ max(len(bmap), 1))
|
||||||
|
wear_stddev = mt.sqrt(
|
||||||
|
sum((b.wear - wear_avg)**2 for b in bmap.values())
|
||||||
|
/ max(len(bmap), 1))
|
||||||
|
|
||||||
|
# if block_cycles isn't provide, scale based on max wear
|
||||||
|
if block_cycles is not None:
|
||||||
|
block_cycles_ = block_cycles
|
||||||
|
else:
|
||||||
|
block_cycles_ = wear_max
|
||||||
|
|
||||||
# give ring a writeln function
|
# give ring a writeln function
|
||||||
def writeln(s=''):
|
def writeln(s=''):
|
||||||
ring.write(s)
|
ring.write(s)
|
||||||
@@ -1799,10 +1818,14 @@ def main(path='-', *,
|
|||||||
b.height = max(b.height, 1)
|
b.height = max(b.height, 1)
|
||||||
|
|
||||||
# TODO chars should probably take priority over braille/dots
|
# TODO chars should probably take priority over braille/dots
|
||||||
|
# TODO limit these based on requested ops?
|
||||||
# assign chars based on op + block
|
# assign chars based on op + block
|
||||||
for b in bmap.values():
|
for b in bmap.values():
|
||||||
b.chars = {}
|
b.chars = {}
|
||||||
for op in ['read', 'prog', 'erase', 'noop']:
|
for op in ((['read'] if reads else [])
|
||||||
|
+ (['prog'] if progs else [])
|
||||||
|
+ (['erase'] if erases else [])
|
||||||
|
+ ['noop']):
|
||||||
char__ = chars_.get((b.block, (op, '0x%x' % b.block)))
|
char__ = chars_.get((b.block, (op, '0x%x' % b.block)))
|
||||||
if char__ is not None:
|
if char__ is not None:
|
||||||
# don't punescape unless we have to
|
# don't punescape unless we have to
|
||||||
@@ -1813,7 +1836,10 @@ def main(path='-', *,
|
|||||||
# assign colors based on op + block
|
# assign colors based on op + block
|
||||||
for b in bmap.values():
|
for b in bmap.values():
|
||||||
b.colors = {}
|
b.colors = {}
|
||||||
for op in ['read', 'prog', 'erase', 'noop']:
|
for op in ((['read'] if reads else [])
|
||||||
|
+ (['prog'] if progs else [])
|
||||||
|
+ (['erase'] if erases else [])
|
||||||
|
+ ['noop']):
|
||||||
color__ = colors_.get((b.block, (op, '0x%x' % b.block)))
|
color__ = colors_.get((b.block, (op, '0x%x' % b.block)))
|
||||||
if color__ is not None:
|
if color__ is not None:
|
||||||
# don't punescape unless we have to
|
# don't punescape unless we have to
|
||||||
@@ -1822,6 +1848,7 @@ def main(path='-', *,
|
|||||||
b.colors[op] = color__
|
b.colors[op] = color__
|
||||||
|
|
||||||
# assign wear chars based on block
|
# assign wear chars based on block
|
||||||
|
if wear:
|
||||||
for b in bmap.values():
|
for b in bmap.values():
|
||||||
b.wear_chars = []
|
b.wear_chars = []
|
||||||
for char__ in wear_chars_.getall((b.block, '0x%x' % b.block)):
|
for char__ in wear_chars_.getall((b.block, '0x%x' % b.block)):
|
||||||
@@ -1831,6 +1858,7 @@ def main(path='-', *,
|
|||||||
b.wear_chars.append(char__[0]) # limit to 1 char
|
b.wear_chars.append(char__[0]) # limit to 1 char
|
||||||
|
|
||||||
# assign wear colors based on block
|
# assign wear colors based on block
|
||||||
|
if wear:
|
||||||
for b in bmap.values():
|
for b in bmap.values():
|
||||||
b.wear_colors = []
|
b.wear_colors = []
|
||||||
for color__ in wear_colors_.getall((b.block, '0x%x' % b.block)):
|
for color__ in wear_colors_.getall((b.block, '0x%x' % b.block)):
|
||||||
@@ -1839,25 +1867,6 @@ def main(path='-', *,
|
|||||||
color__ = punescape(color__, b.attrs)
|
color__ = punescape(color__, b.attrs)
|
||||||
b.wear_colors.append(color__)
|
b.wear_colors.append(color__)
|
||||||
|
|
||||||
# compute total ops
|
|
||||||
total = readed + proged + erased
|
|
||||||
|
|
||||||
# if we're showing wear, find min/max/avg/etc
|
|
||||||
if wear:
|
|
||||||
wear_min = min(b.wear for b in bmap.values())
|
|
||||||
wear_max = max(b.wear for b in bmap.values())
|
|
||||||
wear_avg = (sum(b.wear for b in bmap.values())
|
|
||||||
/ max(len(bmap), 1))
|
|
||||||
wear_stddev = mt.sqrt(
|
|
||||||
sum((b.wear - wear_avg)**2 for b in bmap.values())
|
|
||||||
/ max(len(bmap), 1))
|
|
||||||
|
|
||||||
# if block_cycles isn't provide, scale based on max wear
|
|
||||||
if block_cycles is not None:
|
|
||||||
block_cycles_ = block_cycles
|
|
||||||
else:
|
|
||||||
block_cycles_ = wear_max
|
|
||||||
|
|
||||||
# render to canvas in a specific z-order that prioritizes
|
# render to canvas in a specific z-order that prioritizes
|
||||||
# interesting ops
|
# interesting ops
|
||||||
for op in reversed(Z_ORDER):
|
for op in reversed(Z_ORDER):
|
||||||
@@ -1957,7 +1966,6 @@ def main(path='-', *,
|
|||||||
|
|
||||||
# print some summary info
|
# print some summary info
|
||||||
if not no_header:
|
if not no_header:
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
# # compute stddev of wear using our bmap, this is a bit different
|
# # compute stddev of wear using our bmap, this is a bit different
|
||||||
# # from reads/progs/erases which ignores any bmap window, but it's
|
# # from reads/progs/erases which ignores any bmap window, but it's
|
||||||
|
|||||||
Reference in New Issue
Block a user