浅析Linux Radix-Tree

来源:互联网 发布:制作条形码的软件 编辑:程序博客网 时间:2024/05/20 05:58

浅析Linux Radix-Tree

Radix-Tree在Linux内核中有着广泛的应用,如page cache,swap cache通过Radix-Tree来管理虚拟地址到page cache之间的映射关系.

Radix-Tree的特点是可以通过整数作为index来找到对应的数据结构,而无需像数组一样需要事先定义好整数index的范围,也就是Index可以是离散的,查找速度相较数组也不会逊色太多,在空间和时间上取得一个均衡.

如下内容主要基于Linux-3.18.

主要数据结构及说明

数据结构

struct radix_tree_node {    unsigned int    path;   /* Offset in parent & height from the bottom */    unsigned int    count;/*current used slot in this node*/    union {        struct {            /* Used when ascending tree */            struct radix_tree_node *parent;            /* For tree user */            void *private_data;        };        /* Used when freeing node */        struct rcu_head rcu_head;    };    /* For tree user */    struct list_head private_list;    void __rcu  *slots[RADIX_TREE_MAP_SIZE];/*contain leaf data or next node*/    unsigned long     tags[RADIX_TREE_MAX_TAGS[RADIX_TREE_TAG_LONGS];/*Tags are for tree iteration*/};
  • path:主要是当前node的height和当前node在parent node里面的offset的bit mix
  • rnode:这里有一个flag RADIX_TREE_INDIRECT_PTR,大部分case是置位的,但是在Radix-Tree只有一个Index=0有插入数据时,rnode会直接指向该数据item,并且RADIX_TREE_INDIRECT_PTR不会置位
  • tags:这里主要用来标记Node的某一个slot是否有对应的数据,主要是遍历tree时会用到
struct radix_tree_root {    unsigned int        height;/*current height of the tree*/    gfp_t           gfp_mask;    struct radix_tree_node  __rcu *rnode;/*point to the current highest node(RADIX_TREE_INDIRECT_PTR is set) or point to the data item(RADIX_TREE_INDIRECT_PTR is not set)*/};

-gfp_mask:这里低__GFP_BITS_SHIFT 是存放新的node申请内存用的flag,高位时存root 的tag

Linux实例

在Linux中,Radix-Tree能够表示的范围是unsigned long,如果CONFIG_BASE_SMALL 没有enable的话,每一层表示的范围是2^6,这样在32位机器最坏的状况下,Radix-Tree的Height最大会到6层,也意味着最大会找6次才能命中.

主要API

-定义一个Radix-Tree

#define RADIX_TREE(name, mask) \    struct radix_tree_root name = RADIX_TREE_INIT(mask)

-在Radix-Tree建立Index与Data的映射关系

int radix_tree_insert(struct radix_tree_root *root, unsigned long Index, void * Data);

-在Radix-Tree中移除Index与Data的映射关系

void *radix_tree_delete(struct radix_tree_root *root, unsigned long Index);

-在Radix-Tree中通过Index查找其映射的Data

void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index);

下面是32机器上在一个新的Radix-Tree树上,在index为(1UL<<13)处插入数据A之后的图例

这里写图片描述


原创粉丝点击