ast_visitor::visitor_result dotfile_visitor::visit(abstract_node *node) { if (m_connectTo) { if (m_numconnected == 0) fprintf(m_file, "\tptr%p -> { ", m_connectTo); fprintf(m_file, "ptr%p ", node); ++m_numconnected; } else { m_connectTo = node; m_numconnected = 0; walk_node(node, this, false); if (m_numconnected > 0) { fputs("};\n", m_file); } m_connectTo = nullptr; walk_node(node, this, false); } return ast_visitor::stop; }
int dm_btree_walk(struct dm_btree_info *info, dm_block_t root, int (*fn)(void *context, uint64_t *keys, void *leaf), void *context) { BUG_ON(info->levels > 1); return walk_node(info, root, fn, context); }
/* * FIXME: We shouldn't use a recursive algorithm when we have limited stack * space. Also this only works for single level trees. */ static int walk_node(struct dm_btree_info *info, dm_block_t block, int (*fn)(void *context, uint64_t *keys, void *leaf), void *context) { int r; unsigned i, nr; struct dm_block *node; struct btree_node *n; uint64_t keys; r = bn_read_lock(info, block, &node); if (r) return r; n = dm_block_data(node); nr = le32_to_cpu(n->header.nr_entries); for (i = 0; i < nr; i++) { if (le32_to_cpu(n->header.flags) & INTERNAL_NODE) { r = walk_node(info, value64(n, i), fn, context); if (r) goto out; } else { keys = le64_to_cpu(*key_ptr(n, i)); r = fn(context, &keys, value_ptr(n, i)); if (r) goto out; } } out: dm_tm_unlock(info->tm, node); return r; }