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:
Christopher Haster
2025-04-10 12:37:43 -05:00
parent d5c0e142f0
commit 465fdd1fca
3 changed files with 147 additions and 72 deletions
+44 -36
View File
@@ -1665,7 +1665,7 @@ def main(path='-', *,
if block not in bmap:
return False
else:
bmap[block].erase(0, block_count_,
bmap[block].erase(0, block_size_,
wear=+1 if wear else 0)
erased += block_count_
return True
@@ -1691,6 +1691,25 @@ def main(path='-', *,
if bmap is None:
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
def writeln(s=''):
ring.write(s)
@@ -1799,10 +1818,14 @@ def main(path='-', *,
b.height = max(b.height, 1)
# TODO chars should probably take priority over braille/dots
# TODO limit these based on requested ops?
# assign chars based on op + block
for b in bmap.values():
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)))
if char__ is not None:
# don't punescape unless we have to
@@ -1813,7 +1836,10 @@ def main(path='-', *,
# assign colors based on op + block
for b in bmap.values():
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)))
if color__ is not None:
# don't punescape unless we have to
@@ -1822,41 +1848,24 @@ def main(path='-', *,
b.colors[op] = color__
# assign wear chars based on block
for b in bmap.values():
b.wear_chars = []
for char__ in wear_chars_.getall((b.block, '0x%x' % b.block)):
# don't punescape unless we have to
if '%' in char__:
char__ = punescape(char__, b.attrs)
b.wear_chars.append(char__[0]) # limit to 1 char
if wear:
for b in bmap.values():
b.wear_chars = []
for char__ in wear_chars_.getall((b.block, '0x%x' % b.block)):
# don't punescape unless we have to
if '%' in char__:
char__ = punescape(char__, b.attrs)
b.wear_chars.append(char__[0]) # limit to 1 char
# assign wear colors based on block
for b in bmap.values():
b.wear_colors = []
for color__ in wear_colors_.getall((b.block, '0x%x' % b.block)):
# don't punescape unless we have to
if '%' in color__:
color__ = punescape(color__, b.attrs)
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
for b in bmap.values():
b.wear_colors = []
for color__ in wear_colors_.getall((b.block, '0x%x' % b.block)):
# don't punescape unless we have to
if '%' in color__:
color__ = punescape(color__, b.attrs)
b.wear_colors.append(color__)
# render to canvas in a specific z-order that prioritizes
# interesting ops
@@ -1957,7 +1966,6 @@ def main(path='-', *,
# print some summary info
if not no_header:
# TODO
# # compute stddev of wear using our bmap, this is a bit different
# # from reads/progs/erases which ignores any bmap window, but it's