@@ -25,12 +25,14 @@ 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
BucketWithTable ,
33
34
Empty ,
35
+ EmptyBucket ,
34
36
Full ,
35
37
FullBucket ,
36
38
FullBucketImm ,
@@ -286,11 +288,11 @@ fn search_hashed<K: Eq, V, M: Deref<RawTable<K, V>>>(table: M, hash: &SafeHash,
286
288
search_hashed_generic ( table, hash, |k_| * k == * k_)
287
289
}
288
290
289
- fn pop_internal < K , V > ( starting_bucket : FullBucketMut < K , V > ) -> V {
290
- let ( empty, _k , retval) = starting_bucket. take ( ) ;
291
+ fn pop_internal < K , V > ( starting_bucket : FullBucketMut < K , V > ) -> ( K , V ) {
292
+ let ( empty, retkey , retval) = starting_bucket. take ( ) ;
291
293
let mut gap = match empty. gap_peek ( ) {
292
294
Some ( b) => b,
293
- None => return retval
295
+ None => return ( retkey , retval)
294
296
} ;
295
297
296
298
while gap. full ( ) . distance ( ) != 0 {
@@ -301,7 +303,7 @@ fn pop_internal<K, V>(starting_bucket: FullBucketMut<K, V>) -> V {
301
303
}
302
304
303
305
// Now we've done all our shifting. Return the value we grabbed earlier.
304
- return retval;
306
+ return ( retkey , retval) ;
305
307
}
306
308
307
309
/// Perform robin hood bucket stealing at the given `bucket`. You must
@@ -525,7 +527,8 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> MutableMap<K, V> for HashMap<K, V, H>
525
527
self . make_some_room ( potential_new_size) ;
526
528
527
529
self . search_mut ( k) . map ( |bucket| {
528
- pop_internal ( bucket)
530
+ let ( _k, val) = pop_internal ( bucket) ;
531
+ val
529
532
} )
530
533
}
531
534
}
@@ -855,6 +858,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
855
858
/// // Find the existing key
856
859
/// assert_eq!(*map.find_or_insert("a", -2), 1);
857
860
/// ```
861
+ //#[deprecated = "use view instead"]
858
862
pub fn find_or_insert ( & mut self , k : K , v : V ) -> & mut V {
859
863
self . find_with_or_insert_with ( k, v, |_k, _v, _a| ( ) , |_k, a| a)
860
864
}
@@ -874,6 +878,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
874
878
/// // Find the existing key
875
879
/// assert_eq!(*map.find_or_insert_with(2, |&key| key as uint), 10);
876
880
/// ```
881
+ //#[deprecated = "use view instead"]
877
882
pub fn find_or_insert_with < ' a > ( & ' a mut self , k : K , f: |& K | -> V )
878
883
-> & ' a mut V {
879
884
self . find_with_or_insert_with ( k, ( ) , |_k, _v, _a| ( ) , |k, _a| f ( k) )
@@ -896,6 +901,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
896
901
/// assert_eq!(*map.insert_or_update_with("a", 9, |_key, val| *val = 7), 7);
897
902
/// assert_eq!(map["a"], 7);
898
903
/// ```
904
+ //#[deprecated = "use view instead"]
899
905
pub fn insert_or_update_with < ' a > (
900
906
& ' a mut self ,
901
907
k : K ,
@@ -953,6 +959,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
953
959
/// assert_eq!(map["b key"], vec!["new value"]);
954
960
/// assert_eq!(map["z key"], vec!["new value", "value"]);
955
961
/// ```
962
+ //#[deprecated = "use view instead"]
956
963
pub fn find_with_or_insert_with < ' a , A > ( & ' a mut self ,
957
964
k : K ,
958
965
a : A ,
@@ -1112,7 +1119,8 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
1112
1119
1113
1120
match self . search_equiv_mut ( k) {
1114
1121
Some ( bucket) => {
1115
- Some ( pop_internal ( bucket) )
1122
+ let ( _k, val) = pop_internal ( bucket) ;
1123
+ Some ( val)
1116
1124
}
1117
1125
_ => None
1118
1126
}
@@ -1230,6 +1238,55 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
1230
1238
inner : self . table . move_iter ( ) . map ( |( _, k, v) | ( k, v) )
1231
1239
}
1232
1240
}
1241
+
1242
+ /// Creates a view into a single spot in the map for inplace manipulation
1243
+ pub fn view < ' a > ( & ' a mut self , key : K ) -> Entry < ' a , K , V > {
1244
+ let potential_new_size = self . table . size ( ) + 1 ;
1245
+ self . make_some_room ( potential_new_size) ;
1246
+
1247
+ let hash = self . make_hash ( & key) ;
1248
+ let elem = search_entry_hashed ( & mut self . table , & hash, & key) ;
1249
+ Entry { key : key, hash : hash, elem : elem }
1250
+ }
1251
+ }
1252
+
1253
+ fn search_entry_hashed < ' a , K : Eq , V > ( table : & ' a mut RawTable < K , V > , hash : & SafeHash , k : & K )
1254
+ -> EntryState < K , V , & ' a mut RawTable < K , V > > {
1255
+ // Worst case, we'll find one empty bucket among `size + 1` buckets.
1256
+ let size = table. size ( ) ;
1257
+ let mut probe = Bucket :: new ( table, hash) ;
1258
+ let ib = probe. index ( ) ;
1259
+
1260
+ loop {
1261
+ let bucket = match probe. peek ( ) {
1262
+ Empty ( bucket) => {
1263
+ // Found a hole!
1264
+ return NoElem ( bucket) ;
1265
+ } ,
1266
+ Full ( bucket) => bucket
1267
+ } ;
1268
+
1269
+ if bucket. hash ( ) == * hash {
1270
+ let is_eq = {
1271
+ let ( bucket_k, _) = bucket. read ( ) ;
1272
+ * k == * bucket_k
1273
+ } ;
1274
+
1275
+ if is_eq {
1276
+ return EqElem ( bucket) ;
1277
+ }
1278
+ }
1279
+
1280
+ let robin_ib = bucket. index ( ) as int - bucket. distance ( ) as int ;
1281
+
1282
+ if ( ib as int ) < robin_ib {
1283
+ // Found a luckier bucket than me. Better steal his spot.
1284
+ return NeqElem ( bucket, robin_ib as uint ) ;
1285
+ }
1286
+
1287
+ probe = bucket. next ( ) ;
1288
+ assert ! ( probe. index( ) != ib + size + 1 ) ;
1289
+ }
1233
1290
}
1234
1291
1235
1292
impl < K : Eq + Hash < S > , V : Clone , S , H : Hasher < S > > HashMap < K , V , H > {
@@ -1329,6 +1386,20 @@ pub struct MoveEntries<K, V> {
1329
1386
inner : iter:: Map < ' static , ( SafeHash , K , V ) , ( K , V ) , table:: MoveEntries < K , V > >
1330
1387
}
1331
1388
1389
+ /// Possible states of an Entry
1390
+ enum EntryState < K , V , M > {
1391
+ EqElem ( FullBucket < K , V , M > ) ,
1392
+ NeqElem ( FullBucket < K , V , M > , uint ) ,
1393
+ NoElem ( EmptyBucket < K , V , M > ) ,
1394
+ }
1395
+
1396
+ /// Mutable View into a HashMap's index
1397
+ pub struct Entry < ' a , K , V > {
1398
+ hash : SafeHash ,
1399
+ key : K ,
1400
+ elem : EntryState < K , V , & ' a mut RawTable < K , V > > ,
1401
+ }
1402
+
1332
1403
impl < ' a , K , V > Iterator < ( & ' a K , & ' a V ) > for Entries < ' a , K , V > {
1333
1404
#[ inline]
1334
1405
fn next ( & mut self ) -> Option < ( & ' a K , & ' a V ) > {
@@ -1362,6 +1433,81 @@ impl<K, V> Iterator<(K, V)> for MoveEntries<K, V> {
1362
1433
}
1363
1434
}
1364
1435
1436
+ impl < ' a , K , V > Entry < ' a , K , V > {
1437
+ /// Get a reference to both the key and value at the Entry's location
1438
+ #[ inline]
1439
+ fn get_internal ( & self ) -> Option < ( & K , & V ) > {
1440
+ match self . elem {
1441
+ EqElem ( ref bucket) => Some ( bucket. read ( ) ) ,
1442
+ _ => None
1443
+ }
1444
+ }
1445
+
1446
+ /// Get a reference to the value at the Entry's location
1447
+ #[ inline]
1448
+ pub fn get ( & self ) -> Option < & V > {
1449
+ self . get_internal ( ) . map ( |( _, v) | v)
1450
+ }
1451
+
1452
+ /// Get a mutable reference to the value at the Entry's location
1453
+ #[ inline]
1454
+ pub fn get_mut ( & mut self ) -> Option < & mut V > {
1455
+ match self . elem {
1456
+ EqElem ( ref mut bucket) => {
1457
+ let ( _, v) = bucket. read_mut ( ) ;
1458
+ Some ( v)
1459
+ } ,
1460
+ _ => None
1461
+ }
1462
+ }
1463
+
1464
+ /// Get a reference to the key at the Entry's location
1465
+ #[ inline]
1466
+ pub fn get_key ( & self ) -> Option < & K > {
1467
+ self . get_internal ( ) . map ( |( k, _) | k)
1468
+ }
1469
+
1470
+ /// Return whether the Entry's location contains anything
1471
+ #[ inline]
1472
+ pub fn is_empty ( & self ) -> bool {
1473
+ self . get_internal ( ) . is_none ( )
1474
+ }
1475
+
1476
+ /// Set the key and value of the location pointed to by the Entry, and return any old
1477
+ /// key and value that might have been there
1478
+ #[ inline]
1479
+ pub fn set ( self , value : V ) -> Option < ( K , V ) > {
1480
+ match self . elem {
1481
+ EqElem ( mut bucket) => {
1482
+ let ( _, k, v) = bucket. replace ( self . hash , self . key , value) ;
1483
+ Some ( ( k, v) )
1484
+ } ,
1485
+ NeqElem ( bucket, ib) => {
1486
+ robin_hood ( bucket, ib, self . hash , self . key , value) ;
1487
+ None
1488
+ } ,
1489
+ NoElem ( bucket) => {
1490
+ bucket. put ( self . hash , self . key , value) ;
1491
+ None
1492
+ }
1493
+ }
1494
+ }
1495
+
1496
+ /// Get a reference to the Entry's key
1497
+ #[ inline]
1498
+ pub fn key ( & self ) -> & K {
1499
+ & self . key
1500
+ }
1501
+
1502
+ /// Retrieve the Entry's key
1503
+ #[ inline]
1504
+ pub fn into_key ( self ) -> K {
1505
+ self . key
1506
+ }
1507
+ }
1508
+
1509
+
1510
+
1365
1511
/// HashMap keys iterator
1366
1512
pub type Keys < ' a , K , V > =
1367
1513
iter:: Map < ' static , ( & ' a K , & ' a V ) , & ' a K , Entries < ' a , K , V > > ;
@@ -2002,4 +2148,59 @@ mod test_map {
2002
2148
2003
2149
map[ 4 ] ;
2004
2150
}
2151
+
2152
+ #[ test]
2153
+ fn test_view ( ) {
2154
+ let xs = [ ( 1 i, 10 i) , ( 2 , 20 ) , ( 3 , 30 ) , ( 4 , 40 ) , ( 5 , 50 ) , ( 6 , 60 ) ] ;
2155
+
2156
+ let mut map: HashMap < int , int > = xs. iter ( ) . map ( |& x| x) . collect ( ) ;
2157
+
2158
+ {
2159
+ // Existing key (insert)
2160
+ let view = map. view ( 1 ) ;
2161
+ assert ! ( !view. is_empty( ) ) ;
2162
+ assert_eq ! ( view. key( ) , & 1 ) ;
2163
+ assert_eq ! ( view. get( ) . unwrap( ) , & 10 ) ;
2164
+ assert_eq ! ( view. get_key( ) . unwrap( ) , & 1 ) ;
2165
+ assert_eq ! ( view. set( 100 ) , Some ( ( 1 , 10 ) ) ) ;
2166
+ }
2167
+ assert_eq ! ( map. find( & 1 ) . unwrap( ) , & 100 ) ;
2168
+ assert_eq ! ( map. len( ) , 6 ) ;
2169
+
2170
+
2171
+ // Existing key (update)
2172
+ {
2173
+ let mut view = map. view ( 2 ) ;
2174
+ {
2175
+ let v = view. get_mut ( ) . unwrap ( ) ;
2176
+ let new_v = ( * v) * 10 ;
2177
+ * v = new_v;
2178
+ }
2179
+ assert_eq ! ( view. key( ) , & 2 ) ;
2180
+ }
2181
+ assert_eq ! ( map. find( & 2 ) . unwrap( ) , & 200 ) ;
2182
+ assert_eq ! ( map. len( ) , 6 ) ;
2183
+
2184
+
2185
+ // Inexistent key (insert)
2186
+ {
2187
+ let view = map. view ( 10 ) ;
2188
+ assert ! ( view. is_empty( ) ) ;
2189
+ assert_eq ! ( view. key( ) , & 10 ) ;
2190
+ assert_eq ! ( view. get( ) , None ) ;
2191
+ assert_eq ! ( view. get_key( ) , None ) ;
2192
+ assert_eq ! ( view. set( 1000 ) , None ) ;
2193
+ }
2194
+ assert_eq ! ( map. find( & 10 ) . unwrap( ) , & 1000 ) ;
2195
+ assert_eq ! ( map. len( ) , 7 ) ;
2196
+
2197
+
2198
+ // Inexistent key (update)
2199
+ {
2200
+ let mut view = map. view ( 20 ) ;
2201
+ assert_eq ! ( view. get_mut( ) , None ) ;
2202
+ assert_eq ! ( view. key( ) , & 20 ) ;
2203
+ }
2204
+ assert_eq ! ( map. find( & 20 ) , None ) ;
2205
+ }
2005
2206
}
0 commit comments