idr and radix-tree

本文深入解析了Radix Tree数据结构的实现原理与应用细节,包括节点结构、内部节点判断、子节点计数以及标签使用等内容,并通过具体示例帮助读者更好地理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

idr用到了radix-tree。如果只有一个节点数据结构如下:


crash> idr  ffff880b4d726dd0
struct idr {
  idr_rt = {
    gfp_mask = 0x6000000,
    rnode = 0xffff880bd74d7909
  },
  idr_next = 0x0
}
crash> radix_tree_node  ffff880bd74d7908
struct radix_tree_node {
  shift = 0x0,
  offset = 0x0,
  count = 0x1,
  exceptional = 0x0,
  parent = 0x0,
  root = 0xffff880b4d726dd0,
  {
    private_list = {
      next = 0xffff880bd74d7920,
      prev = 0xffff880bd74d7920
    },
    callback_head = {
      next = 0xffff880bd74d7920,
      func = 0xffff880bd74d7920
    }
  },
  slots = {0x0, 0xffff880b4d726000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
  tags = {{0xfffffffffffffffd}, {0x0}, {0x0}}
}


这里有几点需要注意。第一,如果node末位是1,说明不是叶子节点。dump的时候一定要把1去掉。


#define RADIX_TREE_ENTRY_MASK           3UL
#define RADIX_TREE_INTERNAL_NODE        1UL

static inline bool radix_tree_is_internal_node(void *ptr)
{
        return ((unsigned long)ptr & RADIX_TREE_ENTRY_MASK) ==
                                RADIX_TREE_INTERNAL_NODE;
}

第二,count就是孩子的个数,包括中间节点和叶子节点。
第三,tags就是bitmap,是叶子节点置为0。否则为1。


再举个例子63个节点的例子:


crash> radix_tree_node  ffff880bc1dc16d0
struct radix_tree_node {
  shift = 0x0,
  offset = 0x0,
  count = 0x3f,
  exceptional = 0x0,
  parent = 0x0,
  root = 0xffff880b5354add0,
  {
    private_list = {
      next = 0xffff880bc1dc16e8,
      prev = 0xffff880bc1dc16e8
    },
    callback_head = {
      next = 0xffff880bc1dc16e8,
      func = 0xffff880bc1dc16e8
    }
  },
  slots = {0x0, 0xffff880b5354aa00, 0xffff880b5354b800, 0xffff880b5354ba00, 0xffff880b5354b600, 0xffff880b53548600, 0xffff880b5354b200, 0xffff880b53549a00, 0xffff880b5354a800, 0xffff880b53548400, 0xffff880b5354bc00, 0xffff880b5354b400, 0xffff880b5354be00, 0xffff880b5354ae00, 0xffff880b53549400, 0xffff880b53549e00, 0xffff880b53549200, 0xffff880b5354b000, 0xffff880b53549c00, 0xffff880b5354a400, 0xffff880b53548800, 0xffff880b53549800, 0xffff880b5354a000, 0xffff880b53549000, 0xffff880b53548c00, 0xffff880b53548200, 0xffff880b5354a200, 0xffff880b53548a00, 0xffff880b9a415600, 0xffff880b9a417600, 0xffff880b9a415800, 0xffff880b9a417200, 0xffff880b9a417800, 0xffff880b9a414800, 0xffff880b9a414200, 0xffff880b9a414000, 0xffff880b9a414e00, 0xffff880b9a415000, 0xffff880b9a417400, 0xffff880b9a414600, 0xffff880b9a416400, 0xffff880b9a414c00, 0xffff880b9a414a00, 0xffff880b9a415200, 0xffff880b5e3f7c00, 0xffff880b5e3f5400, 0xffff880b5e3f4400, 0xffff880b5e3f6e00, 0xffff880b5e3f5e00, 0xffff880b5e3f5c00, 0xffff880b5e3f7a00, 0xffff880b5e3f4c00, 0xffff880b5e3f6200, 0xffff880b5e3f5800, 0xffff880b5e3f6000, 0xffff880b5e3f7200, 0xffff880b5e3f6800, 0xffff880b5e3f5a00, 0xffff880b5e3f6400, 0xffff880b5e3f5000, 0xffff880b5e3f6c00, 0xffff880b5e3f4800, 0xffff880b5c46e000, 0xffff880b5c46ea00},
  tags = {{0x1}, {0x0}, {0x0}}
}

那么offset是什么的?首先创建有200个节点的树。


crash> radix_tree_node  ffff880bd74d76c0
struct radix_tree_node {
  shift = 0x6,
  offset = 0x0,
  count = 0x4,
  exceptional = 0x0,
  parent = 0x0,
  root = 0xffff880b4d7247d0,
  {
    private_list = {
      next = 0xffff880bd74d76d8,
      prev = 0xffff880bd74d76d8
    },
    callback_head = {
      next = 0xffff880bd74d76d8,
      func = 0xffff880bd74d76d8
    }
  },
  slots = {0xffff880bd74d7b51, 0xffff880bd74d7479, 0xffff880bd74d6da1, 0xffff880bd74d6fe9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
  tags = {{0xfffffffffffffff9}, {0x0}, {0x0}}
}
crash> radix_tree_node.offset  0xffff880bd74d7b50
  offset = 0x0
crash> radix_tree_node.offset  0xffff880bd74d7478
  offset = 0x1
crash> radix_tree_node.offset  0xffff880bd74d6da0
  offset = 0x2
crash> radix_tree_node.offset  0xffff880bd74d6fe8
  offset = 0x3

应该可以理解为孩子的编号,从0开始。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值