Skip to content

Commit 400c3a0

Browse files
committed
[breaking change] Update entry API as part of RFC 509.
1 parent 260e461 commit 400c3a0

File tree

20 files changed

+170
-135
lines changed

20 files changed

+170
-135
lines changed

src/libcollections/bench.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use prelude::*;
1212
use std::rand;
1313
use std::rand::Rng;
14-
use test::Bencher;
14+
use test::{Bencher, black_box};
1515

1616
pub fn insert_rand_n<M, I, R>(n: uint,
1717
map: &mut M,
@@ -33,7 +33,8 @@ pub fn insert_rand_n<M, I, R>(n: uint,
3333
let k = rng.gen::<uint>() % n;
3434
insert(map, k);
3535
remove(map, k);
36-
})
36+
});
37+
black_box(map);
3738
}
3839

3940
pub fn insert_seq_n<M, I, R>(n: uint,
@@ -55,7 +56,8 @@ pub fn insert_seq_n<M, I, R>(n: uint,
5556
insert(map, i);
5657
remove(map, i);
5758
i = (i + 2) % n;
58-
})
59+
});
60+
black_box(map);
5961
}
6062

6163
pub fn find_rand_n<M, T, I, F>(n: uint,
@@ -82,7 +84,7 @@ pub fn find_rand_n<M, T, I, F>(n: uint,
8284
b.iter(|| {
8385
let t = find(map, keys[i]);
8486
i = (i + 1) % n;
85-
t
87+
black_box(t);
8688
})
8789
}
8890

@@ -104,6 +106,6 @@ pub fn find_seq_n<M, T, I, F>(n: uint,
104106
b.iter(|| {
105107
let x = find(map, i);
106108
i = (i + 1) % n;
107-
x
109+
black_box(x);
108110
})
109111
}

src/libcollections/btree/map.rs

+45-21
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub use self::Entry::*;
1919

2020
use core::prelude::*;
2121

22-
use core::borrow::BorrowFrom;
22+
use core::borrow::{BorrowFrom, ToOwned};
2323
use core::cmp::Ordering;
2424
use core::default::Default;
2525
use core::fmt::Show;
@@ -128,20 +128,23 @@ pub struct Values<'a, K: 'a, V: 'a> {
128128
inner: Map<(&'a K, &'a V), &'a V, Iter<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>
129129
}
130130

131+
#[stable]
131132
/// A view into a single entry in a map, which may either be vacant or occupied.
132-
pub enum Entry<'a, K:'a, V:'a> {
133+
pub enum Entry<'a, Sized? Q:'a, K:'a, V:'a> {
133134
/// A vacant Entry
134-
Vacant(VacantEntry<'a, K, V>),
135+
Vacant(VacantEntry<'a, Q, K, V>),
135136
/// An occupied Entry
136137
Occupied(OccupiedEntry<'a, K, V>),
137138
}
138139

140+
#[stable]
139141
/// A vacant Entry.
140-
pub struct VacantEntry<'a, K:'a, V:'a> {
141-
key: K,
142+
pub struct VacantEntry<'a, Sized? Q:'a, K:'a, V:'a> {
143+
key: &'a Q,
142144
stack: stack::SearchStack<'a, K, V, node::handle::Edge, node::handle::Leaf>,
143145
}
144146

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

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

1136-
impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
1149+
impl<'a, Sized? Q: ToOwned<K>, K: Ord, V> VacantEntry<'a, Q, K, V> {
1150+
#[stable]
11371151
/// Sets the value of the entry with the VacantEntry's key,
11381152
/// and returns a mutable reference to it.
1139-
pub fn set(self, value: V) -> &'a mut V {
1140-
self.stack.insert(self.key, value)
1153+
pub fn insert(self, value: V) -> &'a mut V {
1154+
self.stack.insert(self.key.to_owned(), value)
11411155
}
11421156
}
11431157

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

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

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

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

1185+
#[stable]
11671186
/// Takes the value of the entry out of the map, and returns it.
1168-
pub fn take(self) -> V {
1187+
pub fn remove(self) -> V {
11691188
self.stack.remove()
11701189
}
11711190
}
@@ -1352,9 +1371,9 @@ impl<K: Ord, V> BTreeMap<K, V> {
13521371
///
13531372
/// // count the number of occurrences of letters in the vec
13541373
/// for x in vec!["a","b","a","c","a","b"].iter() {
1355-
/// match count.entry(*x) {
1374+
/// match count.entry(x) {
13561375
/// Entry::Vacant(view) => {
1357-
/// view.set(1);
1376+
/// view.insert(1);
13581377
/// },
13591378
/// Entry::Occupied(mut view) => {
13601379
/// let v = view.get_mut();
@@ -1365,12 +1384,16 @@ impl<K: Ord, V> BTreeMap<K, V> {
13651384
///
13661385
/// assert_eq!(count["a"], 3u);
13671386
/// ```
1368-
pub fn entry<'a>(&'a mut self, mut key: K) -> Entry<'a, K, V> {
1387+
/// The key must have the same ordering before or after `.to_owned()` is called.
1388+
#[stable]
1389+
pub fn entry<'a, Sized? Q>(&'a mut self, mut key: &'a Q) -> Entry<'a, Q, K, V>
1390+
where Q: Ord + ToOwned<K>
1391+
{
13691392
// same basic logic of `swap` and `pop`, blended together
13701393
let mut stack = stack::PartialSearchStack::new(self);
13711394
loop {
13721395
let result = stack.with(move |pusher, node| {
1373-
return match Node::search(node, &key) {
1396+
return match Node::search(node, key) {
13741397
Found(handle) => {
13751398
// Perfect match
13761399
Finished(Occupied(OccupiedEntry {
@@ -1413,6 +1436,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
14131436
#[cfg(test)]
14141437
mod test {
14151438
use prelude::*;
1439+
use std::borrow::{ToOwned, BorrowFrom};
14161440

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

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

15641588
// Existing key (insert)
1565-
match map.entry(1) {
1589+
match map.entry(&1) {
15661590
Vacant(_) => unreachable!(),
15671591
Occupied(mut view) => {
15681592
assert_eq!(view.get(), &10);
1569-
assert_eq!(view.set(100), 10);
1593+
assert_eq!(view.insert(100), 10);
15701594
}
15711595
}
15721596
assert_eq!(map.get(&1).unwrap(), &100);
15731597
assert_eq!(map.len(), 6);
15741598

15751599

15761600
// Existing key (update)
1577-
match map.entry(2) {
1601+
match map.entry(&2) {
15781602
Vacant(_) => unreachable!(),
15791603
Occupied(mut view) => {
15801604
let v = view.get_mut();
@@ -1585,21 +1609,21 @@ mod test {
15851609
assert_eq!(map.len(), 6);
15861610

15871611
// Existing key (take)
1588-
match map.entry(3) {
1612+
match map.entry(&3) {
15891613
Vacant(_) => unreachable!(),
15901614
Occupied(view) => {
1591-
assert_eq!(view.take(), 30);
1615+
assert_eq!(view.remove(), 30);
15921616
}
15931617
}
15941618
assert_eq!(map.get(&3), None);
15951619
assert_eq!(map.len(), 5);
15961620

15971621

15981622
// Inexistent key (insert)
1599-
match map.entry(10) {
1623+
match map.entry(&10) {
16001624
Occupied(_) => unreachable!(),
16011625
Vacant(view) => {
1602-
assert_eq!(*view.set(1000), 1000);
1626+
assert_eq!(*view.insert(1000), 1000);
16031627
}
16041628
}
16051629
assert_eq!(map.get(&10).unwrap(), &1000);

src/librustc/lint/builtin.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1329,8 +1329,8 @@ impl UnusedMut {
13291329
let ident = path1.node;
13301330
if let ast::BindByValue(ast::MutMutable) = mode {
13311331
if !token::get_ident(ident).get().starts_with("_") {
1332-
match mutables.entry(ident.name.uint()) {
1333-
Vacant(entry) => { entry.set(vec![id]); },
1332+
match mutables.entry(&ident.name.uint()) {
1333+
Vacant(entry) => { entry.insert(vec![id]); },
13341334
Occupied(mut entry) => { entry.get_mut().push(id); },
13351335
}
13361336
}

src/librustc/metadata/creader.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ fn dump_crates(cstore: &CStore) {
8787
fn warn_if_multiple_versions(diag: &SpanHandler, cstore: &CStore) {
8888
let mut map = FnvHashMap::new();
8989
cstore.iter_crate_data(|cnum, data| {
90-
match map.entry(data.name()) {
91-
Vacant(entry) => { entry.set(vec![cnum]); },
90+
match map.entry(&data.name()) {
91+
Vacant(entry) => { entry.insert(vec![cnum]); },
9292
Occupied(mut entry) => { entry.get_mut().push(cnum); },
9393
}
9494
});

src/librustc/metadata/loader.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,6 @@ use util::fs;
228228

229229
use std::c_str::ToCStr;
230230
use std::cmp;
231-
use std::collections::hash_map::Entry::{Occupied, Vacant};
232231
use std::collections::{HashMap, HashSet};
233232
use std::io::fs::PathExtensions;
234233
use std::io;
@@ -400,10 +399,9 @@ impl<'a> Context<'a> {
400399
};
401400
info!("lib candidate: {}", path.display());
402401

403-
let slot = match candidates.entry(hash.to_string()) {
404-
Occupied(entry) => entry.into_mut(),
405-
Vacant(entry) => entry.set((HashSet::new(), HashSet::new())),
406-
};
402+
let hash_str = hash.to_string();
403+
let slot = candidates.entry(&hash_str).get().unwrap_or_else(
404+
|vacant_entry| vacant_entry.insert((HashSet::new(), HashSet::new())));
407405
let (ref mut rlibs, ref mut dylibs) = *slot;
408406
if rlib {
409407
rlibs.insert(fs::realpath(path).unwrap());

src/librustc/middle/const_eval.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,8 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr) -> P<ast::Pat> {
311311

312312
ast::ExprCall(ref callee, ref args) => {
313313
let def = tcx.def_map.borrow()[callee.id].clone();
314-
if let Vacant(entry) = tcx.def_map.borrow_mut().entry(expr.id) {
315-
entry.set(def);
314+
if let Vacant(entry) = tcx.def_map.borrow_mut().entry(&expr.id) {
315+
entry.insert(def);
316316
}
317317
let path = match def {
318318
def::DefStruct(def_id) => def_to_path(tcx, def_id),

src/librustc/middle/infer/freshen.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,13 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
6666
None => { }
6767
}
6868

69-
match self.freshen_map.entry(key) {
69+
match self.freshen_map.entry(&key) {
7070
Entry::Occupied(entry) => *entry.get(),
7171
Entry::Vacant(entry) => {
7272
let index = self.freshen_count;
7373
self.freshen_count += 1;
7474
let t = ty::mk_infer(self.infcx.tcx, freshener(index));
75-
entry.set(t);
75+
entry.insert(t);
7676
t
7777
}
7878
}

src/librustc/middle/infer/region_inference/graphviz.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ impl<'a, 'tcx> ConstraintGraph<'a, 'tcx> {
137137
let mut node_ids = FnvHashMap::new();
138138
{
139139
let mut add_node = |&mut : node| {
140-
if let Vacant(e) = node_ids.entry(node) {
141-
e.set(i);
140+
if let Vacant(e) = node_ids.entry(&node) {
141+
e.insert(i);
142142
i += 1;
143143
}
144144
};

src/librustc/middle/traits/fulfill.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -437,8 +437,9 @@ fn register_region_obligation<'tcx>(tcx: &ty::ctxt<'tcx>,
437437
debug!("register_region_obligation({})",
438438
region_obligation.repr(tcx));
439439

440-
match region_obligations.entry(region_obligation.cause.body_id) {
441-
Vacant(entry) => { entry.set(vec![region_obligation]); },
440+
let body_id = region_obligation.cause.body_id;
441+
match region_obligations.entry(&body_id) {
442+
Vacant(entry) => { entry.insert(vec![region_obligation]); },
442443
Occupied(mut entry) => { entry.get_mut().push(region_obligation); },
443444
}
444445

src/librustc/middle/ty.rs

+4-9
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ use std::ops;
7878
use std::rc::Rc;
7979
use collections::enum_set::{EnumSet, CLike};
8080
use std::collections::{HashMap, HashSet};
81-
use std::collections::hash_map::Entry::{Occupied, Vacant};
8281
use syntax::abi;
8382
use syntax::ast::{CrateNum, DefId, Ident, ItemTrait, LOCAL_CRATE};
8483
use syntax::ast::{MutImmutable, MutMutable, Name, NamedField, NodeId};
@@ -5651,10 +5650,8 @@ pub fn lookup_field_type<'tcx>(tcx: &ctxt<'tcx>,
56515650
node_id_to_type(tcx, id.node)
56525651
} else {
56535652
let mut tcache = tcx.tcache.borrow_mut();
5654-
let pty = match tcache.entry(id) {
5655-
Occupied(entry) => entry.into_mut(),
5656-
Vacant(entry) => entry.set(csearch::get_field_type(tcx, struct_id, id)),
5657-
};
5653+
let pty = tcache.entry(&id).get().unwrap_or_else(
5654+
|vacant_entry| vacant_entry.insert(csearch::get_field_type(tcx, struct_id, id)));
56585655
pty.ty
56595656
};
56605657
ty.subst(tcx, substs)
@@ -6841,10 +6838,8 @@ pub fn replace_late_bound_regions<'tcx, T, F>(
68416838
debug!("region={}", region.repr(tcx));
68426839
match region {
68436840
ty::ReLateBound(debruijn, br) if debruijn.depth == current_depth => {
6844-
* match map.entry(br) {
6845-
Vacant(entry) => entry.set(mapf(br, debruijn)),
6846-
Occupied(entry) => entry.into_mut(),
6847-
}
6841+
* map.entry(&br).get().unwrap_or_else(
6842+
|vacant_entry| vacant_entry.insert(mapf(br, debruijn)))
68486843
}
68496844
_ => {
68506845
region

src/librustc/session/config.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1114,8 +1114,8 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
11141114
None => early_error("--extern value must be of the format `foo=bar`"),
11151115
};
11161116

1117-
match externs.entry(name.to_string()) {
1118-
Vacant(entry) => { entry.set(vec![location.to_string()]); },
1117+
match externs.entry(&name.to_string()) {
1118+
Vacant(entry) => { entry.insert(vec![location.to_string()]); },
11191119
Occupied(mut entry) => { entry.get_mut().push(location.to_string()); },
11201120
}
11211121
}

0 commit comments

Comments
 (0)