@@ -25,11 +25,13 @@ use ops::{Deref, DerefMut};
25
25
use option:: { Some , None , Option } ;
26
26
use result:: { Ok , Err } ;
27
27
use ops:: Index ;
28
+ use core:: result:: Result ;
28
29
29
30
use super :: table;
30
31
use super :: table:: {
31
32
Bucket ,
32
33
Empty ,
34
+ EmptyBucket ,
33
35
Full ,
34
36
FullBucket ,
35
37
FullBucketImm ,
@@ -328,11 +330,11 @@ fn search_hashed<K: Eq, V, M: Deref<RawTable<K, V>>>(table: M, hash: &SafeHash,
328
330
search_hashed_generic ( table, hash, |k_| * k == * k_)
329
331
}
330
332
331
- fn pop_internal < K , V > ( starting_bucket : FullBucketMut < K , V > ) -> V {
332
- let ( empty, _k , retval) = starting_bucket. take ( ) ;
333
+ fn pop_internal < K , V > ( starting_bucket : FullBucketMut < K , V > ) -> ( K , V ) {
334
+ let ( empty, retkey , retval) = starting_bucket. take ( ) ;
333
335
let mut gap = match empty. gap_peek ( ) {
334
336
Some ( b) => b,
335
- None => return retval
337
+ None => return ( retkey , retval)
336
338
} ;
337
339
338
340
while gap. full ( ) . distance ( ) != 0 {
@@ -343,7 +345,7 @@ fn pop_internal<K, V>(starting_bucket: FullBucketMut<K, V>) -> V {
343
345
}
344
346
345
347
// Now we've done all our shifting. Return the value we grabbed earlier.
346
- return retval;
348
+ return ( retkey , retval) ;
347
349
}
348
350
349
351
/// Perform robin hood bucket stealing at the given `bucket`. You must
@@ -567,7 +569,8 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> MutableMap<K, V> for HashMap<K, V, H>
567
569
self . make_some_room ( potential_new_size) ;
568
570
569
571
self . search_mut ( k) . map ( |bucket| {
570
- pop_internal ( bucket)
572
+ let ( _k, val) = pop_internal ( bucket) ;
573
+ val
571
574
} )
572
575
}
573
576
}
@@ -867,6 +870,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
867
870
/// // Find the existing key
868
871
/// assert_eq!(*map.find_or_insert("a", -2), 1);
869
872
/// ```
873
+ #[ deprecated = "use entry instead" ]
870
874
pub fn find_or_insert ( & mut self , k : K , v : V ) -> & mut V {
871
875
self . find_with_or_insert_with ( k, v, |_k, _v, _a| ( ) , |_k, a| a)
872
876
}
@@ -886,6 +890,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
886
890
/// // Find the existing key
887
891
/// assert_eq!(*map.find_or_insert_with(2, |&key| key as uint), 10);
888
892
/// ```
893
+ #[ deprecated = "use entry instead" ]
889
894
pub fn find_or_insert_with < ' a > ( & ' a mut self , k : K , f: |& K | -> V )
890
895
-> & ' a mut V {
891
896
self . find_with_or_insert_with ( k, ( ) , |_k, _v, _a| ( ) , |k, _a| f ( k) )
@@ -908,6 +913,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
908
913
/// assert_eq!(*map.insert_or_update_with("a", 9, |_key, val| *val = 7), 7);
909
914
/// assert_eq!(map["a"], 7);
910
915
/// ```
916
+ #[ deprecated = "use entry instead" ]
911
917
pub fn insert_or_update_with < ' a > (
912
918
& ' a mut self ,
913
919
k : K ,
@@ -965,6 +971,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
965
971
/// assert_eq!(map["b key"], vec!["new value"]);
966
972
/// assert_eq!(map["z key"], vec!["new value", "value"]);
967
973
/// ```
974
+ #[ deprecated = "use entry instead" ]
968
975
pub fn find_with_or_insert_with < ' a , A > ( & ' a mut self ,
969
976
k : K ,
970
977
a : A ,
@@ -1124,7 +1131,8 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
1124
1131
1125
1132
match self . search_equiv_mut ( k) {
1126
1133
Some ( bucket) => {
1127
- Some ( pop_internal ( bucket) )
1134
+ let ( _k, val) = pop_internal ( bucket) ;
1135
+ Some ( val)
1128
1136
}
1129
1137
_ => None
1130
1138
}
@@ -1254,6 +1262,70 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
1254
1262
inner : self . table . into_iter ( ) . map ( |( _, k, v) | ( k, v) )
1255
1263
}
1256
1264
}
1265
+
1266
+ /// Gets the given key's corresponding entry in the map for in-place manipulation
1267
+ pub fn entry < ' a > ( & ' a mut self , key : K ) -> Entry < ' a , K , V > {
1268
+ // Gotta resize now, and we don't know which direction, so try both?
1269
+ let size = self . table . size ( ) ;
1270
+ self . make_some_room ( size + 1 ) ;
1271
+ if size > 0 {
1272
+ self . make_some_room ( size - 1 ) ;
1273
+ }
1274
+
1275
+ let hash = self . make_hash ( & key) ;
1276
+ search_entry_hashed ( & mut self . table , hash, key)
1277
+ }
1278
+ }
1279
+
1280
+ fn search_entry_hashed < ' a , K : Eq , V > ( table : & ' a mut RawTable < K , V > , hash : SafeHash , k : K )
1281
+ -> Entry < ' a , K , V > {
1282
+ // Worst case, we'll find one empty bucket among `size + 1` buckets.
1283
+ let size = table. size ( ) ;
1284
+ let mut probe = Bucket :: new ( table, & hash) ;
1285
+ let ib = probe. index ( ) ;
1286
+
1287
+ loop {
1288
+ let bucket = match probe. peek ( ) {
1289
+ Empty ( bucket) => {
1290
+ // Found a hole!
1291
+ return Vacant ( VacantEntry {
1292
+ hash : hash,
1293
+ key : k,
1294
+ elem : NoElem ( bucket) ,
1295
+ } ) ;
1296
+ } ,
1297
+ Full ( bucket) => bucket
1298
+ } ;
1299
+
1300
+ if bucket. hash ( ) == hash {
1301
+ let is_eq = {
1302
+ let ( bucket_k, _) = bucket. read ( ) ;
1303
+ k == * bucket_k
1304
+ } ;
1305
+
1306
+ if is_eq {
1307
+ return Occupied ( OccupiedEntry {
1308
+ hash : hash,
1309
+ key : k,
1310
+ elem : bucket,
1311
+ } ) ;
1312
+ }
1313
+ }
1314
+
1315
+ let robin_ib = bucket. index ( ) as int - bucket. distance ( ) as int ;
1316
+
1317
+ if ( ib as int ) < robin_ib {
1318
+ // Found a luckier bucket than me. Better steal his spot.
1319
+ return Vacant ( VacantEntry {
1320
+ hash : hash,
1321
+ key : k,
1322
+ elem : NeqElem ( bucket, robin_ib as uint ) ,
1323
+ } ) ;
1324
+ }
1325
+
1326
+ probe = bucket. next ( ) ;
1327
+ assert ! ( probe. index( ) != ib + size + 1 ) ;
1328
+ }
1257
1329
}
1258
1330
1259
1331
impl < K : Eq + Hash < S > , V : Clone , S , H : Hasher < S > > HashMap < K , V , H > {
@@ -1353,6 +1425,34 @@ pub struct MoveEntries<K, V> {
1353
1425
inner : iter:: Map < ' static , ( SafeHash , K , V ) , ( K , V ) , table:: MoveEntries < K , V > >
1354
1426
}
1355
1427
1428
+ /// A view into a single occupied location in a HashMap
1429
+ pub struct OccupiedEntry < ' a , K : ' a , V : ' a > {
1430
+ hash : SafeHash ,
1431
+ key : K ,
1432
+ elem : FullBucket < K , V , & ' a mut RawTable < K , V > > ,
1433
+ }
1434
+
1435
+ /// A view into a single empty location in a HashMap
1436
+ pub struct VacantEntry < ' a , K : ' a , V : ' a > {
1437
+ hash : SafeHash ,
1438
+ key : K ,
1439
+ elem : VacantEntryState < K , V , & ' a mut RawTable < K , V > > ,
1440
+ }
1441
+
1442
+ /// A view into a single location in a map, which may be vacant or occupied
1443
+ pub enum Entry < ' a , K : ' a , V : ' a > {
1444
+ /// An occupied Entry
1445
+ Occupied ( OccupiedEntry < ' a , K , V > ) ,
1446
+ /// A vacant Entry
1447
+ Vacant ( VacantEntry < ' a , K , V > ) ,
1448
+ }
1449
+
1450
+ /// Possible states of a VacantEntry
1451
+ enum VacantEntryState < K , V , M > {
1452
+ NeqElem ( FullBucket < K , V , M > , uint ) ,
1453
+ NoElem ( EmptyBucket < K , V , M > ) ,
1454
+ }
1455
+
1356
1456
impl < ' a , K , V > Iterator < ( & ' a K , & ' a V ) > for Entries < ' a , K , V > {
1357
1457
#[ inline]
1358
1458
fn next ( & mut self ) -> Option < ( & ' a K , & ' a V ) > {
@@ -1386,6 +1486,64 @@ impl<K, V> Iterator<(K, V)> for MoveEntries<K, V> {
1386
1486
}
1387
1487
}
1388
1488
1489
+ impl < ' a , K , V > OccupiedEntry < ' a , K , V > {
1490
+ /// Gets a reference to the value in the entry
1491
+ pub fn get ( & self ) -> & V {
1492
+ let ( _, v) = self . elem . read ( ) ;
1493
+ v
1494
+ }
1495
+
1496
+ /// Gets a mutable reference to the value in the entry
1497
+ pub fn get_mut ( & mut self ) -> & mut V {
1498
+ let ( _, v) = self . elem . read_mut ( ) ;
1499
+ v
1500
+ }
1501
+
1502
+ /// Converts the OccupiedEntry into a mutable reference to the value in the entry
1503
+ /// with a lifetime bound to the map itself
1504
+ pub fn into_mut ( self ) -> & ' a mut V {
1505
+ let ( _, v) = self . elem . into_mut_refs ( ) ;
1506
+ v
1507
+ }
1508
+
1509
+ /// Sets the value of the entry with the OccupiedEntry's key, and returns the entry's old value
1510
+ pub fn set ( mut self , value : V ) -> V {
1511
+ let ( _, _, v) = self . elem . replace ( self . hash , self . key , value) ;
1512
+ v
1513
+ }
1514
+
1515
+ /// Takes the value out of the entry, and returns it
1516
+ pub fn take ( self ) -> V {
1517
+ let ( _, _, v) = self . elem . take ( ) ;
1518
+ v
1519
+ }
1520
+ }
1521
+
1522
+ impl < ' a , K , V > VacantEntry < ' a , K , V > {
1523
+ /// Sets the value of the entry with the VacantEntry's key,
1524
+ /// and returns a mutable reference to it
1525
+ pub fn set ( self , value : V ) -> & ' a mut V {
1526
+ match self . elem {
1527
+ NeqElem ( mut bucket, ib) => {
1528
+ // Capture a mutable ptr to bucket's contents now, since robin_hood will
1529
+ // steal the bucket, but we know that this is the location the inserted
1530
+ // value can be found at afterwards
1531
+ let val_ptr = {
1532
+ let ( _, v) = bucket. read_mut ( ) ;
1533
+ v as * mut _
1534
+ } ;
1535
+ robin_hood ( bucket, ib, self . hash , self . key , value) ;
1536
+ unsafe { & mut * val_ptr }
1537
+ }
1538
+ NoElem ( bucket) => {
1539
+ let full = bucket. put ( self . hash , self . key , value) ;
1540
+ let ( _, v) = full. into_mut_refs ( ) ;
1541
+ v
1542
+ }
1543
+ }
1544
+ }
1545
+ }
1546
+
1389
1547
/// HashMap keys iterator
1390
1548
pub type Keys < ' a , K , V > =
1391
1549
iter:: Map < ' static , ( & ' a K , & ' a V ) , & ' a K , Entries < ' a , K , V > > ;
@@ -1416,6 +1574,7 @@ mod test_map {
1416
1574
use prelude:: * ;
1417
1575
1418
1576
use super :: HashMap ;
1577
+ use super :: { Occupied , Vacant } ;
1419
1578
use cmp:: Equiv ;
1420
1579
use hash;
1421
1580
use iter:: { Iterator , range_inclusive, range_step_inclusive} ;
@@ -2026,4 +2185,56 @@ mod test_map {
2026
2185
2027
2186
map[ 4 ] ;
2028
2187
}
2188
+
2189
+ #[ test]
2190
+ fn test_entry ( ) {
2191
+ let xs = [ ( 1 i, 10 i) , ( 2 , 20 ) , ( 3 , 30 ) , ( 4 , 40 ) , ( 5 , 50 ) , ( 6 , 60 ) ] ;
2192
+
2193
+ let mut map: HashMap < int , int > = xs. iter ( ) . map ( |& x| x) . collect ( ) ;
2194
+
2195
+ // Existing key (insert)
2196
+ match map. entry ( 1 ) {
2197
+ Vacant ( _) => unreachable ! ( ) ,
2198
+ Occupied ( view) => {
2199
+ assert_eq ! ( view. get( ) , & 10 ) ;
2200
+ assert_eq ! ( view. set( 100 ) , 10 ) ;
2201
+ }
2202
+ }
2203
+ assert_eq ! ( map. find( & 1 ) . unwrap( ) , & 100 ) ;
2204
+ assert_eq ! ( map. len( ) , 6 ) ;
2205
+
2206
+
2207
+ // Existing key (update)
2208
+ match map. entry ( 2 ) {
2209
+ Vacant ( _) => unreachable ! ( ) ,
2210
+ Occupied ( mut view) => {
2211
+ let v = view. get_mut ( ) ;
2212
+ let new_v = ( * v) * 10 ;
2213
+ * v = new_v;
2214
+ }
2215
+ }
2216
+ assert_eq ! ( map. find( & 2 ) . unwrap( ) , & 200 ) ;
2217
+ assert_eq ! ( map. len( ) , 6 ) ;
2218
+
2219
+ // Existing key (take)
2220
+ match map. entry ( 3 ) {
2221
+ Vacant ( _) => unreachable ! ( ) ,
2222
+ Occupied ( view) => {
2223
+ assert_eq ! ( view. take( ) , 30 ) ;
2224
+ }
2225
+ }
2226
+ assert_eq ! ( map. find( & 3 ) , None ) ;
2227
+ assert_eq ! ( map. len( ) , 5 ) ;
2228
+
2229
+
2230
+ // Inexistent key (insert)
2231
+ match map. entry ( 10 ) {
2232
+ Occupied ( _) => unreachable ! ( ) ,
2233
+ Vacant ( view) => {
2234
+ assert_eq ! ( * view. set( 1000 ) , 1000 ) ;
2235
+ }
2236
+ }
2237
+ assert_eq ! ( map. find( & 10 ) . unwrap( ) , & 1000 ) ;
2238
+ assert_eq ! ( map. len( ) , 6 ) ;
2239
+ }
2029
2240
}
0 commit comments