您的位置:首页 > 其它

区间树作为范围锁的应用

2017-02-09 10:18 471 查看
在多线程访问数据对象时,往往需要加锁来保证互斥,而如果对整个对象加锁,则即使访问该对象不同区段的请求也不能并发,而基于区间树我们可以很方便的实现一个细颗粒度的区间锁。

内核区间树说明: http://tomoyo.osdn.jp/cgi-bin/lxr/source/Documentation/rbtree.txt
区间树(interval
tree)是一种扩展的红黑树。
参考:“Introduction to Algorithms” Cormen, Leiserson, Rivest and Stein
经典的红黑树只有一个 key,不能直接用来存储区间范围如 [lo : hi],也不能快速的判断一个新的范围 [lo : hi] 是否有重叠,以便于查找新的 [lo : hi] 是否有一个精确的匹配。

struct interval_tree_node {
int start;
int last;
int __subtree_last;
rb_node rb;
}
/* 查找与范围 [start,last] 重叠的第一个区段
cond1 :node->start <= last
cond2 :node->last >= start
如果一个区段满足以上两个条件,则其与范围 [start,last] 是相交的。 */
struct interval_tree_node * interval_tree_first_match(struct rb_root *root, unsigned long start, unsigned long last) {
struct interval_tree_node *node;
if (!root->rb_node)
return NULL;
node = rb_entry(root->rb_node, struct interval_tree_node, rb);
while (true) {
if (node->rb.rb_left) {
struct interval_tree_node *left = rb_entry(node->rb.rb_left, struct interval_tree_node, rb);
if (left->__subtree_last >= start) {
/* 查找最左边的满足 cond2 的区段 */
node = left;
continue;
}
}
if (node->start <= last) { /* Cond1 */
if (node->last >= start) /* Cond2 */
return node; /* node is leftmost match */
if (node->rb.rb_right) {
node = rb_entry(node->rb.rb_right, struct interval_tree_node, rb);
if (node->__subtree_last >= start)
continue;
}
}
return NULL; /* No match */
}
} 使用该接口我们在得到一个新的读写范围时,就可以查找其与正在执行的读写范围是否重叠,从而可以达到并发的访问不同区段的效果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息