Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
be7fb4c1
提交
be7fb4c1
6月 24, 2011
创建
作者:
Frans Kaashoek
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Unsigned keys
Key/value pairs
上级
7559ced5
隐藏空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
70 行增加
和
36 行删除
+70
-36
bonsai.c
bonsai.c
+70
-36
没有找到文件。
bonsai.c
浏览文件 @
be7fb4c1
...
...
@@ -23,19 +23,18 @@
typedef
struct
node
node_t
;
struct
node
{
int
key
;
int
val
;
struct
kv
kv
;
int
size
;
node_t
*
r
,
*
l
;
}
__attribute__
((
aligned
(
CACHELINE
)));
static
node_t
*
alloc_node
(
int
key
,
node_t
*
l
,
node_t
*
r
)
alloc_node
(
struct
kv
*
kv
,
node_t
*
l
,
node_t
*
r
)
{
node_t
*
n
=
kmalloc
(
sizeof
(
node_t
));
if
(
n
==
0
)
return
0
;
n
->
k
ey
=
key
;
n
->
k
v
=
*
kv
;
n
->
size
=
SIZE
(
l
)
+
SIZE
(
r
)
+
1
;
n
->
l
=
l
;
n
->
r
=
r
;
...
...
@@ -46,7 +45,7 @@ static void
free_node
(
void
*
p
)
{
// printf("free_node: 0x%lx\n", (long) n);
kfree
(
p
);
k
m
free
(
p
);
}
static
void
...
...
@@ -72,29 +71,45 @@ tree_print(node_t *n, int depth)
if
(
n
->
l
!=
0
)
tree_print
(
n
->
l
,
depth
+
1
);
tree_printspace
(
depth
*
2
);
cprintf
(
"0x%lx: %d sz %d l 0x%lx 0x%lx
\n
"
,
(
long
)
n
,
n
->
key
,
n
->
size
,
cprintf
(
"0x%lx: %d sz %d l 0x%lx 0x%lx
\n
"
,
(
long
)
n
,
n
->
k
v
.
k
ey
,
n
->
size
,
(
long
)
n
->
l
,
(
long
)
n
->
r
);
if
(
n
->
r
!=
0
)
tree_print
(
n
->
r
,
depth
+
1
);
}
node_t
*
tree_
contains
(
node_t
*
n
,
int
key
)
struct
kv
*
tree_
find
(
node_t
*
n
,
int
key
)
{
if
(
n
==
0
)
return
0
;
if
(
n
->
key
==
key
)
return
n
;
if
(
n
->
kv
.
key
==
key
)
return
&
n
->
kv
;
if
(
key
<
n
->
kv
.
key
)
return
tree_find
(
n
->
l
,
key
);
else
return
tree_find
(
n
->
r
,
key
);
}
struct
kv
*
tree_find_gt
(
node_t
*
n
,
int
key
)
{
struct
kv
*
r
=
0
;
if
(
n
==
0
)
return
0
;
if
(
key
<
n
->
key
)
return
tree_contains
(
n
->
l
,
key
);
else
return
tree_contains
(
n
->
r
,
key
);
if
(
n
->
kv
.
key
>
key
)
{
r
=
tree_find_gt
(
n
->
l
,
key
);
if
(
r
==
0
)
r
=
&
n
->
kv
;
}
else
{
r
=
tree_find_gt
(
n
->
r
,
key
);
}
return
r
;
}
static
node_t
*
tree_balance
(
node_t
*
n
,
node_t
*
l
,
node_t
*
r
,
int
,
int
);
static
node_t
*
tree_single_left
(
int
key
,
node_t
*
l
,
node_t
*
r
)
tree_single_left
(
struct
kv
*
kv
,
node_t
*
l
,
node_t
*
r
)
{
node_t
*
t
=
alloc_node
(
r
->
key
,
alloc_node
(
key
,
l
,
r
->
l
),
r
->
r
);
node_t
*
t
=
alloc_node
(
&
r
->
kv
,
alloc_node
(
kv
,
l
,
r
->
l
),
r
->
r
);
rcu_free_node
(
r
);
return
t
;
}
...
...
@@ -102,10 +117,10 @@ tree_single_left(int key, node_t *l, node_t *r)
static
node_t
*
tree_double_left
(
node_t
*
n
,
node_t
*
l
,
node_t
*
r
)
{
node_t
*
tl
=
alloc_node
(
n
->
key
,
l
,
r
->
l
->
l
);
node_t
*
tl
=
alloc_node
(
&
n
->
kv
,
l
,
r
->
l
->
l
);
// node_t *tr = alloc_node(r->key, r->l->r, r->r);
node_t
*
tr
=
tree_balance
(
r
,
r
->
l
->
r
,
r
->
r
,
0
,
0
);
node_t
*
t
=
alloc_node
(
r
->
l
->
key
,
tl
,
tr
);
node_t
*
t
=
alloc_node
(
&
r
->
l
->
kv
,
tl
,
tr
);
rcu_free_node
(
r
->
l
);
// rcu_free_node(r);
...
...
@@ -113,9 +128,9 @@ tree_double_left(node_t *n, node_t *l, node_t *r)
}
static
node_t
*
tree_single_right
(
int
key
,
node_t
*
l
,
node_t
*
r
)
tree_single_right
(
struct
kv
*
kv
,
node_t
*
l
,
node_t
*
r
)
{
node_t
*
t
=
alloc_node
(
l
->
key
,
l
->
l
,
alloc_node
(
key
,
l
->
r
,
r
));
node_t
*
t
=
alloc_node
(
&
l
->
kv
,
l
->
l
,
alloc_node
(
kv
,
l
->
r
,
r
));
rcu_free_node
(
l
);
return
t
;
}
...
...
@@ -125,8 +140,8 @@ tree_double_right(node_t *n, node_t *l, node_t *r)
{
// node_t *tl = alloc_node(l->key, l->l, l->r->l);
node_t
*
tl
=
tree_balance
(
l
,
l
->
l
,
l
->
r
->
l
,
0
,
0
);
node_t
*
tr
=
alloc_node
(
n
->
key
,
l
->
r
->
r
,
r
);
node_t
*
t
=
alloc_node
(
l
->
r
->
key
,
tl
,
tr
);
node_t
*
tr
=
alloc_node
(
&
n
->
kv
,
l
->
r
->
r
,
r
);
node_t
*
t
=
alloc_node
(
&
l
->
r
->
kv
,
tl
,
tr
);
rcu_free_node
(
l
->
r
);
// rcu_free_node(l);
...
...
@@ -147,7 +162,7 @@ tree_node(node_t *n, node_t *l, node_t *r, int leftreplace, int inplace)
n
->
size
=
1
+
SIZE
(
l
)
+
SIZE
(
r
);
t
=
n
;
}
else
{
t
=
alloc_node
(
n
->
key
,
l
,
r
);
t
=
alloc_node
(
&
n
->
kv
,
l
,
r
);
rcu_free_node
(
n
);
}
return
t
;
...
...
@@ -168,13 +183,13 @@ tree_balance(node_t *n, node_t *l, node_t *r, int leftreplace, int inplace)
}
else
if
(
rn
>
WEIGHT
*
ln
)
{
int
rln
=
SIZE
(
r
->
l
);
int
rrn
=
SIZE
(
r
->
r
);
if
(
rln
<
rrn
)
t
=
tree_single_left
(
n
->
key
,
l
,
r
);
if
(
rln
<
rrn
)
t
=
tree_single_left
(
&
n
->
kv
,
l
,
r
);
else
t
=
tree_double_left
(
n
,
l
,
r
);
rcu_free_node
(
n
);
}
else
if
(
ln
>
WEIGHT
*
rn
)
{
int
lln
=
SIZE
(
l
->
l
);
int
lrn
=
SIZE
(
l
->
r
);
if
(
lrn
<
lln
)
t
=
tree_single_right
(
n
->
key
,
l
,
r
);
if
(
lrn
<
lln
)
t
=
tree_single_right
(
&
n
->
kv
,
l
,
r
);
else
t
=
tree_double_right
(
n
,
l
,
r
);
rcu_free_node
(
n
);
}
else
{
...
...
@@ -184,17 +199,17 @@ tree_balance(node_t *n, node_t *l, node_t *r, int leftreplace, int inplace)
}
node_t
*
tree_insert
(
node_t
*
n
,
int
key
)
tree_insert
(
node_t
*
n
,
struct
kv
*
kv
)
{
node_t
*
t
;
if
(
n
==
0
)
{
t
=
alloc_node
(
k
ey
,
0
,
0
);
}
else
if
(
k
ey
==
n
->
key
)
{
t
=
alloc_node
(
k
v
,
0
,
0
);
}
else
if
(
k
v
->
key
==
n
->
kv
.
key
)
{
t
=
n
;
}
else
if
(
k
ey
<
n
->
key
)
{
t
=
tree_balance
(
n
,
tree_insert
(
n
->
l
,
k
ey
),
n
->
r
,
1
,
1
);
}
else
if
(
k
v
->
key
<
n
->
kv
.
key
)
{
t
=
tree_balance
(
n
,
tree_insert
(
n
->
l
,
k
v
),
n
->
r
,
1
,
1
);
}
else
{
t
=
tree_balance
(
n
,
n
->
l
,
tree_insert
(
n
->
r
,
k
ey
),
0
,
1
);
t
=
tree_balance
(
n
,
n
->
l
,
tree_insert
(
n
->
r
,
k
v
),
0
,
1
);
}
return
t
;
}
...
...
@@ -243,9 +258,9 @@ tree_remove(node_t *n, int key)
node_t
*
t
;
if
(
n
==
0
)
t
=
0
;
else
if
(
key
<
n
->
key
)
{
else
if
(
key
<
n
->
k
v
.
k
ey
)
{
t
=
tree_balance
(
n
,
tree_remove
(
n
->
l
,
key
),
n
->
r
,
1
,
1
);
}
else
if
(
key
>
n
->
key
)
{
}
else
if
(
key
>
n
->
k
v
.
k
ey
)
{
t
=
tree_balance
(
n
,
n
->
l
,
tree_remove
(
n
->
r
,
key
),
0
,
1
);
}
else
{
t
=
tree_delprime
(
n
->
l
,
n
->
r
);
...
...
@@ -254,6 +269,23 @@ tree_remove(node_t *n, int key)
return
t
;
}
int
tree_foreach
(
node_t
*
n
,
int
(
*
cb
)(
struct
kv
*
,
void
*
),
void
*
st
)
{
if
(
n
==
0
)
return
1
;
if
(
!
tree_foreach
(
n
->
l
,
cb
,
st
))
return
0
;
if
(
!
cb
(
&
n
->
kv
,
st
))
return
0
;
if
(
!
tree_foreach
(
n
->
r
,
cb
,
st
))
return
0
;
return
1
;
}
#define TEST
#ifdef TEST
#define NINSERT 1000
...
...
@@ -271,10 +303,10 @@ tree_check(node_t *n)
if
(
n
->
l
!=
0
)
t
=
tree_check
(
n
->
l
);
// in order?
if
(
n
->
l
!=
0
&&
n
->
l
->
k
ey
>
n
->
key
)
{
if
(
n
->
l
!=
0
&&
n
->
l
->
k
v
.
key
>
n
->
kv
.
key
)
{
panic
(
"out of order l"
);
}
if
(
n
->
r
!=
0
&&
n
->
r
->
k
ey
<
n
->
key
)
{
if
(
n
->
r
!=
0
&&
n
->
r
->
k
v
.
key
<
n
->
kv
.
key
)
{
panic
(
"out of order r"
);
}
...
...
@@ -299,14 +331,14 @@ void
rcu_tree_check
(
int
t
,
int
sz
)
{
int
i
;
node_t
*
n
;
struct
kv
*
kv
;
// are all keys in the tree?
for
(
i
=
0
;
i
<
sz
;
i
++
)
{
if
(
insert_values
[
i
]
==
0
)
continue
;
n
=
tree_contains
(
root
,
insert_values
[
i
]);
if
(
n
==
0
)
{
kv
=
tree_find
(
root
,
insert_values
[
i
]);
if
(
kv
==
0
)
{
cprintf
(
"tree_check %d (%d) fails
\n
"
,
insert_values
[
i
],
i
);
panic
(
"key missing"
);
}
...
...
@@ -328,11 +360,13 @@ tree_test(void)
{
int
i
;
for
(
i
=
0
;
i
<
NINSERT
;
i
++
)
{
struct
kv
kv
;
long
d
=
draw
(
0
);
kv
.
key
=
d
;
insert_values
[
i
]
=
d
;
// tree_print(root, 0);
// printf("add(%ld,%ld) nfree %d\n", d, d, tree_nfree);
root
=
tree_insert
(
root
,
d
);
root
=
tree_insert
(
root
,
&
kv
);
}
rcu_tree_check
(
0
,
NINSERT
);
cprintf
(
"tree_test ok1
\n
"
);
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论