diff --git a/scripts/dbgbmap.py b/scripts/dbgbmap.py index 8f31ff98..116369dd 100755 --- a/scripts/dbgbmap.py +++ b/scripts/dbgbmap.py @@ -792,85 +792,6 @@ class Rbyd: yield rid, tag, w, j, d, data - # create tree representation for debugging - def tree(self): - trunks = co.defaultdict(lambda: (-1, 0)) - alts = co.defaultdict(lambda: {}) - - rid, tag = -1, 0 - while True: - done, rid, tag, w, j, d, data, path = self.lookup(rid, tag+0x1) - # found end of tree? - if done: - break - - # keep track of trunks/alts - trunks[j] = (rid, tag) - - for j_, j__, followed, c in path: - if followed: - alts[j_] |= {'f': j__, 'c': c} - else: - alts[j_] |= {'nf': j__, 'c': c} - - # treat unreachable alts as converging paths - for j_, alt in alts.items(): - if 'f' not in alt: - alt['f'] = alt['nf'] - elif 'nf' not in alt: - alt['nf'] = alt['f'] - - # find the trunk and depth of each alt - def rec_trunk(j_): - if j_ not in alts: - return trunks[j_] - else: - if 'nft' not in alts[j_]: - alts[j_]['nft'] = rec_trunk(alts[j_]['nf']) - return alts[j_]['nft'] - - for j_ in alts.keys(): - rec_trunk(j_) - for j_, alt in alts.items(): - if alt['f'] in alts: - alt['ft'] = alts[alt['f']]['nft'] - else: - alt['ft'] = trunks[alt['f']] - - def rec_height(j_): - if j_ not in alts: - return 0 - else: - if 'h' not in alts[j_]: - alts[j_]['h'] = max( - rec_height(alts[j_]['f']), - rec_height(alts[j_]['nf'])) + 1 - return alts[j_]['h'] - - for j_ in alts.keys(): - rec_height(j_) - - t_depth = max((alt['h']+1 for alt in alts.values()), default=0) - - # convert to more general tree representation - tree = set() - for j, alt in alts.items(): - # note all non-trunk edges should be black - tree.add(TBranch( - a=alt['nft'], - b=alt['nft'], - d=t_depth-1 - alt['h'], - c=alt['c'], - )) - tree.add(TBranch( - a=alt['nft'], - b=alt['ft'], - d=t_depth-1 - alt['h'], - c='b', - )) - - return tree, t_depth - # btree lookup with this rbyd as the root def btree_lookup(self, f, block_size, bid, *, depth=None): @@ -927,201 +848,6 @@ class Rbyd: else: return not tags, bid + (rid_-rid), w, rbyd, rid_, tags, path - # btree rbyd-tree generation for debugging - def btree_tree(self, f, block_size, *, - depth=None, - inner=False): - # find the max depth of each layer to nicely align trees - bdepths = {} - bid = -1 - while True: - done, bid, w, rbyd, rid, tags, path = self.btree_lookup( - f, block_size, bid+1, depth=depth) - if done: - break - - for d, (bid, w, rbyd, rid, tags) in enumerate(path): - _, rdepth = rbyd.tree() - bdepths[d] = max(bdepths.get(d, 0), rdepth) - - # find all branches - tree = set() - root = None - branches = {} - bid = -1 - while True: - done, bid, w, rbyd, rid, tags, path = self.btree_lookup( - f, block_size, bid+1, depth=depth) - if done: - break - - d_ = 0 - leaf = None - for d, (bid, w, rbyd, rid, tags) in enumerate(path): - if not tags: - continue - - # map rbyd tree into B-tree space - rtree, rdepth = rbyd.tree() - - # note we adjust our bid/rids to be left-leaning, - # this allows a global order and make tree rendering quite - # a bit easier - rtree_ = set() - for branch in rtree: - a_rid, a_tag = branch.a - b_rid, b_tag = branch.b - _, _, _, a_w, _, _, _, _ = rbyd.lookup(a_rid, 0) - _, _, _, b_w, _, _, _, _ = rbyd.lookup(b_rid, 0) - rtree_.add(TBranch( - a=(a_rid-(a_w-1), a_tag), - b=(b_rid-(b_w-1), b_tag), - d=branch.d, - c=branch.c, - )) - rtree = rtree_ - - # connect our branch to the rbyd's root - if leaf is not None: - root = min(rtree, - key=lambda branch: branch.d, - default=None) - - if root is not None: - r_rid, r_tag = root.a - else: - r_rid, r_tag = rid-(w-1), tags[0][0] - tree.add(TBranch( - a=leaf, - b=(bid-rid+r_rid, d, r_rid, r_tag), - d=d_-1, - c='b', - )) - - for branch in rtree: - # map rbyd branches into our btree space - a_rid, a_tag = branch.a - b_rid, b_tag = branch.b - tree.add(TBranch( - a=(bid-rid+a_rid, d, a_rid, a_tag), - b=(bid-rid+b_rid, d, b_rid, b_tag), - d=branch.d + d_ + bdepths.get(d, 0)-rdepth, - c=branch.c, - )) - - d_ += max(bdepths.get(d, 0), 1) - leaf = (bid-(w-1), d, rid-(w-1), - next((tag for tag, _, _, _ in tags - if tag & 0xfff == TAG_BRANCH), - TAG_BRANCH)) - - # remap branches to leaves if we aren't showing inner branches - if not inner: - # step through each layer backwards - b_depth = max((branch.a[1]+1 for branch in tree), default=0) - - # keep track of the original bids, unfortunately because we - # store the bids in the branches we overwrite these - tree = {(branch.b[0] - branch.b[2], branch) for branch in tree} - - for bd in reversed(range(b_depth-1)): - # find leaf-roots at this level - roots = {} - for bid, branch in tree: - # choose the highest node as the root - if (branch.b[1] == b_depth-1 - and (bid not in roots - or branch.d < roots[bid].d)): - roots[bid] = branch - - # remap branches to leaf-roots - tree_ = set() - for bid, branch in tree: - if branch.a[1] == bd and branch.a[0] in roots: - branch = TBranch( - a=roots[branch.a[0]].b, - b=branch.b, - d=branch.d, - c=branch.c, - ) - if branch.b[1] == bd and branch.b[0] in roots: - branch = TBranch( - a=branch.a, - b=roots[branch.b[0]].b, - d=branch.d, - c=branch.c, - ) - tree_.add((bid, branch)) - tree = tree_ - - # strip out bids - tree = {branch for _, branch in tree} - - return tree, max((branch.d+1 for branch in tree), default=0) - - # btree B-tree generation for debugging - def btree_btree(self, f, block_size, *, - depth=None, - inner=False): - # find all branches - tree = set() - root = None - branches = {} - bid = -1 - while True: - done, bid, w, rbyd, rid, tags, path = self.btree_lookup( - f, block_size, bid+1, depth=depth) - if done: - break - - # if we're not showing inner nodes, prefer names higher in - # the tree since this avoids showing vestigial names - name = None - if not inner: - name = None - for bid_, w_, rbyd_, rid_, tags_ in reversed(path): - for tag_, j_, d_, data_ in tags_: - if tag_ & 0x7f00 == TAG_NAME: - name = (tag_, j_, d_, data_) - - if rid_-(w_-1) != 0: - break - - a = root - for d, (bid, w, rbyd, rid, tags) in enumerate(path): - if not tags: - continue - - b = (bid-(w-1), d, rid-(w-1), - (name if name else tags[0])[0]) - - # remap branches to leaves if we aren't showing - # inner branches - if not inner: - if b not in branches: - bid, w, rbyd, rid, tags = path[-1] - if not tags: - continue - branches[b] = ( - bid-(w-1), len(path)-1, rid-(w-1), - (name if name else tags[0])[0]) - b = branches[b] - - # found entry point? - if root is None: - root = b - a = root - - tree.add(TBranch( - a=a, - b=b, - d=d, - c='b', - )) - a = b - - return tree, max((branch.d+1 for branch in tree), default=0) - # mtree lookup with this rbyd as the mroot def mtree_lookup(self, f, block_size, mbid): # have mtree? diff --git a/scripts/dbgbtree.py b/scripts/dbgbtree.py index bc7685ba..21278a34 100755 --- a/scripts/dbgbtree.py +++ b/scripts/dbgbtree.py @@ -456,7 +456,8 @@ class Rbyd: yield rid, tag, w, j, d, data # create tree representation for debugging - def tree(self): + def tree(self, *, + rbyd=False): trunks = co.defaultdict(lambda: (-1, 0)) alts = co.defaultdict(lambda: {}) @@ -476,12 +477,30 @@ class Rbyd: else: alts[j_] |= {'nf': j__, 'c': c} - # treat unreachable alts as converging paths - for j_, alt in alts.items(): - if 'f' not in alt: - alt['f'] = alt['nf'] - elif 'nf' not in alt: - alt['nf'] = alt['f'] + if rbyd: + # treat unreachable alts as converging paths + for j_, alt in alts.items(): + if 'f' not in alt: + alt['f'] = alt['nf'] + elif 'nf' not in alt: + alt['nf'] = alt['f'] + + else: + # prune any alts with unreachable edges + pruned = {} + for j_, alt in alts.items(): + if 'f' not in alt: + pruned[j_] = alt['nf'] + elif 'nf' not in alt: + pruned[j_] = alt['f'] + for j_ in pruned.keys(): + del alts[j_] + + for j_, alt in alts.items(): + while alt['f'] in pruned: + alt['f'] = pruned[alt['f']] + while alt['nf'] in pruned: + alt['nf'] = pruned[alt['nf']] # find the trunk and depth of each alt def rec_trunk(j_): @@ -630,7 +649,7 @@ def main(disk, roots=None, *, # precompute rbyd-trees if requested t_width = 0 - if args.get('tree'): + if args.get('tree') or args.get('rbyd'): # find the max depth of each layer to nicely align trees bdepths = {} bid = -1 @@ -641,7 +660,7 @@ def main(disk, roots=None, *, break for d, (bid, w, rbyd, rid, tags) in enumerate(path): - _, rdepth = rbyd.tree() + _, rdepth = rbyd.tree(rbyd=args.get('rbyd')) bdepths[d] = max(bdepths.get(d, 0), rdepth) # find all branches @@ -662,7 +681,7 @@ def main(disk, roots=None, *, continue # map rbyd tree into B-tree space - rtree, rdepth = rbyd.tree() + rtree, rdepth = rbyd.tree(rbyd=args.get('rbyd')) # note we adjust our bid/rids to be left-leaning, # this allows a global order and make tree rendering quite @@ -817,7 +836,7 @@ def main(disk, roots=None, *, a = b # common tree renderer - if args.get('tree') or args.get('btree'): + if args.get('tree') or args.get('rbyd') or args.get('btree'): # find the max depth from the tree t_depth = max((branch.d+1 for branch in tree), default=0) if t_depth > 0: @@ -888,7 +907,9 @@ def main(disk, roots=None, *, if prbyd is None or rbyd != prbyd else '', treerepr(bid, w, bd, rid, tag) - if args.get('tree') or args.get('btree') else '', + if args.get('tree') + or args.get('rbyd') + or args.get('btree') else '', 2*w_width+1, '' if i != 0 else '%d-%d' % (bid-(w-1), bid) if w > 1 else bid if w > 0 @@ -1039,7 +1060,11 @@ if __name__ == "__main__": parser.add_argument( '-B', '--btree', action='store_true', - help="Show the underlying B-tree.") + help="Show the B-tree.") + parser.add_argument( + '-R', '--rbyd', + action='store_true', + help="Show the full underlying rbyd trees.") parser.add_argument( '-i', '--inner', action='store_true', diff --git a/scripts/dbglfs.py b/scripts/dbglfs.py index 2c725dcc..16ea5c02 100755 --- a/scripts/dbglfs.py +++ b/scripts/dbglfs.py @@ -487,7 +487,8 @@ class Rbyd: yield rid, tag, w, j, d, data # create tree representation for debugging - def tree(self): + def tree(self, *, + rbyd=False): trunks = co.defaultdict(lambda: (-1, 0)) alts = co.defaultdict(lambda: {}) @@ -507,12 +508,30 @@ class Rbyd: else: alts[j_] |= {'nf': j__, 'c': c} - # treat unreachable alts as converging paths - for j_, alt in alts.items(): - if 'f' not in alt: - alt['f'] = alt['nf'] - elif 'nf' not in alt: - alt['nf'] = alt['f'] + if rbyd: + # treat unreachable alts as converging paths + for j_, alt in alts.items(): + if 'f' not in alt: + alt['f'] = alt['nf'] + elif 'nf' not in alt: + alt['nf'] = alt['f'] + + else: + # prune any alts with unreachable edges + pruned = {} + for j_, alt in alts.items(): + if 'f' not in alt: + pruned[j_] = alt['nf'] + elif 'nf' not in alt: + pruned[j_] = alt['f'] + for j_ in pruned.keys(): + del alts[j_] + + for j_, alt in alts.items(): + while alt['f'] in pruned: + alt['f'] = pruned[alt['f']] + while alt['nf'] in pruned: + alt['nf'] = pruned[alt['nf']] # find the trunk and depth of each alt def rec_trunk(j_): @@ -624,18 +643,19 @@ class Rbyd: # btree rbyd-tree generation for debugging def btree_tree(self, f, block_size, *, depth=None, - inner=False): + inner=False, + rbyd=False): # find the max depth of each layer to nicely align trees bdepths = {} bid = -1 while True: - done, bid, w, rbyd, rid, tags, path = self.btree_lookup( + done, bid, w, rbyd_, rid, tags, path = self.btree_lookup( f, block_size, bid+1, depth=depth) if done: break - for d, (bid, w, rbyd, rid, tags) in enumerate(path): - _, rdepth = rbyd.tree() + for d, (bid, w, rbyd_, rid, tags) in enumerate(path): + _, rdepth = rbyd_.tree(rbyd=rbyd) bdepths[d] = max(bdepths.get(d, 0), rdepth) # find all branches @@ -644,19 +664,19 @@ class Rbyd: branches = {} bid = -1 while True: - done, bid, w, rbyd, rid, tags, path = self.btree_lookup( + done, bid, w, rbyd_, rid, tags, path = self.btree_lookup( f, block_size, bid+1, depth=depth) if done: break d_ = 0 leaf = None - for d, (bid, w, rbyd, rid, tags) in enumerate(path): + for d, (bid, w, rbyd_, rid, tags) in enumerate(path): if not tags: continue # map rbyd tree into B-tree space - rtree, rdepth = rbyd.tree() + rtree, rdepth = rbyd_.tree(rbyd=rbyd) # note we adjust our bid/rids to be left-leaning, # this allows a global order and make tree rendering quite @@ -665,8 +685,8 @@ class Rbyd: for branch in rtree: a_rid, a_tag = branch.a b_rid, b_tag = branch.b - _, _, _, a_w, _, _, _, _ = rbyd.lookup(a_rid, 0) - _, _, _, b_w, _, _, _, _ = rbyd.lookup(b_rid, 0) + _, _, _, a_w, _, _, _, _ = rbyd_.lookup(a_rid, 0) + _, _, _, b_w, _, _, _, _ = rbyd_.lookup(b_rid, 0) rtree_.add(TBranch( a=(a_rid-(a_w-1), a_tag), b=(b_rid-(b_w-1), b_tag), @@ -1257,11 +1277,12 @@ def dbg_fstruct(f, block_size, mdir, rid, tag, j, d, data, *, # precompute rbyd-trees if requested t_width = 0 - if args.get('tree'): + if args.get('tree') or args.get('rbyd'): tree, tdepth = btree.btree_tree( f, block_size, depth=args.get('struct_depth'), - inner=args.get('inner')) + inner=args.get('inner'), + rbyd=args.get('rbyd')) # precompute B-trees if requested elif args.get('btree'): @@ -1270,7 +1291,7 @@ def dbg_fstruct(f, block_size, mdir, rid, tag, j, d, data, *, depth=args.get('struct_depth'), inner=args.get('inner')) - if args.get('tree') or args.get('btree'): + if args.get('tree') or args.get('rbyd') or args.get('btree'): # map the tree into our block space tree_ = set() for branch in tree: @@ -1348,7 +1369,7 @@ def dbg_fstruct(f, block_size, mdir, rid, tag, j, d, data, *, tree = tree_ # common tree renderer - if args.get('tree') or args.get('btree'): + if args.get('tree') or args.get('rbyd') or args.get('btree'): # find the max depth from the tree t_depth = max((branch.d+1 for branch in tree), default=0) if t_depth > 0: @@ -1420,7 +1441,9 @@ def dbg_fstruct(f, block_size, mdir, rid, tag, j, d, data, *, else '', m_width, '', treerepr(bid, w, bd, rid, False, tag) - if args.get('tree') or args.get('btree') else '', + if args.get('tree') + or args.get('rbyd') + or args.get('btree') else '', '%*s ' % (2*w_width+1, '' if i != 0 else '%d-%d' % (bid-(w-1), bid) if w > 1 else bid if w > 0 @@ -1474,7 +1497,9 @@ def dbg_fstruct(f, block_size, mdir, rid, tag, j, d, data, *, '\x1b[0m' if color and notes else '', m_width, '', treerepr(bid, w, bd, rid, True, tag) - if args.get('tree') or args.get('btree') else '', + if args.get('tree') + or args.get('rbyd') + or args.get('btree') else '', '\x1b[31m' if color and notes else '', '%*s ' % (2*w_width+1, '%d-%d' % (bid-(w-1), bid) if w > 1 else bid if w > 0 @@ -2231,7 +2256,11 @@ if __name__ == "__main__": parser.add_argument( '-B', '--btree', action='store_true', - help="Show the underlying B-tree.") + help="Show the underlying B-trees.") + parser.add_argument( + '-R', '--rbyd', + action='store_true', + help="Show the full underlying rbyd trees.") parser.add_argument( '-i', '--inner', action='store_true', diff --git a/scripts/dbgmtree.py b/scripts/dbgmtree.py index cce4a8aa..0a967ab5 100755 --- a/scripts/dbgmtree.py +++ b/scripts/dbgmtree.py @@ -471,7 +471,8 @@ class Rbyd: yield rid, tag, w, j, d, data # create tree representation for debugging - def tree(self): + def tree(self, *, + rbyd=False): trunks = co.defaultdict(lambda: (-1, 0)) alts = co.defaultdict(lambda: {}) @@ -491,12 +492,30 @@ class Rbyd: else: alts[j_] |= {'nf': j__, 'c': c} - # treat unreachable alts as converging paths - for j_, alt in alts.items(): - if 'f' not in alt: - alt['f'] = alt['nf'] - elif 'nf' not in alt: - alt['nf'] = alt['f'] + if rbyd: + # treat unreachable alts as converging paths + for j_, alt in alts.items(): + if 'f' not in alt: + alt['f'] = alt['nf'] + elif 'nf' not in alt: + alt['nf'] = alt['f'] + + else: + # prune any alts with unreachable edges + pruned = {} + for j_, alt in alts.items(): + if 'f' not in alt: + pruned[j_] = alt['nf'] + elif 'nf' not in alt: + pruned[j_] = alt['f'] + for j_ in pruned.keys(): + del alts[j_] + + for j_, alt in alts.items(): + while alt['f'] in pruned: + alt['f'] = pruned[alt['f']] + while alt['nf'] in pruned: + alt['nf'] = pruned[alt['nf']] # find the trunk and depth of each alt def rec_trunk(j_): @@ -608,18 +627,19 @@ class Rbyd: # btree rbyd-tree generation for debugging def btree_tree(self, f, block_size, *, depth=None, - inner=False): + inner=False, + rbyd=False): # find the max depth of each layer to nicely align trees bdepths = {} bid = -1 while True: - done, bid, w, rbyd, rid, tags, path = self.btree_lookup( + done, bid, w, rbyd_, rid, tags, path = self.btree_lookup( f, block_size, bid+1, depth=depth) if done: break - for d, (bid, w, rbyd, rid, tags) in enumerate(path): - _, rdepth = rbyd.tree() + for d, (bid, w, rbyd_, rid, tags) in enumerate(path): + _, rdepth = rbyd_.tree(rbyd=rbyd) bdepths[d] = max(bdepths.get(d, 0), rdepth) # find all branches @@ -628,19 +648,19 @@ class Rbyd: branches = {} bid = -1 while True: - done, bid, w, rbyd, rid, tags, path = self.btree_lookup( + done, bid, w, rbyd_, rid, tags, path = self.btree_lookup( f, block_size, bid+1, depth=depth) if done: break d_ = 0 leaf = None - for d, (bid, w, rbyd, rid, tags) in enumerate(path): + for d, (bid, w, rbyd_, rid, tags) in enumerate(path): if not tags: continue # map rbyd tree into B-tree space - rtree, rdepth = rbyd.tree() + rtree, rdepth = rbyd_.tree(rbyd=rbyd) # note we adjust our bid/rids to be left-leaning, # this allows a global order and make tree rendering quite @@ -649,8 +669,8 @@ class Rbyd: for branch in rtree: a_rid, a_tag = branch.a b_rid, b_tag = branch.b - _, _, _, a_w, _, _, _, _ = rbyd.lookup(a_rid, 0) - _, _, _, b_w, _, _, _, _ = rbyd.lookup(b_rid, 0) + _, _, _, a_w, _, _, _, _ = rbyd_.lookup(a_rid, 0) + _, _, _, b_w, _, _, _, _ = rbyd_.lookup(b_rid, 0) rtree_.add(TBranch( a=(a_rid-(a_w-1), a_tag), b=(b_rid-(b_w-1), b_tag), @@ -919,7 +939,7 @@ def main(disk, mroots=None, *, # precompute rbyd-tree if requested t_width = 0 - if args.get('tree'): + if args.get('tree') or args.get('rbyd'): # compute mroot chain "tree", prefix our actual mtree with this tree = set() d_ = 0 @@ -931,7 +951,7 @@ def main(disk, mroots=None, *, break # compute the mroots rbyd-tree - rtree, rdepth = mroot_.tree() + rtree, rdepth = mroot_.tree(rbyd=args.get('rbyd')) # connect branch to our root if d > 0: @@ -977,7 +997,7 @@ def main(disk, mroots=None, *, # compute mdir's rbyd-tree if there is one if mdir: - rtree, rdepth = mdir.tree() + rtree, rdepth = mdir.tree(rbyd=args.get('rbyd')) # connect branch to our root root = min(rtree, @@ -1011,7 +1031,8 @@ def main(disk, mroots=None, *, tree_, tdepth = mtree.btree_tree( f, block_size, depth=args.get('depth', mdepth)-mdepth, - inner=args.get('inner')) + inner=args.get('inner'), + rbyd=args.get('rbyd')) # connect a branch to the root of the tree root = min(tree_, key=lambda branch: branch.d, default=None) @@ -1063,7 +1084,7 @@ def main(disk, mroots=None, *, blocks = frommdir(data) mdir_ = Rbyd.fetch(f, block_size, blocks) - rtree, rdepth = mdir_.tree() + rtree, rdepth = mdir_.tree(rbyd=args.get('rbyd')) mdepth_ = max(mdepth_, rdepth) # compute the rbyd-tree for each mdir @@ -1093,7 +1114,7 @@ def main(disk, mroots=None, *, blocks = frommdir(data) mdir_ = Rbyd.fetch(f, block_size, blocks) - rtree, rdepth = mdir_.tree() + rtree, rdepth = mdir_.tree(rbyd=args.get('rbyd')) # connect the root to the mtree branch = max( @@ -1230,7 +1251,8 @@ def main(disk, mroots=None, *, tree_, tdepth = mtree.btree_btree( f, block_size, depth=args.get('depth', mdepth)-mdepth, - inner=args.get('inner')) + inner=args.get('inner'), + rbyd=args.get('rbyd')) # connect a branch to the root of the tree root = min(tree_, key=lambda branch: branch.d, default=None) @@ -1310,7 +1332,7 @@ def main(disk, mroots=None, *, tree = tree_ # common tree renderer - if args.get('tree') or args.get('btree'): + if args.get('tree') or args.get('rbyd') or args.get('btree'): # find the max depth from the tree t_depth = max((branch.d+1 for branch in tree), default=0) if t_depth > 0: @@ -1375,7 +1397,9 @@ def main(disk, mroots=None, *, mdir.redund_blocks)) if i == 0 else '', treerepr(mbid-max(mw-1, 0), 0, md, 0, rid, tag) - if args.get('tree') or args.get('btree') else '', + if args.get('tree') + or args.get('rbyd') + or args.get('btree') else '', '%*s %-*s%s' % ( 2*w_width+1, '%d.%d-%d' % ( mbid//mleaf_weight, rid-(w-1), rid) @@ -1425,7 +1449,9 @@ def main(disk, mroots=None, *, if prbyd is None or rbyd != prbyd else '', treerepr(bid, w, bd, rid, 0, tag) - if args.get('tree') or args.get('btree') else '', + if args.get('tree') + or args.get('rbyd') + or args.get('btree') else '', 2*w_width+1, '' if i != 0 else '%d-%d' % ( (bid-(w-1))//mleaf_weight, @@ -1685,7 +1711,11 @@ if __name__ == "__main__": parser.add_argument( '-B', '--btree', action='store_true', - help="Show the underlying B-tree.") + help="Show the underlying B-trees.") + parser.add_argument( + '-R', '--rbyd', + action='store_true', + help="Show the full underlying rbyd trees.") parser.add_argument( '-i', '--inner', action='store_true', diff --git a/scripts/dbgrbyd.py b/scripts/dbgrbyd.py index c210ece1..f2e10f8f 100755 --- a/scripts/dbgrbyd.py +++ b/scripts/dbgrbyd.py @@ -676,7 +676,7 @@ def dbg_tree(data, block_size, rev, trunk, weight, *, # precompute tree t_width = 0 - if args.get('tree'): + if args.get('tree') or args.get('rbyd'): trunks = co.defaultdict(lambda: (-1, 0)) alts = co.defaultdict(lambda: {}) @@ -696,12 +696,30 @@ def dbg_tree(data, block_size, rev, trunk, weight, *, else: alts[j_] |= {'nf': j__, 'c': c} - # treat unreachable alts as converging paths - for j_, alt in alts.items(): - if 'f' not in alt: - alt['f'] = alt['nf'] - elif 'nf' not in alt: - alt['nf'] = alt['f'] + if args.get('rbyd'): + # treat unreachable alts as converging paths + for j_, alt in alts.items(): + if 'f' not in alt: + alt['f'] = alt['nf'] + elif 'nf' not in alt: + alt['nf'] = alt['f'] + + else: + # prune any alts with unreachable edges + pruned = {} + for j_, alt in alts.items(): + if 'f' not in alt: + pruned[j_] = alt['nf'] + elif 'nf' not in alt: + pruned[j_] = alt['f'] + for j_ in pruned.keys(): + del alts[j_] + + for j_, alt in alts.items(): + while alt['f'] in pruned: + alt['f'] = pruned[alt['f']] + while alt['nf'] in pruned: + alt['nf'] = pruned[alt['nf']] # find the trunk and depth of each alt def rec_trunk(j_): @@ -819,7 +837,8 @@ def dbg_tree(data, block_size, rev, trunk, weight, *, # show human-readable tag representation print('%08x: %s%*s %-*s %s' % ( j, - treerepr(rid, tag) if args.get('tree') else '', + treerepr(rid, tag) + if args.get('tree') or args.get('rbyd') else '', 2*w_width+1, '%d-%d' % (rid-(w-1), rid) if w > 1 else rid if w > 0 or i == 0 else '', @@ -1070,6 +1089,10 @@ if __name__ == "__main__": '-t', '--tree', action='store_true', help="Show the rbyd tree.") + parser.add_argument( + '-R', '--rbyd', + action='store_true', + help="Show the full rbyd tree.") parser.add_argument( '-j', '--jumps', action='store_true',