From e9b7ce6f57e8ca74dfdb16ba91fcae38d2c44798 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 28 Aug 2012 11:59:31 -0700 Subject: [PATCH] refactor send_map impl to be based on structs --- src/libcore/send_map.rs | 66 +++++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/src/libcore/send_map.rs b/src/libcore/send_map.rs index 19d87980c8c3..12d3583aef15 100644 --- a/src/libcore/send_map.rs +++ b/src/libcore/send_map.rs @@ -13,19 +13,38 @@ Sendable hash maps. Very much a work in progress. type HashFn = pure fn~(K) -> uint; type EqFn = pure fn~(K, K) -> bool; +trait send_map { + // FIXME(#3148) ^^^^ once find_ref() works, we can drop V:copy + + fn insert(&mut self, +k: K, +v: V) -> bool; + fn remove(&mut self, k: &K) -> bool; + fn clear(&mut self); + pure fn len(&const self) -> uint; + pure fn is_empty(&const self) -> bool; + fn contains_key(&const self, k: &K) -> bool; + fn each_ref(&self, blk: fn(k: &K, v: &V) -> bool); + fn each_key_ref(&self, blk: fn(k: &K) -> bool); + fn each_value_ref(&self, blk: fn(v: &V) -> bool); + fn find(&const self, k: &K) -> Option; + fn get(&const self, k: &K) -> V; +} + /// Open addressing with linear probing. mod linear { export LinearMap, linear_map, linear_map_with_capacity, public_methods; const initial_capacity: uint = 32u; // 2^5 - type Bucket = {hash: uint, key: K, value: V}; - enum LinearMap { - LinearMap_({ - hashfn: pure fn~(x: &K) -> uint, - eqfn: pure fn~(x: &K, y: &K) -> bool, - resize_at: uint, - size: uint, - buckets: ~[Option>]}) + struct Bucket { + hash: uint; + key: K; + value: V; + } + struct LinearMap { + hashfn: pure fn~(x: &K) -> uint; + eqfn: pure fn~(x: &K, y: &K) -> bool; + resize_at: uint; + size: uint; + buckets: ~[Option>]; } // FIXME(#3148) -- we could rewrite found_entry @@ -51,12 +70,13 @@ mod linear { +eqfn: pure fn~(x: &K, y: &K) -> bool, initial_capacity: uint) -> LinearMap { - LinearMap_({ + LinearMap { hashfn: hashfn, eqfn: eqfn, resize_at: resize_at(initial_capacity), size: 0, - buckets: vec::from_fn(initial_capacity, |_i| None)}) + buckets: vec::from_fn(initial_capacity, |_i| None) + } } priv impl LinearMap { @@ -136,15 +156,19 @@ mod linear { for uint::range(0, old_capacity) |i| { let mut bucket = None; bucket <-> old_buckets[i]; - if bucket.is_some() { - self.insert_bucket(bucket); - } + self.insert_opt_bucket(bucket); } } - fn insert_bucket(&mut self, +bucket: Option>) { - let {hash, key, value} <- option::unwrap(bucket); - let _ = self.insert_internal(hash, key, value); + fn insert_opt_bucket(&mut self, +bucket: Option>) { + match move bucket { + Some(Bucket {hash: move hash, + key: move key, + value: move value}) => { + self.insert_internal(hash, key, value); + } + None => {} + } } /// Inserts the key value pair into the buckets. @@ -156,14 +180,18 @@ mod linear { FoundHole(idx) => { debug!("insert fresh (%?->%?) at idx %?, hash %?", k, v, idx, hash); - self.buckets[idx] = Some({hash: hash, key: k, value: v}); + self.buckets[idx] = Some(Bucket {hash: hash, + key: k, + value: v}); self.size += 1; return true; } FoundEntry(idx) => { debug!("insert overwrite (%?->%?) at idx %?, hash %?", k, v, idx, hash); - self.buckets[idx] = Some({hash: hash, key: k, value: v}); + self.buckets[idx] = Some(Bucket {hash: hash, + key: k, + value: v}); return false; } } @@ -223,7 +251,7 @@ mod linear { while self.buckets[idx].is_some() { let mut bucket = None; bucket <-> self.buckets[idx]; - self.insert_bucket(bucket); + self.insert_opt_bucket(bucket); idx = self.next_bucket(idx, len_buckets); } self.size -= 1;