about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-06-28 19:31:27 -0700
committerBrian Anderson <banderson@mozilla.com>2011-06-28 19:48:33 -0700
commit7c500fc0a0354ab72f0d76ccae6fae8c2ee5e62d (patch)
tree52ed9be9d81c70d04344713ea4caefba9789aa32
parent7b5d34aa9ac5c82e08c82b6e865c3b697299f65d (diff)
downloadrust-7c500fc0a0354ab72f0d76ccae6fae8c2ee5e62d.tar.gz
rust-7c500fc0a0354ab72f0d76ccae6fae8c2ee5e62d.zip
Replace common::new_seq_hash with an adapter around std::smallintmap
It would be better to either convert ast_map to use smallintmap or make
smallintmap and hashmap follow the same interface, but I don't feel up to
it just now. Closes #585.
-rw-r--r--src/comp/middle/ast_map.rs70
-rw-r--r--src/comp/util/common.rs102
2 files changed, 69 insertions, 103 deletions
diff --git a/src/comp/middle/ast_map.rs b/src/comp/middle/ast_map.rs
index f6943b60529..eeee4149345 100644
--- a/src/comp/middle/ast_map.rs
+++ b/src/comp/middle/ast_map.rs
@@ -1,3 +1,5 @@
+import std::smallintmap;
+import std::option;
 import front::ast::*;
 import visit::vt;
 
@@ -11,7 +13,10 @@ tag ast_node {
 type map = std::map::hashmap[node_id, ast_node];
 
 fn map_crate(&crate c) -> map {
-    auto map = util::common::new_seq_int_hash[ast_node]();
+    // FIXME: This is using an adapter to convert the smallintmap
+    // interface to the hashmap interface. It would be better to just
+    // convert everything to use the smallintmap.
+    auto map = new_smallintmap_int_adapter[ast_node]();
 
     auto v_map = @rec(visit_item=bind map_item(map, _, _, _),
                       visit_native_item=bind map_native_item(map, _, _, _),
@@ -42,6 +47,69 @@ fn map_expr(&map map, &@expr ex, &() e, &vt[()] v) {
     visit::visit_expr(ex, e, v);
 }
 
+fn new_smallintmap_int_adapter[V]() -> std::map::hashmap[int, V] {
+    auto key_idx = fn(&int key) -> uint { key as uint };
+    auto idx_key = fn(&uint idx) -> int { idx as int };
+    ret new_smallintmap_adapter(key_idx, idx_key);
+}
+
+// This creates an object with the hashmap interface backed
+// by the smallintmap type, because I don't want to go through
+// the entire codebase adapting all the callsites to the different
+// interface.
+// FIXME: hashmap and smallintmap should support the same interface.
+fn new_smallintmap_adapter[K, V](fn(&K) -> uint key_idx,
+                                 fn(&uint) -> K idx_key)
+    -> std::map::hashmap[K, V] {
+
+    obj adapter[K, V](smallintmap::smallintmap[V] map,
+                      fn(&K) -> uint key_idx,
+                      fn(&uint) -> K idx_key) {
+
+        fn size() -> uint { fail }
+
+        fn insert(&K key, &V value) -> bool {
+            auto exists = smallintmap::contains_key(map, key_idx(key));
+            smallintmap::insert(map, key_idx(key), value);
+            ret !exists;
+        }
+
+        fn contains_key(&K key) -> bool {
+            ret smallintmap::contains_key(map, key_idx(key));
+        }
+
+        fn get(&K key) -> V {
+            ret smallintmap::get(map, key_idx(key));
+        }
+
+        fn find(&K key) -> option::t[V] {
+            ret smallintmap::find(map, key_idx(key));
+        }
+
+        fn remove(&K key) -> option::t[V] { fail }
+
+        fn rehash() { fail }
+
+        iter items() -> @tup(K, V) {
+            auto idx = 0u;
+            for (option::t[V] item in map.v) {
+                alt (item) {
+                    case (option::some(?elt)) {
+                        auto value = elt;
+                        auto key = idx_key(idx);
+                        put @tup(key, value);
+                    }
+                    case (option::none) { }
+                }
+                idx += 1u;
+            }
+        }
+    }
+
+    auto map = smallintmap::mk[V]();
+    ret adapter(map, key_idx, idx_key);
+}
+
 // Local Variables:
 // mode: rust
 // fill-column: 78;
diff --git a/src/comp/util/common.rs b/src/comp/util/common.rs
index e4a9d205c87..302eec6f52c 100644
--- a/src/comp/util/common.rs
+++ b/src/comp/util/common.rs
@@ -105,108 +105,6 @@ fn new_uint_hash[V]() -> std::map::hashmap[uint, V] {
     ret std::map::mk_hashmap[uint, V](hasher, eqer);
 }
 
-fn new_seq_hash[K, V](fn(&K) -> uint key_idx,
-                      fn(&uint) -> K idx_key) -> std::map::hashmap[K, V] {
-    fn ensure_size[V](&mutable vec[mutable option::t[V]] bkts, uint idx) {
-        auto bkt_len = vec::len(bkts);
-        if (idx >= bkt_len) {
-            auto needed = idx - bkt_len + 1u;
-            auto new = vec::init_elt_mut(option::none[V], needed);
-            bkts += new;
-        }
-    }
-
-    obj seq_hash[K, V](mutable uint nelts,
-                       mutable vec[mutable option::t[V]] bkts,
-                       fn(&K) -> uint key_idx,
-                       fn(&uint) -> K idx_key) {
-
-        fn size() -> uint { nelts }
-
-        fn insert(&K key, &V value) -> bool {
-            auto idx = key_idx(key);
-            ensure_size(bkts, idx);
-            if (option::is_some(bkts.(idx))) {
-                bkts.(idx) = option::some(value);
-                ret false;
-            } else {
-                bkts.(idx) = option::some(value);
-                nelts += 1u;
-                ret true;
-            }
-        }
-
-        fn contains_key(&K key) -> bool {
-            auto idx = key_idx(key);
-            ensure_size(bkts, idx);
-            if (option::is_some(bkts.(idx))) {
-                ret true;
-            } else {
-                ret false;
-            }
-        }
-
-        fn get(&K key) -> V {
-            ret alt (self.find(key)) {
-                case (option::some(?v)) { v }
-                case (_) { fail }
-            };
-        }
-
-        fn find(&K key) -> option::t[V] {
-            auto idx = key_idx(key);
-            ensure_size(bkts, idx);
-            ret bkts.(idx);
-        }
-
-        fn remove(&K key) -> option::t[V] {
-            auto idx = key_idx(key);
-            ensure_size(bkts, idx);
-            auto val = bkts.(idx);
-            if (option::is_some(val)) {
-                bkts.(idx) = option::none;
-                nelts -= 1u;
-            }
-            ret val;
-        }
-
-        fn rehash() { }
-
-        iter items() -> @tup(K, V) {
-            auto idx = 0u;
-            auto bktsize = vec::len(bkts);
-            while (idx < bktsize) {
-                alt (bkts.(idx)) {
-                    case (option::some(?v)) {
-                        // FIXME: Appease alias analysis
-                        auto value = v;
-                        put @tup(idx_key(idx), value);
-                    }
-                    case (_) { }
-                }
-                idx += 1u;
-            }
-        }
-    }
-
-    let vec[mutable option::t[V]] bkts = [mutable];
-    ret seq_hash[K, V](0u, bkts, key_idx, idx_key);
-}
-
-// A specialized map for keys that are sequential ints
-fn new_seq_int_hash[V]() -> std::map::hashmap[int, V] {
-    auto key_idx = fn(&int key) -> uint { key as uint };
-    auto idx_key = fn(&uint idx) -> int { idx as int };
-    ret new_seq_hash(key_idx, idx_key);
-}
-
-// A specialized map for keys that are sequential uints
-fn new_seq_uint_hash[V]() -> std::map::hashmap[uint, V] {
-    auto key_idx = fn(&uint key) -> uint { key };
-    auto idx_key = fn(&uint idx) -> uint { idx };
-    ret new_seq_hash(key_idx, idx_key);
-}
-
 fn istr(int i) -> str { ret int::to_str(i, 10u); }
 
 fn uistr(uint i) -> str { ret uint::to_str(i, 10u); }