/* Make sure the tree is high enough. */ if (max > maxindex) { int error = radix_tree_extend(root, gfp, max, shift); /* 实现radix tree纵向的生长 */ if (error < 0) return error; shift = error; child = rcu_dereference_raw(root->xa_head); }
while (shift > 0) { shift -= RADIX_TREE_MAP_SHIFT; if (child == NULL) { /* Have to add a child node. */ child = radix_tree_node_alloc(gfp, node, root, shift, offset, 0, 0); /* 结点分配 */ if (!child) return -ENOMEM; rcu_assign_pointer(*slot, node_to_entry(child)); if (node) node->count++; } elseif (!radix_tree_is_internal_node(child)) /* 判点是否为内部节点 */ break;
/* Go a level down */ node = entry_to_node(child); offset = radix_tree_descend(node, &child, index); /* 节点查找 */ slot = &node->slots[offset]; }
if (nodep) *nodep = node; if (slotp) *slotp = slot; return0; }
两个函数之间,不管是函数名称还是执行流程,都有一些比较类似的地方,在条件符合时,两者可以互相替代
一些高版本的 kernel 开始使用 XArray 来替代原来的基数树:
linux-2.6.34 的 address_space->i_pages 使用基数树
1 2 3 4
structaddress_space { structinode *host;/* owner: inode, block_device */ structradix_tree_rootpage_tree;/* radix tree of all pages */ ......