|
| 1 | +/* |
| 2 | +A functional key,value store that works on anything. |
| 3 | +
|
| 4 | +This works using a binary search tree. In the first version, it's a |
| 5 | +very naive algorithm, but it will probably be updated to be a |
| 6 | +red-black tree or something else. |
| 7 | +
|
| 8 | +This is copied and modified from treemap right now. It's missing a lot |
| 9 | +of features. |
| 10 | +
|
| 11 | +*/ |
| 12 | + |
| 13 | +import option::some; |
| 14 | +import option::none; |
| 15 | +import option = option::t; |
| 16 | + |
| 17 | +export treemap; |
| 18 | +export init; |
| 19 | +export insert; |
| 20 | +export find; |
| 21 | +export traverse; |
| 22 | + |
| 23 | +tag tree_node<@K, @V> { |
| 24 | + empty; |
| 25 | + node(@K, @V, @tree_node<K, V>, @tree_node<K, V>); |
| 26 | +} |
| 27 | + |
| 28 | +type treemap<@K, @V> = @tree_node<K, V>; |
| 29 | + |
| 30 | +fn init<@K, @V>() -> treemap<K, V> { @empty } |
| 31 | + |
| 32 | +fn insert<@K, @V>(m : &treemap<K, V>, k : &K, v : &V) -> treemap<K,V> { |
| 33 | + @alt m { |
| 34 | + @empty. { |
| 35 | + node(@k, @v, @empty, @empty) |
| 36 | + } |
| 37 | + @node(@kk, vv, left, right) { |
| 38 | + if k < kk { |
| 39 | + node(@kk, vv, insert(left, k, v), right) |
| 40 | + } else if k == kk { |
| 41 | + node(@kk, @v, left, right) |
| 42 | + } else { |
| 43 | + node(@kk, vv, left, insert(right, k, v)) |
| 44 | + } |
| 45 | + } |
| 46 | + } |
| 47 | +} |
| 48 | + |
| 49 | +fn find<@K, @V>(m : &treemap<K, V>, k : &K) -> option<V> { |
| 50 | + alt *m { |
| 51 | + empty. { none } |
| 52 | + node(@kk, @v, left, right) { |
| 53 | + if k == kk { some(v) } |
| 54 | + else if k < kk { find(left, k) } |
| 55 | + else { find(right, k) } |
| 56 | + } |
| 57 | + } |
| 58 | +} |
| 59 | + |
| 60 | + |
| 61 | +// Performs an in-order traversal |
| 62 | +fn traverse<@K, @V>(m : &treemap<K, V>, f : fn(&K, &V)) { |
| 63 | + alt *m { |
| 64 | + empty. { } |
| 65 | + node(@k, @v, _, _) { |
| 66 | + // copy v to make aliases work out |
| 67 | + let v1 = v; |
| 68 | + alt *m { |
| 69 | + node(_, _, left, _) { |
| 70 | + traverse(left, f); |
| 71 | + } |
| 72 | + } |
| 73 | + f(k, v1); |
| 74 | + alt *m { |
| 75 | + node(_, _, _, right) { |
| 76 | + traverse(right, f); |
| 77 | + } |
| 78 | + } |
| 79 | + } |
| 80 | + } |
| 81 | +} |
0 commit comments