Linux数据结构之radix-tree

本文深入探讨了Linux文件系统和句柄表中使用的Radix Tree数据结构,这是一种高效的ID与数据映射机制。介绍了如何进行初始化、预分配、插入、删除、替换节点、查询遍历、安全访问以及标签操作。Radix Tree结合RCU机制确保了数据的安全性和高效性。
摘要由CSDN通过智能技术生成

引言

radix-tree在linux文件系统和句柄表使用的一种高效数据结构。它通过类似B+树的原理建立ID与数据指针的映射,并且通过rcu机制提供数据安全性和高效性。

1 使用介绍

1.1 定义变量

struct radix_tree_root g_rdtree_root;

注:radix_tree_root也可以嵌套到结构体中

1.2 初始化

INIT_RADIX_TREE(&g_rdtree_root, GFP_KERNEL);

1.3 预分配

//预分配空间
int err = radix_tree_preload(GFP_KERNEL); //成功后关闭内核抢占
if (err) {
    goto fail;
}
# 略略略... ...
radix_tree_preload_end(); //打开内核抢占

1.4 插入节点

int err = radix_tree_insert(&g_rdtree_root, index, xxx_ptr);

1.5 删除节点

struct xxx_st* xxx_ptr = radix_tree_delete(&g_rdtree_root, index);

1.6 替换节点

void __rcu **slot = radix_tree_lookup_slot(&g_rdtree_root, index);
if (slot) {
    radix_tree_replace_slot(&g_rdtree_root, slot, xxx_new_ptr);
}

1.7 查询遍历

//查询单个节点
struct xxx_st* xxx_ptr = radix_tree_lookup(&g_rdtree_root, index);
//查询连续节点
struct xxx_st* xxx_ptrs[16];
count = radix_tree_gang_lookup(&g_rdtree_root, (void **)xxx_ptrs, index, 16);
//从begin_index往后遍历
struct radix_tree_iter iter;
radix_tree_for_each_slot(slot, &g_rdtree_root, &iter, begin_index) {
    # 略略略... ...
}

1.8 安全访问

  • 安全读
rcu_read_lock();
void __rcu **slot = radix_tree_lookup_slot(&g_rdtree_root, index);
if (slot) {
    struct xxx_st* xxx_tmp = rcu_dereference(*slot);
    # 略略略... ...
}
rcu_read_unlock();
  • 安全写
spin_lock(&g_rdtree_lock);
void __rcu **slot = radix_tree_lookup_slot(&g_rdtree_root, index);
struct xxx_st* xxx_old_ptr = slot ? radix_tree_deref_slot_protected(slot, &g_rdtree_lock) : NULL;
if (slot) {
    radix_tree_replace_slot(&g_rdtree_root, slot, xxx_new_ptr);
} else {
    radix_tree_insert(&g_rdtree_root, index, xxx_new_ptr);
}
spin_unlock(&g_rdtree_lock);

if (xxx_old_ptr) {
    synchronize_rcu();
    kfree(xxx_old_ptr);
}

1.9 标签操作

//设置tag
struct xxx_st* xxx_ptr = radix_tree_tag_set(&g_rdtree_root, index, tag);
//清除tag
struct xxx_st* xxx_ptr = radix_tree_tag_clear(&g_rdtree_root, index, tag);
//判断index是否标记, 存在返回1、否则返回0
int tagged = radix_tree_tag_get(&g_rdtree_root, index, tag);
//判断是否存在tag的index, 存在返回非0、否则返回0
int tagged = radix_tree_tagged(&g_rdtree_root, tag);
//查询tag
struct xxx_st* xxx_ptrs[16];
int size = radix_tree_gang_lookup_tag(&g_rdtree_root, (void **)xxx_ptrs, first_index, 16, tag);

注:tag必须小于RADIX_TREE_MAX_TAGS

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值