diff --git a/src/lib/std.rc b/src/lib/std.rc index fca67a25da4..ffbf26b5928 100644 --- a/src/lib/std.rc +++ b/src/lib/std.rc @@ -75,6 +75,7 @@ mod net; // FIXME: parametric mod map; +mod treemap; mod deque; mod list; mod rand; diff --git a/src/lib/treemap.rs b/src/lib/treemap.rs new file mode 100644 index 00000000000..97ab1353c6b --- /dev/null +++ b/src/lib/treemap.rs @@ -0,0 +1,76 @@ +/* +A key,value store that works on anything. + +This works using a binary search tree. In the first version, it's a +very naive algorithm, but it will probably be updated to be a +red-black tree or something else. + +*/ + +import option::some; +import option::none; +import option = option::t; + +export treemap; +export init; +export insert; +export find; + +tag tree_node<@K, @V> { + empty; + node(@K, @V, treemap, treemap); +} + +type treemap<@K, @V> = @mutable tree_node; + +fn init<@K, @V>() -> treemap { @mutable empty } + +fn insert<@K, @V>(m : &treemap, k : &K, v : &V) { + alt m { + @empty. { + *m = node(@k, @v, @mutable empty, @mutable empty); + } + @node(@kk, _, _, _) { + // We have to name left and right individually, because + // otherwise the alias checker complains. + if k < kk { + alt m { + @node(_, _, left, _) { + insert(left, k, v); + } + } + } + else { + alt m { + @node(_, _, _, right) { + insert(right, k, v); + } + } + } + } + } +} + +fn find<@K, @V>(m : &treemap, k : &K) -> option { + alt *m { + empty. { none } + node(@kk, @v, _, _) { + if k == kk { some(v) } + // Again, ugliness to unpack left and right individually. + else if k < kk { + alt *m { + node(_, _, left, _) { + find(left, k) + } + } + } + else { + alt *m { + node(_, _, _, right) { + find(right, k) + } + } + } + } + } +} diff --git a/src/test/stdtest/stdtest.rc b/src/test/stdtest/stdtest.rc index ecf157cddae..64d52beb202 100644 --- a/src/test/stdtest/stdtest.rc +++ b/src/test/stdtest/stdtest.rc @@ -12,6 +12,7 @@ mod io; mod vec; mod list; mod map; +mod treemap; mod net; mod option; mod os; diff --git a/src/test/stdtest/treemap.rs b/src/test/stdtest/treemap.rs new file mode 100644 index 00000000000..58777b2579c --- /dev/null +++ b/src/test/stdtest/treemap.rs @@ -0,0 +1,42 @@ +use std; +import std::treemap::*; +import std::option::some; +import std::option::none; + +#[test] +fn init_treemap() { + let m = init::(); +} + +#[test] +fn insert_one() { + let m = init(); + insert(m, 1, 2); +} + +#[test] +fn insert_two() { + let m = init(); + insert(m, 1, 2); + insert(m, 3, 4); +} + +#[test] +fn insert_find() { + let m = init(); + insert(m, 1, 2); + assert(find(m, 1) == some(2)); +} + +#[test] +fn find_empty() { + let m = init::(); + assert(find(m, 1) == none); +} + +#[test] +fn find_not_found() { + let m = init(); + insert(m, 1, 2); + assert(find(m, 2) == none); +}