From 7c500fc0a0354ab72f0d76ccae6fae8c2ee5e62d Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 28 Jun 2011 19:31:27 -0700 Subject: [PATCH] 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. --- src/comp/middle/ast_map.rs | 70 ++++++++++++++++++++++++- src/comp/util/common.rs | 102 ------------------------------------- 2 files changed, 69 insertions(+), 103 deletions(-) diff --git a/src/comp/middle/ast_map.rs b/src/comp/middle/ast_map.rs index f6943b60529e..eeee41493458 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 e4a9d205c874..302eec6f52c6 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); }