about summary refs log tree commit diff
path: root/src/lib
diff options
context:
space:
mode:
authorMichael Sullivan <sully@msully.net>2011-08-30 11:38:14 -0400
committerMichael Sullivan <sully@msully.net>2011-08-31 14:10:15 -0400
commit959938e89144435c3a2fb1752527cfb17dd071a4 (patch)
tree94b3f8f3876e5351a1556305f7eedca35cdc3331 /src/lib
parent6209e844eefe6058fab2c0427e4a6f4ff21dc865 (diff)
downloadrust-959938e89144435c3a2fb1752527cfb17dd071a4.tar.gz
rust-959938e89144435c3a2fb1752527cfb17dd071a4.zip
Produce the start of an immutable treemap.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/fun_treemap.rs81
-rw-r--r--src/lib/std.rc1
2 files changed, 82 insertions, 0 deletions
diff --git a/src/lib/fun_treemap.rs b/src/lib/fun_treemap.rs
new file mode 100644
index 00000000000..30ce4bc1b09
--- /dev/null
+++ b/src/lib/fun_treemap.rs
@@ -0,0 +1,81 @@
+/*
+A functional 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.
+
+This is copied and modified from treemap right now. It's missing a lot
+of features.
+
+*/
+
+import option::some;
+import option::none;
+import option = option::t;
+
+export treemap;
+export init;
+export insert;
+export find;
+export traverse;
+
+tag tree_node<@K, @V> {
+    empty;
+    node(@K, @V, @tree_node<K, V>, @tree_node<K, V>);
+}
+
+type treemap<@K, @V> = @tree_node<K, V>;
+
+fn init<@K, @V>() -> treemap<K, V> { @empty }
+
+fn insert<@K, @V>(m : &treemap<K, V>, k : &K, v : &V) -> treemap<K,V> {
+    @alt m {
+      @empty. {
+        node(@k, @v, @empty, @empty)
+      }
+      @node(@kk, vv, left, right) {
+        if k < kk {
+            node(@kk, vv, insert(left, k, v), right)
+        } else if k == kk {
+            node(@kk, @v, left, right)
+        } else {
+            node(@kk, vv, left, insert(right, k, v))
+        }
+      }
+    }
+}
+
+fn find<@K, @V>(m : &treemap<K, V>, k : &K) -> option<V> {
+  alt *m {
+    empty. { none }
+    node(@kk, @v, left, right) {
+      if k == kk { some(v) }
+      else if k < kk { find(left, k) }
+      else { find(right, k) }
+    }
+  }
+}
+
+
+// Performs an in-order traversal
+fn traverse<@K, @V>(m : &treemap<K, V>, f : fn(&K, &V)) {
+  alt *m {
+    empty. { }
+    node(@k, @v, _, _) {
+      // copy v to make aliases work out
+      let v1 = v;
+      alt *m {
+        node(_, _, left, _) {
+          traverse(left, f);
+        }
+      }
+      f(k, v1);
+      alt *m {
+        node(_, _, _, right) {
+          traverse(right, f);
+        }
+      }
+    }
+  }
+}
diff --git a/src/lib/std.rc b/src/lib/std.rc
index d39f5004af1..d07ee097023 100644
--- a/src/lib/std.rc
+++ b/src/lib/std.rc
@@ -76,6 +76,7 @@ mod net;
 // FIXME: parametric
 mod map;
 mod treemap;
+mod fun_treemap;
 mod deque;
 mod list;
 mod rand;