Linux Kernel(2.6)の実装に関するメモ書き

Radix Tree


Rev.5を表示中。最新版はこちら

1. 概要

Tree検索を行うRadix TreeのLinuxでの実装メモ。

Radix Treeの機能はlib/radix-tree.cで提供される。実際の使用例としては、ページキャッシュのページを管理するのにRadix Treeを使っている。

2. データ構造

LinuxでのRadixツリーの構造を図1に示す。


図1 Radix Treeのデータ構造

2.1 Treeの管理データ

Radix Treeの管理の大元のデータとしてstruct radix_tree_rootがある。このデータはRadix Tree関連関数でどのTreeに対して操作を行うのか指定するのに使われる。

このデータのrnodeがルートノード(Treeトップのノード)を指している。heightはTreeの高さを表しており、例えばheight=1だと、ルートノードのみの1段のTreeであることを意味する。

2.2 Treeのノード

Treeの各ノードはstruct radix_tree_nodeが使われる。

この構造体にはslots[]配列があり、子ノードへのポインタを保持している。末端のノードの場合はslots[]は検索対象のオブジェクト(item)へのポインタを格納している(*1)。子ノードやitemが無い場合はslots[]の該当要素にはNULLが格納されている。現状slots配列は64エントリ存在し、Radix Treeは64分木を構成することになる。

countフィールドは、そのノードに子がいくついるかを示すカウンタ。つまり、slots[]に有効なポインタがいくつ格納しているかを表している。

(*1) ページキャッシュのRadix Treeの場合は、itemはstruct pageになる。

2.3 検索キー

Tree検索時に使用する検索キー(index)はLinuxではunsigned long(32bit)値に限定されている。

検索キーは図1に示すようにRADIX_TREE_MAP_SHIFT(6) bit毎に区切られて扱われる。検索キーの区切られた各部分の値がTree各段のノードのslots[]のインデクスとなる(*2)。検索時は各フィールドの値を参照してTreeを下っていくことで、検索キーに対応するitemを取得できる。

[補足]

6bit区切りだと端数がでるので、検索キーの上位は2bitのみになる。このため、図1では1段目でも64分岐するように描いているが、実際には4分岐しかしない。

ページキャッシュのRadix Treeではページ(struct page)を登録する際、ファイル先頭からのページオフセットをindexにしている。このため、アクセスするデータのページオフセットから高速にページデータを取得できる。

(*2) 6bitで取り得る値は0〜63なので、slots[]は64エントリとなり64分木となる。

3. Treeの拡張

図1ではRadix Treeの高さが固定であるような描き方になっているが、実際にはRadix Treeの高さはエントリを追加した時に必要に応じて拡張されていくようになっている。

例えば、登録エントリの検索キーが0〜63の範囲に収まっている時は、Treeは1段しかない(図2)。

図2 1段のRadix Tree

ここで、検索キーが2000のエントリがRadix Treeに追加されると、Treeが2段必要になる。このため、Treeが1段拡張される(図3)。このように、Treeに登録されているエントリの検索キーの範囲に応じてTreeの高さが拡張される。


図3 2段に拡張されたRadix Tree

4. タグ



関連関数

radix_tree_insert(*root, index, *item)
Treeへのエントリ登録
rootで指定したTreeにindexを検索キーとしてitemを登録する。

radix_tree_lookup(struct radix_tree_root *root, unsigned long index)
エントリの検索
rootで指定したTreeをindexで検索して、itemが存在すれば返す。

最終更新 2007/06/06 18:12:21 - kztomita
(2007/06/06 16:57:27 作成)
添付ファイル
radix.png - kztomita
expand1.png - kztomita
expand2.png - kztomita
bitmaps.png - kztomita
bitmap_usage.png - kztomita


リンク
最近更新したページ
検索