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.
This commit is contained in:
parent
7b5d34aa9a
commit
7c500fc0a0
2 changed files with 69 additions and 103 deletions
|
@ -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;
|
||||
|
|
|
@ -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); }
|
||||
|
|
Loading…
Reference in a new issue