@@ -9,67 +9,74 @@ red-black tree or something else.
9
9
import core:: option:: { some, none} ;
10
10
import option = core:: option;
11
11
12
- export treemap;
13
12
export treemap;
14
13
export insert;
15
14
export find;
16
15
export traverse;
17
16
18
- type treemap < K , V > = @mut tree_node < K , V > ;
17
+ type treemap < K , V > = @mut tree_edge < K , V > ;
18
+
19
+ type tree_edge < K , V > = option < @tree_node < K , V > > ;
19
20
20
- enum tree_node < K , V > { empty, node( @K , @V , treemap < K , V > , treemap < K , V > ) }
21
+ enum tree_node < K , V > = {
22
+ key: K ,
23
+ mut value: V ,
24
+ mut left: tree_edge<K , V >,
25
+ mut right: tree_edge<K , V >
26
+ } ;
21
27
22
28
#[ doc = "Create a treemap" ]
23
- fn treemap < K , V > ( ) -> treemap < K , V > { @mut empty }
29
+ fn treemap < K , V > ( ) -> treemap < K , V > { @mut none }
24
30
25
31
#[ doc = "Insert a value into the map" ]
26
- fn insert < K : copy , V : copy > ( m : treemap < K , V > , k : K , v : V ) {
27
- alt m {
28
- @empty { * m = node ( @k, @v, @mut empty, @mut empty) ; }
29
- @node ( @kk, _, _, _) {
30
-
31
- // We have to name left and right individually, because
32
- // otherwise the alias checker complains.
33
- if k < kk {
34
- alt check m { @node( _, _, left, _) { insert ( left, k, v) ; } }
32
+ fn insert < K : copy , V : copy > ( m : & mut tree_edge < K , V > , k : K , v : V ) {
33
+ alt copy * m {
34
+ none {
35
+ * m = some ( @tree_node ( { key: k,
36
+ mut value: v,
37
+ mut left: none,
38
+ mut right: none} ) ) ;
39
+ ret;
40
+ }
41
+ some ( node) {
42
+ if k == node. key {
43
+ node. value = v;
44
+ } else if k < node. key {
45
+ insert ( & mut node. left , k, v) ;
35
46
} else {
36
- alt check m {
37
- @node( _, _, _, right) { insert ( right, k, v) ; }
38
- }
47
+ insert ( & mut node. right , k, v) ;
39
48
}
40
49
}
41
- }
50
+ } ;
42
51
}
43
52
44
53
#[ doc = "Find a value based on the key" ]
45
- fn find < K : copy , V : copy > ( m : treemap < K , V > , k : K ) -> option < V > {
46
- alt * m {
47
- empty { none }
54
+ fn find < K : copy , V : copy > ( m : & const tree_edge < K , V > , k : K ) -> option < V > {
55
+ alt copy * m {
56
+ none { none }
57
+
48
58
// TODO: was that an optimization?
49
- node( @kk, @v, left, right) {
50
- if k == kk {
51
- some ( v)
52
- } else if k < kk {
53
- find ( left, k)
54
- } else { find ( right, k) }
59
+ some( node) {
60
+ if k == node. key {
61
+ some ( node. value )
62
+ } else if k < node. key {
63
+ find ( & const node. left , k)
64
+ } else {
65
+ find ( & const node. right , k)
66
+ }
55
67
}
56
68
}
57
69
}
58
70
59
71
#[ doc = "Visit all pairs in the map in order." ]
60
- fn traverse < K , V > ( m : treemap < K , V > , f : fn ( K , V ) ) {
61
- alt * m {
62
- empty { }
63
- /*
64
- Previously, this had what looked like redundant
65
- matches to me, so I changed it. but that may be a
66
- de-optimization -- tjc
67
- */
68
- node( k, v, left, right) {
69
- let k1 = k, v1 = v;
70
- traverse ( left, f) ;
71
- f ( * k1, * v1) ;
72
- traverse ( right, f) ;
72
+ fn traverse < K , V : copy > ( m : & const tree_edge < K , V > , f : fn ( K , V ) ) {
73
+ alt copy * m {
74
+ none { }
75
+ some( node) {
76
+ traverse ( & const node. left , f) ;
77
+ // copy of value is req'd as f() requires an immutable ptr
78
+ f ( node. key , copy node. value ) ;
79
+ traverse ( & const node. right , f) ;
73
80
}
74
81
}
75
82
}
@@ -134,4 +141,4 @@ mod tests {
134
141
assert ( find ( m, k2) == some ( "bar" ) ) ;
135
142
assert ( find ( m, k1) == some ( "foo" ) ) ;
136
143
}
137
- }
144
+ }
0 commit comments