about summary refs log tree commit diff
path: root/src/lib
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2011-07-08 11:43:14 -0700
committerPatrick Walton <pcwalton@mimiga.net>2011-07-08 11:44:38 -0700
commit0864a22aceab14092cef9b8a99dedcfb16fe1548 (patch)
treea2a659666e8205a271d9b49e449a95eb345862e8 /src/lib
parentd7db25e8f60af6894556a14cd420f7523f33e89b (diff)
downloadrust-0864a22aceab14092cef9b8a99dedcfb16fe1548.tar.gz
rust-0864a22aceab14092cef9b8a99dedcfb16fe1548.zip
stdlib: Add an interior vector version of union-find for now
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/std.rc1
-rw-r--r--src/lib/ufindivec.rs54
2 files changed, 55 insertions, 0 deletions
diff --git a/src/lib/std.rc b/src/lib/std.rc
index 24cae023c69..21fd2cbbbc6 100644
--- a/src/lib/std.rc
+++ b/src/lib/std.rc
@@ -78,6 +78,7 @@ mod sort;
 mod sha1;
 mod ebml;
 mod ufind;
+mod ufindivec;
 mod extfmt;
 mod box;
 mod getopts;
diff --git a/src/lib/ufindivec.rs b/src/lib/ufindivec.rs
new file mode 100644
index 00000000000..9759820222a
--- /dev/null
+++ b/src/lib/ufindivec.rs
@@ -0,0 +1,54 @@
+
+import option::none;
+import option::some;
+
+
+// A very naive implementation of union-find with unsigned integer nodes.
+// Maintains the invariant that the root of a node is always equal to or less
+// than the node itself.
+type node = option::t[uint];
+
+type ufind = rec(mutable node[mutable] nodes);
+
+fn make() -> ufind {
+    ret rec(mutable nodes=~[mutable]);
+}
+
+fn make_set(&ufind ufnd) -> uint {
+    auto idx = ivec::len(ufnd.nodes);
+    ufnd.nodes += ~[mutable none[uint]];
+    ret idx;
+}
+
+
+/// Creates sets as necessary to ensure that least `n` sets are present in the
+/// data structure.
+fn grow(&ufind ufnd, uint n) {
+    while (set_count(ufnd) < n) { make_set(ufnd); }
+}
+
+fn find(&ufind ufnd, uint n) -> uint {
+    alt (ufnd.nodes.(n)) {
+        case (none) { ret n; }
+        case (some(?m)) { auto m_ = m; be find(ufnd, m_); }
+    }
+}
+
+fn union(&ufind ufnd, uint m, uint n) {
+    auto m_root = find(ufnd, m);
+    auto n_root = find(ufnd, n);
+    if (m_root < n_root) {
+        ufnd.nodes.(n_root) = some[uint](m_root);
+    } else if (m_root > n_root) { ufnd.nodes.(m_root) = some[uint](n_root); }
+}
+
+fn set_count(&ufind ufnd) -> uint { ret ivec::len[node](ufnd.nodes); }
+
+
+// Removes all sets with IDs greater than or equal to the given value.
+fn prune(&ufind ufnd, uint n) {
+    // TODO: Use "slice" once we get rid of "mutable?"
+
+    auto len = ivec::len[node](ufnd.nodes);
+    while (len != n) { ivec::pop[node](ufnd.nodes); len -= 1u; }
+}