Skip to content

Commit

Permalink
[breaking change] Update entry API as part of RFC 509.
Browse files Browse the repository at this point in the history
  • Loading branch information
bfops committed Jan 4, 2015
1 parent 260e461 commit 400c3a0
Show file tree
Hide file tree
Showing 20 changed files with 170 additions and 135 deletions.
12 changes: 7 additions & 5 deletions src/libcollections/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use prelude::*;
use std::rand;
use std::rand::Rng;
use test::Bencher;
use test::{Bencher, black_box};

pub fn insert_rand_n<M, I, R>(n: uint,
map: &mut M,
Expand All @@ -33,7 +33,8 @@ pub fn insert_rand_n<M, I, R>(n: uint,
let k = rng.gen::<uint>() % n;
insert(map, k);
remove(map, k);
})
});
black_box(map);
}

pub fn insert_seq_n<M, I, R>(n: uint,
Expand All @@ -55,7 +56,8 @@ pub fn insert_seq_n<M, I, R>(n: uint,
insert(map, i);
remove(map, i);
i = (i + 2) % n;
})
});
black_box(map);
}

pub fn find_rand_n<M, T, I, F>(n: uint,
Expand All @@ -82,7 +84,7 @@ pub fn find_rand_n<M, T, I, F>(n: uint,
b.iter(|| {
let t = find(map, keys[i]);
i = (i + 1) % n;
t
black_box(t);
})
}

Expand All @@ -104,6 +106,6 @@ pub fn find_seq_n<M, T, I, F>(n: uint,
b.iter(|| {
let x = find(map, i);
i = (i + 1) % n;
x
black_box(x);
})
}
66 changes: 45 additions & 21 deletions src/libcollections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub use self::Entry::*;

use core::prelude::*;

use core::borrow::BorrowFrom;
use core::borrow::{BorrowFrom, ToOwned};
use core::cmp::Ordering;
use core::default::Default;
use core::fmt::Show;
Expand Down Expand Up @@ -128,20 +128,23 @@ pub struct Values<'a, K: 'a, V: 'a> {
inner: Map<(&'a K, &'a V), &'a V, Iter<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>
}

#[stable]
/// A view into a single entry in a map, which may either be vacant or occupied.
pub enum Entry<'a, K:'a, V:'a> {
pub enum Entry<'a, Sized? Q:'a, K:'a, V:'a> {
/// A vacant Entry
Vacant(VacantEntry<'a, K, V>),
Vacant(VacantEntry<'a, Q, K, V>),
/// An occupied Entry
Occupied(OccupiedEntry<'a, K, V>),
}

#[stable]
/// A vacant Entry.
pub struct VacantEntry<'a, K:'a, V:'a> {
key: K,
pub struct VacantEntry<'a, Sized? Q:'a, K:'a, V:'a> {
key: &'a Q,
stack: stack::SearchStack<'a, K, V, node::handle::Edge, node::handle::Leaf>,
}

#[stable]
/// An occupied Entry.
pub struct OccupiedEntry<'a, K:'a, V:'a> {
stack: stack::SearchStack<'a, K, V, node::handle::KV, node::handle::LeafOrInternal>,
Expand Down Expand Up @@ -1132,40 +1135,56 @@ impl<'a, K, V> DoubleEndedIterator for Values<'a, K, V> {
#[stable]
impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {}

impl<'a, Sized? Q, K: Ord, V> Entry<'a, Q, K, V> {
#[unstable = "matches collection reform v2 specification, waiting for dust to settle"]
/// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, Q, K, V>> {
match self {
Occupied(entry) => Ok(entry.into_mut()),
Vacant(entry) => Err(entry),
}
}
}

impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
impl<'a, Sized? Q: ToOwned<K>, K: Ord, V> VacantEntry<'a, Q, K, V> {
#[stable]
/// Sets the value of the entry with the VacantEntry's key,
/// and returns a mutable reference to it.
pub fn set(self, value: V) -> &'a mut V {
self.stack.insert(self.key, value)
pub fn insert(self, value: V) -> &'a mut V {
self.stack.insert(self.key.to_owned(), value)
}
}

impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
#[stable]
/// Gets a reference to the value in the entry.
pub fn get(&self) -> &V {
self.stack.peek()
}

#[stable]
/// Gets a mutable reference to the value in the entry.
pub fn get_mut(&mut self) -> &mut V {
self.stack.peek_mut()
}

#[stable]
/// Converts the entry into a mutable reference to its value.
pub fn into_mut(self) -> &'a mut V {
self.stack.into_top()
}

#[stable]
/// Sets the value of the entry with the OccupiedEntry's key,
/// and returns the entry's old value.
pub fn set(&mut self, mut value: V) -> V {
pub fn insert(&mut self, mut value: V) -> V {
mem::swap(self.stack.peek_mut(), &mut value);
value
}

#[stable]
/// Takes the value of the entry out of the map, and returns it.
pub fn take(self) -> V {
pub fn remove(self) -> V {
self.stack.remove()
}
}
Expand Down Expand Up @@ -1352,9 +1371,9 @@ impl<K: Ord, V> BTreeMap<K, V> {
///
/// // count the number of occurrences of letters in the vec
/// for x in vec!["a","b","a","c","a","b"].iter() {
/// match count.entry(*x) {
/// match count.entry(x) {
/// Entry::Vacant(view) => {
/// view.set(1);
/// view.insert(1);
/// },
/// Entry::Occupied(mut view) => {
/// let v = view.get_mut();
Expand All @@ -1365,12 +1384,16 @@ impl<K: Ord, V> BTreeMap<K, V> {
///
/// assert_eq!(count["a"], 3u);
/// ```
pub fn entry<'a>(&'a mut self, mut key: K) -> Entry<'a, K, V> {
/// The key must have the same ordering before or after `.to_owned()` is called.
#[stable]
pub fn entry<'a, Sized? Q>(&'a mut self, mut key: &'a Q) -> Entry<'a, Q, K, V>
where Q: Ord + ToOwned<K>
{
// same basic logic of `swap` and `pop`, blended together
let mut stack = stack::PartialSearchStack::new(self);
loop {
let result = stack.with(move |pusher, node| {
return match Node::search(node, &key) {
return match Node::search(node, key) {
Found(handle) => {
// Perfect match
Finished(Occupied(OccupiedEntry {
Expand Down Expand Up @@ -1413,6 +1436,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
#[cfg(test)]
mod test {
use prelude::*;
use std::borrow::{ToOwned, BorrowFrom};

use super::{BTreeMap, Occupied, Vacant};

Expand Down Expand Up @@ -1562,19 +1586,19 @@ mod test {
let mut map: BTreeMap<int, int> = xs.iter().map(|&x| x).collect();

// Existing key (insert)
match map.entry(1) {
match map.entry(&1) {
Vacant(_) => unreachable!(),
Occupied(mut view) => {
assert_eq!(view.get(), &10);
assert_eq!(view.set(100), 10);
assert_eq!(view.insert(100), 10);
}
}
assert_eq!(map.get(&1).unwrap(), &100);
assert_eq!(map.len(), 6);


// Existing key (update)
match map.entry(2) {
match map.entry(&2) {
Vacant(_) => unreachable!(),
Occupied(mut view) => {
let v = view.get_mut();
Expand All @@ -1585,21 +1609,21 @@ mod test {
assert_eq!(map.len(), 6);

// Existing key (take)
match map.entry(3) {
match map.entry(&3) {
Vacant(_) => unreachable!(),
Occupied(view) => {
assert_eq!(view.take(), 30);
assert_eq!(view.remove(), 30);
}
}
assert_eq!(map.get(&3), None);
assert_eq!(map.len(), 5);


// Inexistent key (insert)
match map.entry(10) {
match map.entry(&10) {
Occupied(_) => unreachable!(),
Vacant(view) => {
assert_eq!(*view.set(1000), 1000);
assert_eq!(*view.insert(1000), 1000);
}
}
assert_eq!(map.get(&10).unwrap(), &1000);
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1329,8 +1329,8 @@ impl UnusedMut {
let ident = path1.node;
if let ast::BindByValue(ast::MutMutable) = mode {
if !token::get_ident(ident).get().starts_with("_") {
match mutables.entry(ident.name.uint()) {
Vacant(entry) => { entry.set(vec![id]); },
match mutables.entry(&ident.name.uint()) {
Vacant(entry) => { entry.insert(vec![id]); },
Occupied(mut entry) => { entry.get_mut().push(id); },
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ fn dump_crates(cstore: &CStore) {
fn warn_if_multiple_versions(diag: &SpanHandler, cstore: &CStore) {
let mut map = FnvHashMap::new();
cstore.iter_crate_data(|cnum, data| {
match map.entry(data.name()) {
Vacant(entry) => { entry.set(vec![cnum]); },
match map.entry(&data.name()) {
Vacant(entry) => { entry.insert(vec![cnum]); },
Occupied(mut entry) => { entry.get_mut().push(cnum); },
}
});
Expand Down
8 changes: 3 additions & 5 deletions src/librustc/metadata/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,6 @@ use util::fs;

use std::c_str::ToCStr;
use std::cmp;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::collections::{HashMap, HashSet};
use std::io::fs::PathExtensions;
use std::io;
Expand Down Expand Up @@ -400,10 +399,9 @@ impl<'a> Context<'a> {
};
info!("lib candidate: {}", path.display());

let slot = match candidates.entry(hash.to_string()) {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => entry.set((HashSet::new(), HashSet::new())),
};
let hash_str = hash.to_string();
let slot = candidates.entry(&hash_str).get().unwrap_or_else(
|vacant_entry| vacant_entry.insert((HashSet::new(), HashSet::new())));
let (ref mut rlibs, ref mut dylibs) = *slot;
if rlib {
rlibs.insert(fs::realpath(path).unwrap());
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,8 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr) -> P<ast::Pat> {

ast::ExprCall(ref callee, ref args) => {
let def = tcx.def_map.borrow()[callee.id].clone();
if let Vacant(entry) = tcx.def_map.borrow_mut().entry(expr.id) {
entry.set(def);
if let Vacant(entry) = tcx.def_map.borrow_mut().entry(&expr.id) {
entry.insert(def);
}
let path = match def {
def::DefStruct(def_id) => def_to_path(tcx, def_id),
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/infer/freshen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,13 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
None => { }
}

match self.freshen_map.entry(key) {
match self.freshen_map.entry(&key) {
Entry::Occupied(entry) => *entry.get(),
Entry::Vacant(entry) => {
let index = self.freshen_count;
self.freshen_count += 1;
let t = ty::mk_infer(self.infcx.tcx, freshener(index));
entry.set(t);
entry.insert(t);
t
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/infer/region_inference/graphviz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ impl<'a, 'tcx> ConstraintGraph<'a, 'tcx> {
let mut node_ids = FnvHashMap::new();
{
let mut add_node = |&mut : node| {
if let Vacant(e) = node_ids.entry(node) {
e.set(i);
if let Vacant(e) = node_ids.entry(&node) {
e.insert(i);
i += 1;
}
};
Expand Down
5 changes: 3 additions & 2 deletions src/librustc/middle/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,8 +437,9 @@ fn register_region_obligation<'tcx>(tcx: &ty::ctxt<'tcx>,
debug!("register_region_obligation({})",
region_obligation.repr(tcx));

match region_obligations.entry(region_obligation.cause.body_id) {
Vacant(entry) => { entry.set(vec![region_obligation]); },
let body_id = region_obligation.cause.body_id;
match region_obligations.entry(&body_id) {
Vacant(entry) => { entry.insert(vec![region_obligation]); },
Occupied(mut entry) => { entry.get_mut().push(region_obligation); },
}

Expand Down
13 changes: 4 additions & 9 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ use std::ops;
use std::rc::Rc;
use collections::enum_set::{EnumSet, CLike};
use std::collections::{HashMap, HashSet};
use std::collections::hash_map::Entry::{Occupied, Vacant};
use syntax::abi;
use syntax::ast::{CrateNum, DefId, Ident, ItemTrait, LOCAL_CRATE};
use syntax::ast::{MutImmutable, MutMutable, Name, NamedField, NodeId};
Expand Down Expand Up @@ -5651,10 +5650,8 @@ pub fn lookup_field_type<'tcx>(tcx: &ctxt<'tcx>,
node_id_to_type(tcx, id.node)
} else {
let mut tcache = tcx.tcache.borrow_mut();
let pty = match tcache.entry(id) {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => entry.set(csearch::get_field_type(tcx, struct_id, id)),
};
let pty = tcache.entry(&id).get().unwrap_or_else(
|vacant_entry| vacant_entry.insert(csearch::get_field_type(tcx, struct_id, id)));
pty.ty
};
ty.subst(tcx, substs)
Expand Down Expand Up @@ -6841,10 +6838,8 @@ pub fn replace_late_bound_regions<'tcx, T, F>(
debug!("region={}", region.repr(tcx));
match region {
ty::ReLateBound(debruijn, br) if debruijn.depth == current_depth => {
* match map.entry(br) {
Vacant(entry) => entry.set(mapf(br, debruijn)),
Occupied(entry) => entry.into_mut(),
}
* map.entry(&br).get().unwrap_or_else(
|vacant_entry| vacant_entry.insert(mapf(br, debruijn)))
}
_ => {
region
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1114,8 +1114,8 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
None => early_error("--extern value must be of the format `foo=bar`"),
};

match externs.entry(name.to_string()) {
Vacant(entry) => { entry.set(vec![location.to_string()]); },
match externs.entry(&name.to_string()) {
Vacant(entry) => { entry.insert(vec![location.to_string()]); },
Occupied(mut entry) => { entry.get_mut().push(location.to_string()); },
}
}
Expand Down
Loading

7 comments on commit 400c3a0

@bors
Copy link
Contributor

@bors bors commented on 400c3a0 Jan 5, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on 400c3a0 Jan 5, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging bfops/rust/master = 400c3a0 into auto

@bors
Copy link
Contributor

@bors bors commented on 400c3a0 Jan 5, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

status: {"merge_sha": "ad9e759382ad7daed26f86732f41f5f83cd673e2"}

@bors
Copy link
Contributor

@bors bors commented on 400c3a0 Jan 5, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bfops/rust/master = 400c3a0 merged ok, testing candidate = ad9e759

@bors
Copy link
Contributor

@bors bors commented on 400c3a0 Jan 5, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = ad9e759

@bors
Copy link
Contributor

@bors bors commented on 400c3a0 Jan 5, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = ad9e759

Please sign in to comment.