Skip to content

Commit

Permalink
Complete Entry feature parity by adding the small methods
Browse files Browse the repository at this point in the history
Add .key(), .get() and so on, and now the entry API is feature complete
(with HashMap's current feature set as norm).
  • Loading branch information
bluss committed Nov 2, 2016
1 parent d462803 commit bbbca34
Showing 1 changed file with 34 additions and 14 deletions.
48 changes: 34 additions & 14 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::borrow::Borrow;

use std::cmp::max;
use std::fmt;
use std::mem::{swap, replace};
use std::mem::{replace};
use std::marker::PhantomData;

use util::{second, ptrdistance, enumerate};
Expand Down Expand Up @@ -203,6 +203,23 @@ impl<Sz> ShortHashProxy<Sz>
/// not depend on the keys or the hash function at all.
///
/// All iterators traverse the map in the same order.
///
/// # Examples
///
/// ```
/// use ordermap::OrderMap;
///
/// // count the frequency of each letter in a sentence.
/// let mut letters = OrderMap::new();
/// for ch in "a short treatise on fungi".chars() {
/// *letters.entry(ch).or_insert(0) += 1;
/// }
///
/// assert_eq!(letters[&'s'], 2);
/// assert_eq!(letters[&'t'], 3);
/// assert_eq!(letters[&'u'], 1);
/// assert_eq!(letters.get(&'y'), None);
/// ```
#[derive(Clone)]
pub struct OrderMap<K, V, S = RandomState> {
mask: usize,
Expand Down Expand Up @@ -418,27 +435,36 @@ impl<'a, K, V, S> Entry<'a, K, V, S> {
Entry::Vacant(entry) => entry.insert(call()),
}
}

pub fn key(&self) -> &K {
match *self {
Entry::Occupied(ref entry) => entry.key(),
Entry::Vacant(ref entry) => entry.key(),
}
}
}

pub struct OccupiedEntry<'a, K: 'a, V: 'a, S: 'a = RandomState> {
map: &'a mut OrderMap<K, V, S>,
key: K,
#[allow(dead_code)]
hash: HashValue,
#[allow(dead_code)]
probe: usize,
index: usize,
}

impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> {
pub fn key(&self) -> &K { &self.key }
pub fn get(&self) -> &V {
&self.map.entries[self.index].value
}
pub fn get_mut(&mut self) -> &mut V {
&mut self.map.entries[self.index].value
}
pub fn into_mut(self) -> &'a mut V {
&mut self.map.entries[self.index].value
}
pub fn insert(self, mut value: V) -> V {
swap(&mut self.map.entries[self.index].value, &mut value);
value

pub fn insert(self, value: V) -> V {
replace(&mut self.into_mut(), value)
}

pub fn remove(self) -> V {
Expand All @@ -449,7 +475,6 @@ impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> {
pub fn remove_entry(self) -> (K, V) {
self.map.remove_found(self.probe, self.index)
}

}


Expand All @@ -458,8 +483,6 @@ pub struct VacantEntry<'a, K: 'a, V: 'a, S: 'a = RandomState> {
key: K,
hash: HashValue,
probe: usize,
#[allow(dead_code)]
index: usize,
}

impl<'a, K, V, S> VacantEntry<'a, K, V, S> {
Expand Down Expand Up @@ -488,7 +511,7 @@ impl<K, V, S> OrderMap<K, V, S>
where K: Hash + Eq,
S: BuildHasher,
{
/// FIXME Entry API does not implement all hash map's methods yet.
/// Get the given key’s corresponding entry in the map for in-place manipulation.
pub fn entry(&mut self, key: K) -> Entry<K, V, S> {
self.reserve_one();
dispatch_32_vs_64!(self.entry_phase_1(key))
Expand All @@ -514,12 +537,10 @@ impl<K, V, S> OrderMap<K, V, S>
hash: hash,
key: key,
probe: probe,
index: i,
});
} else if entry_hash == hash && self.entries[i].key == key {
return Entry::Occupied(OccupiedEntry {
map: self,
hash: hash,
key: key,
probe: probe,
index: i,
Expand All @@ -532,7 +553,6 @@ impl<K, V, S> OrderMap<K, V, S>
hash: hash,
key: key,
probe: probe,
index: 0,
});
}
dist += 1;
Expand Down

0 comments on commit bbbca34

Please sign in to comment.