hashmap: port to Vec<T>
This commit is contained in:
parent
1798de7d08
commit
b2ec71fc27
1 changed files with 25 additions and 25 deletions
|
@ -66,8 +66,9 @@ use rand::Rng;
|
||||||
use rand;
|
use rand;
|
||||||
use uint;
|
use uint;
|
||||||
use util::replace;
|
use util::replace;
|
||||||
use vec::{ImmutableVector, MutableVector, OwnedVector};
|
use vec::{ImmutableVector, MutableVector, OwnedVector, Items, MutItems};
|
||||||
use vec;
|
use vec_ng;
|
||||||
|
use vec_ng::Vec;
|
||||||
|
|
||||||
static INITIAL_CAPACITY: uint = 32u; // 2^5
|
static INITIAL_CAPACITY: uint = 32u; // 2^5
|
||||||
|
|
||||||
|
@ -90,7 +91,7 @@ pub struct HashMap<K,V> {
|
||||||
priv k1: u64,
|
priv k1: u64,
|
||||||
priv resize_at: uint,
|
priv resize_at: uint,
|
||||||
priv size: uint,
|
priv size: uint,
|
||||||
priv buckets: ~[Option<Bucket<K, V>>],
|
priv buckets: Vec<Option<Bucket<K, V>>>
|
||||||
}
|
}
|
||||||
|
|
||||||
// We could rewrite FoundEntry to have type Option<&Bucket<K, V>>
|
// We could rewrite FoundEntry to have type Option<&Bucket<K, V>>
|
||||||
|
@ -151,7 +152,7 @@ impl<K:Hash + Eq,V> HashMap<K, V> {
|
||||||
-> SearchResult {
|
-> SearchResult {
|
||||||
let mut ret = TableFull;
|
let mut ret = TableFull;
|
||||||
self.bucket_sequence(hash, |i| {
|
self.bucket_sequence(hash, |i| {
|
||||||
match self.buckets[i] {
|
match self.buckets.as_slice()[i] {
|
||||||
Some(ref bkt) if bkt.hash == hash && *k == bkt.key => {
|
Some(ref bkt) if bkt.hash == hash && *k == bkt.key => {
|
||||||
ret = FoundEntry(i); false
|
ret = FoundEntry(i); false
|
||||||
},
|
},
|
||||||
|
@ -169,7 +170,7 @@ impl<K:Hash + Eq,V> HashMap<K, V> {
|
||||||
-> SearchResult {
|
-> SearchResult {
|
||||||
let mut ret = TableFull;
|
let mut ret = TableFull;
|
||||||
self.bucket_sequence(hash, |i| {
|
self.bucket_sequence(hash, |i| {
|
||||||
match self.buckets[i] {
|
match self.buckets.as_slice()[i] {
|
||||||
Some(ref bkt) if bkt.hash == hash && k.equiv(&bkt.key) => {
|
Some(ref bkt) if bkt.hash == hash && k.equiv(&bkt.key) => {
|
||||||
ret = FoundEntry(i); false
|
ret = FoundEntry(i); false
|
||||||
},
|
},
|
||||||
|
@ -194,7 +195,7 @@ impl<K:Hash + Eq,V> HashMap<K, V> {
|
||||||
self.resize_at = resize_at(new_capacity);
|
self.resize_at = resize_at(new_capacity);
|
||||||
|
|
||||||
let old_buckets = replace(&mut self.buckets,
|
let old_buckets = replace(&mut self.buckets,
|
||||||
vec::from_fn(new_capacity, |_| None));
|
Vec::from_fn(new_capacity, |_| None));
|
||||||
|
|
||||||
self.size = 0;
|
self.size = 0;
|
||||||
for bucket in old_buckets.move_iter() {
|
for bucket in old_buckets.move_iter() {
|
||||||
|
@ -213,7 +214,7 @@ impl<K:Hash + Eq,V> HashMap<K, V> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn value_for_bucket<'a>(&'a self, idx: uint) -> &'a V {
|
fn value_for_bucket<'a>(&'a self, idx: uint) -> &'a V {
|
||||||
match self.buckets[idx] {
|
match self.buckets.as_slice()[idx] {
|
||||||
Some(ref bkt) => &bkt.value,
|
Some(ref bkt) => &bkt.value,
|
||||||
None => fail!("HashMap::find: internal logic error"),
|
None => fail!("HashMap::find: internal logic error"),
|
||||||
}
|
}
|
||||||
|
@ -221,7 +222,7 @@ impl<K:Hash + Eq,V> HashMap<K, V> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mut_value_for_bucket<'a>(&'a mut self, idx: uint) -> &'a mut V {
|
fn mut_value_for_bucket<'a>(&'a mut self, idx: uint) -> &'a mut V {
|
||||||
match self.buckets[idx] {
|
match self.buckets.as_mut_slice()[idx] {
|
||||||
Some(ref mut bkt) => &mut bkt.value,
|
Some(ref mut bkt) => &mut bkt.value,
|
||||||
None => unreachable!()
|
None => unreachable!()
|
||||||
}
|
}
|
||||||
|
@ -234,13 +235,12 @@ impl<K:Hash + Eq,V> HashMap<K, V> {
|
||||||
match self.bucket_for_key_with_hash(hash, &k) {
|
match self.bucket_for_key_with_hash(hash, &k) {
|
||||||
TableFull => { fail!("Internal logic error"); }
|
TableFull => { fail!("Internal logic error"); }
|
||||||
FoundHole(idx) => {
|
FoundHole(idx) => {
|
||||||
self.buckets[idx] = Some(Bucket{hash: hash, key: k,
|
self.buckets.as_mut_slice()[idx] = Some(Bucket{hash: hash, key: k, value: v});
|
||||||
value: v});
|
|
||||||
self.size += 1;
|
self.size += 1;
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
FoundEntry(idx) => {
|
FoundEntry(idx) => {
|
||||||
match self.buckets[idx] {
|
match self.buckets.as_mut_slice()[idx] {
|
||||||
None => { fail!("insert_internal: Internal logic error") }
|
None => { fail!("insert_internal: Internal logic error") }
|
||||||
Some(ref mut b) => {
|
Some(ref mut b) => {
|
||||||
b.hash = hash;
|
b.hash = hash;
|
||||||
|
@ -273,7 +273,7 @@ impl<K:Hash + Eq,V> HashMap<K, V> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let len_buckets = self.buckets.len();
|
let len_buckets = self.buckets.len();
|
||||||
let bucket = self.buckets[idx].take();
|
let bucket = self.buckets.as_mut_slice()[idx].take();
|
||||||
|
|
||||||
let value = bucket.map(|bucket| bucket.value);
|
let value = bucket.map(|bucket| bucket.value);
|
||||||
|
|
||||||
|
@ -281,8 +281,8 @@ impl<K:Hash + Eq,V> HashMap<K, V> {
|
||||||
what our new size is ahead of time before we start insertions */
|
what our new size is ahead of time before we start insertions */
|
||||||
let size = self.size - 1;
|
let size = self.size - 1;
|
||||||
idx = self.next_bucket(idx, len_buckets);
|
idx = self.next_bucket(idx, len_buckets);
|
||||||
while self.buckets[idx].is_some() {
|
while self.buckets.as_slice()[idx].is_some() {
|
||||||
let bucket = self.buckets[idx].take();
|
let bucket = self.buckets.as_mut_slice()[idx].take();
|
||||||
self.insert_opt_bucket(bucket);
|
self.insert_opt_bucket(bucket);
|
||||||
idx = self.next_bucket(idx, len_buckets);
|
idx = self.next_bucket(idx, len_buckets);
|
||||||
}
|
}
|
||||||
|
@ -300,7 +300,7 @@ impl<K:Hash + Eq,V> Container for HashMap<K, V> {
|
||||||
impl<K:Hash + Eq,V> Mutable for HashMap<K, V> {
|
impl<K:Hash + Eq,V> Mutable for HashMap<K, V> {
|
||||||
/// Clear the map, removing all key-value pairs.
|
/// Clear the map, removing all key-value pairs.
|
||||||
fn clear(&mut self) {
|
fn clear(&mut self) {
|
||||||
for bkt in self.buckets.mut_iter() {
|
for bkt in self.buckets.as_mut_slice().mut_iter() {
|
||||||
*bkt = None;
|
*bkt = None;
|
||||||
}
|
}
|
||||||
self.size = 0;
|
self.size = 0;
|
||||||
|
@ -380,7 +380,7 @@ impl<K: Hash + Eq, V> HashMap<K, V> {
|
||||||
k0: k0, k1: k1,
|
k0: k0, k1: k1,
|
||||||
resize_at: resize_at(cap),
|
resize_at: resize_at(cap),
|
||||||
size: 0,
|
size: 0,
|
||||||
buckets: vec::from_fn(cap, |_| None)
|
buckets: Vec::from_fn(cap, |_| None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,7 +455,7 @@ impl<K: Hash + Eq, V> HashMap<K, V> {
|
||||||
FoundEntry(idx) => { found(&k, self.mut_value_for_bucket(idx), a); idx }
|
FoundEntry(idx) => { found(&k, self.mut_value_for_bucket(idx), a); idx }
|
||||||
FoundHole(idx) => {
|
FoundHole(idx) => {
|
||||||
let v = not_found(&k, a);
|
let v = not_found(&k, a);
|
||||||
self.buckets[idx] = Some(Bucket{hash: hash, key: k, value: v});
|
self.buckets.as_mut_slice()[idx] = Some(Bucket{hash: hash, key: k, value: v});
|
||||||
self.size += 1;
|
self.size += 1;
|
||||||
idx
|
idx
|
||||||
}
|
}
|
||||||
|
@ -541,14 +541,14 @@ impl<K: Hash + Eq, V> HashMap<K, V> {
|
||||||
/// An iterator visiting all key-value pairs in arbitrary order.
|
/// An iterator visiting all key-value pairs in arbitrary order.
|
||||||
/// Iterator element type is (&'a K, &'a V).
|
/// Iterator element type is (&'a K, &'a V).
|
||||||
pub fn iter<'a>(&'a self) -> Entries<'a, K, V> {
|
pub fn iter<'a>(&'a self) -> Entries<'a, K, V> {
|
||||||
Entries { iter: self.buckets.iter() }
|
Entries { iter: self.buckets.as_slice().iter() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An iterator visiting all key-value pairs in arbitrary order,
|
/// An iterator visiting all key-value pairs in arbitrary order,
|
||||||
/// with mutable references to the values.
|
/// with mutable references to the values.
|
||||||
/// Iterator element type is (&'a K, &'a mut V).
|
/// Iterator element type is (&'a K, &'a mut V).
|
||||||
pub fn mut_iter<'a>(&'a mut self) -> MutEntries<'a, K, V> {
|
pub fn mut_iter<'a>(&'a mut self) -> MutEntries<'a, K, V> {
|
||||||
MutEntries { iter: self.buckets.mut_iter() }
|
MutEntries { iter: self.buckets.as_mut_slice().mut_iter() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a consuming iterator, that is, one that moves each key-value
|
/// Creates a consuming iterator, that is, one that moves each key-value
|
||||||
|
@ -599,17 +599,17 @@ impl<K:Hash + Eq + Clone,V:Clone> Clone for HashMap<K,V> {
|
||||||
/// HashMap iterator
|
/// HashMap iterator
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub struct Entries<'a, K, V> {
|
pub struct Entries<'a, K, V> {
|
||||||
priv iter: vec::Items<'a, Option<Bucket<K, V>>>,
|
priv iter: Items<'a, Option<Bucket<K, V>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// HashMap mutable values iterator
|
/// HashMap mutable values iterator
|
||||||
pub struct MutEntries<'a, K, V> {
|
pub struct MutEntries<'a, K, V> {
|
||||||
priv iter: vec::MutItems<'a, Option<Bucket<K, V>>>,
|
priv iter: MutItems<'a, Option<Bucket<K, V>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// HashMap move iterator
|
/// HashMap move iterator
|
||||||
pub struct MoveEntries<K, V> {
|
pub struct MoveEntries<K, V> {
|
||||||
priv iter: vec::MoveItems<Option<Bucket<K, V>>>,
|
priv iter: vec_ng::MoveItems<Option<Bucket<K, V>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// HashMap keys iterator
|
/// HashMap keys iterator
|
||||||
|
@ -623,12 +623,12 @@ pub type Values<'a, K, V> =
|
||||||
/// HashSet iterator
|
/// HashSet iterator
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub struct SetItems<'a, K> {
|
pub struct SetItems<'a, K> {
|
||||||
priv iter: vec::Items<'a, Option<Bucket<K, ()>>>,
|
priv iter: Items<'a, Option<Bucket<K, ()>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// HashSet move iterator
|
/// HashSet move iterator
|
||||||
pub struct SetMoveItems<K> {
|
pub struct SetMoveItems<K> {
|
||||||
priv iter: vec::MoveItems<Option<Bucket<K, ()>>>,
|
priv iter: vec_ng::MoveItems<Option<Bucket<K, ()>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {
|
impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {
|
||||||
|
@ -807,7 +807,7 @@ impl<T:Hash + Eq> HashSet<T> {
|
||||||
/// An iterator visiting all elements in arbitrary order.
|
/// An iterator visiting all elements in arbitrary order.
|
||||||
/// Iterator element type is &'a T.
|
/// Iterator element type is &'a T.
|
||||||
pub fn iter<'a>(&'a self) -> SetItems<'a, T> {
|
pub fn iter<'a>(&'a self) -> SetItems<'a, T> {
|
||||||
SetItems { iter: self.map.buckets.iter() }
|
SetItems { iter: self.map.buckets.as_slice().iter() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a consuming iterator, that is, one that moves each value out
|
/// Creates a consuming iterator, that is, one that moves each value out
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue