1- #![ allow( unsafe_code) ]
21//! This is the core implementation that doesn't depend on the hasher at all.
32//!
43//! The methods of `IndexMapCore` don't use any Hash properties of K.
87//!
98//! However, we should probably not let this show in the public API or docs.
109
10+ mod raw;
11+
1112#[ cfg( not( has_std) ) ]
1213use std:: vec:: Vec ;
1314
@@ -23,8 +24,6 @@ use equivalent::Equivalent;
2324use util:: enumerate;
2425use { Bucket , Entries , HashValue } ;
2526
26- type RawBucket = hashbrown:: raw:: Bucket < usize > ;
27-
2827/// Core of the map that does not depend on S
2928pub ( crate ) struct IndexMapCore < K , V > {
3029 /// indices mapping from the entry hash to its index.
6766 V : fmt:: Debug ,
6867{
6968 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
70- struct DebugIndices < ' a > ( & ' a RawTable < usize > ) ;
71- impl fmt:: Debug for DebugIndices < ' _ > {
72- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
73- let indices = unsafe { self . 0 . iter ( ) . map ( |raw_bucket| raw_bucket. read ( ) ) } ;
74- f. debug_list ( ) . entries ( indices) . finish ( )
75- }
76- }
77-
7869 f. debug_struct ( "IndexMapCore" )
79- . field ( "indices" , & DebugIndices ( & self . indices ) )
70+ . field ( "indices" , & raw :: DebugIndices ( & self . indices ) )
8071 . field ( "entries" , & self . entries )
8172 . finish ( )
8273 }
@@ -168,8 +159,7 @@ impl<K, V> IndexMapCore<K, V> {
168159 pub ( crate ) fn pop ( & mut self ) -> Option < ( K , V ) > {
169160 if let Some ( entry) = self . entries . pop ( ) {
170161 let last = self . entries . len ( ) ;
171- let raw_bucket = self . find_index ( entry. hash , last) . unwrap ( ) ;
172- unsafe { self . indices . erase_no_drop ( & raw_bucket) } ;
162+ self . erase_index ( entry. hash , last) ;
173163 Some ( ( entry. key , entry. value ) )
174164 } else {
175165 None
@@ -190,17 +180,6 @@ impl<K, V> IndexMapCore<K, V> {
190180 i
191181 }
192182
193- /// Return the index in `entries` where an equivalent key can be found
194- pub ( crate ) fn get_index_of < Q > ( & self , hash : HashValue , key : & Q ) -> Option < usize >
195- where
196- Q : ?Sized + Equivalent < K > ,
197- {
198- match self . find_equivalent ( hash, key) {
199- Some ( raw_bucket) => Some ( unsafe { raw_bucket. read ( ) } ) ,
200- None => None ,
201- }
202- }
203-
204183 pub ( crate ) fn insert_full ( & mut self , hash : HashValue , key : K , value : V ) -> ( usize , Option < V > )
205184 where
206185 K : Eq ,
@@ -211,150 +190,6 @@ impl<K, V> IndexMapCore<K, V> {
211190 }
212191 }
213192
214- pub ( crate ) fn entry ( & mut self , hash : HashValue , key : K ) -> Entry < K , V >
215- where
216- K : Eq ,
217- {
218- match self . find_equivalent ( hash, & key) {
219- // Safety: The entry is created with a live raw bucket, at the same time we have a &mut
220- // reference to the map, so it can not be modified further.
221- Some ( raw_bucket) => Entry :: Occupied ( OccupiedEntry {
222- map : self ,
223- raw_bucket,
224- key,
225- } ) ,
226- None => Entry :: Vacant ( VacantEntry {
227- map : self ,
228- hash,
229- key,
230- } ) ,
231- }
232- }
233-
234- /// Return the raw bucket with an equivalent key
235- fn find_equivalent < Q > ( & self , hash : HashValue , key : & Q ) -> Option < RawBucket >
236- where
237- Q : ?Sized + Equivalent < K > ,
238- {
239- self . indices . find ( hash. get ( ) , {
240- |& i| Q :: equivalent ( key, & self . entries [ i] . key )
241- } )
242- }
243-
244- /// Return the raw bucket for the given index
245- fn find_index ( & self , hash : HashValue , index : usize ) -> Option < RawBucket > {
246- self . indices . find ( hash. get ( ) , |& i| i == index)
247- }
248-
249- /// Remove an entry by shifting all entries that follow it
250- pub ( crate ) fn shift_remove_full < Q > ( & mut self , hash : HashValue , key : & Q ) -> Option < ( usize , K , V ) >
251- where
252- Q : ?Sized + Equivalent < K > ,
253- {
254- match self . find_equivalent ( hash, key) {
255- Some ( raw_bucket) => unsafe { Some ( self . shift_remove_bucket ( raw_bucket) ) } ,
256- None => None ,
257- }
258- }
259-
260- /// Remove an entry by shifting all entries that follow it
261- pub ( crate ) fn shift_remove_index ( & mut self , index : usize ) -> Option < ( K , V ) > {
262- let raw_bucket = match self . entries . get ( index) {
263- Some ( entry) => self . find_index ( entry. hash , index) . unwrap ( ) ,
264- None => return None ,
265- } ;
266- unsafe {
267- let ( _, key, value) = self . shift_remove_bucket ( raw_bucket) ;
268- Some ( ( key, value) )
269- }
270- }
271-
272- /// Remove an entry by shifting all entries that follow it
273- ///
274- /// Safety: The caller must pass a live `raw_bucket`.
275- #[ allow( unused_unsafe) ]
276- unsafe fn shift_remove_bucket ( & mut self , raw_bucket : RawBucket ) -> ( usize , K , V ) {
277- // use Vec::remove, but then we need to update the indices that point
278- // to all of the other entries that have to move
279- let index = unsafe {
280- self . indices . erase_no_drop ( & raw_bucket) ;
281- raw_bucket. read ( )
282- } ;
283- let entry = self . entries . remove ( index) ;
284-
285- // correct indices that point to the entries that followed the removed entry.
286- // use a heuristic between a full sweep vs. a `find()` for every shifted item.
287- let raw_capacity = self . indices . buckets ( ) ;
288- let shifted_entries = & self . entries [ index..] ;
289- if shifted_entries. len ( ) > raw_capacity / 2 {
290- // shift all indices greater than `index`
291- unsafe {
292- for bucket in self . indices . iter ( ) {
293- let i = bucket. read ( ) ;
294- if i > index {
295- bucket. write ( i - 1 ) ;
296- }
297- }
298- }
299- } else {
300- // find each following entry to shift its index
301- for ( i, entry) in ( index + 1 ..) . zip ( shifted_entries) {
302- let shifted_bucket = self . find_index ( entry. hash , i) . unwrap ( ) ;
303- unsafe { shifted_bucket. write ( i - 1 ) } ;
304- }
305- }
306-
307- ( index, entry. key , entry. value )
308- }
309-
310- /// Remove an entry by swapping it with the last
311- pub ( crate ) fn swap_remove_full < Q > ( & mut self , hash : HashValue , key : & Q ) -> Option < ( usize , K , V ) >
312- where
313- Q : ?Sized + Equivalent < K > ,
314- {
315- match self . find_equivalent ( hash, key) {
316- Some ( raw_bucket) => unsafe { Some ( self . swap_remove_bucket ( raw_bucket) ) } ,
317- None => None ,
318- }
319- }
320-
321- /// Remove an entry by swapping it with the last
322- pub ( crate ) fn swap_remove_index ( & mut self , index : usize ) -> Option < ( K , V ) > {
323- let raw_bucket = match self . entries . get ( index) {
324- Some ( entry) => self . find_index ( entry. hash , index) . unwrap ( ) ,
325- None => return None ,
326- } ;
327- unsafe {
328- let ( _, key, value) = self . swap_remove_bucket ( raw_bucket) ;
329- Some ( ( key, value) )
330- }
331- }
332-
333- /// Remove an entry by swapping it with the last
334- ///
335- /// Safety: The caller must pass a live `raw_bucket`.
336- #[ allow( unused_unsafe) ]
337- unsafe fn swap_remove_bucket ( & mut self , raw_bucket : RawBucket ) -> ( usize , K , V ) {
338- // use swap_remove, but then we need to update the index that points
339- // to the other entry that has to move
340- let index = unsafe {
341- self . indices . erase_no_drop ( & raw_bucket) ;
342- raw_bucket. read ( )
343- } ;
344- let entry = self . entries . swap_remove ( index) ;
345-
346- // correct index that points to the entry that had to swap places
347- if let Some ( entry) = self . entries . get ( index) {
348- // was not last element
349- // examine new element in `index` and find it in indices
350- let last = self . entries . len ( ) ;
351- let swapped_bucket = self . find_index ( entry. hash , last) . unwrap ( ) ;
352- unsafe { swapped_bucket. write ( index) } ;
353- }
354-
355- ( index, entry. key , entry. value )
356- }
357-
358193 pub ( crate ) fn retain_in_order < F > ( & mut self , mut keep : F )
359194 where
360195 F : FnMut ( & mut K , & mut V ) -> bool ,
@@ -381,20 +216,6 @@ impl<K, V> IndexMapCore<K, V> {
381216 }
382217 }
383218
384- pub ( crate ) fn reverse ( & mut self ) {
385- self . entries . reverse ( ) ;
386-
387- // No need to save hash indices, can easily calculate what they should
388- // be, given that this is an in-place reversal.
389- let len = self . entries . len ( ) ;
390- unsafe {
391- for raw_bucket in self . indices . iter ( ) {
392- let i = raw_bucket. read ( ) ;
393- raw_bucket. write ( len - i - 1 ) ;
394- }
395- }
396- }
397-
398219 fn rebuild_hash_table ( & mut self ) {
399220 self . indices . clear_no_drop ( ) ;
400221 debug_assert ! ( self . indices. capacity( ) >= self . entries. len( ) ) ;
@@ -487,52 +308,10 @@ impl<'a, K: 'a + fmt::Debug, V: 'a + fmt::Debug> fmt::Debug for Entry<'a, K, V>
487308 }
488309}
489310
490- /// A view into an occupied entry in a `IndexMap`.
491- /// It is part of the [`Entry`] enum.
492- ///
493- /// [`Entry`]: enum.Entry.html
494- pub struct OccupiedEntry < ' a , K : ' a , V : ' a > {
495- map : & ' a mut IndexMapCore < K , V > ,
496- raw_bucket : RawBucket ,
497- key : K ,
498- }
499-
500- // `hashbrown::raw::Bucket` is only `Send`, not `Sync`.
501- // SAFETY: `&self` only accesses the bucket to read it.
502- unsafe impl < K : Sync , V : Sync > Sync for OccupiedEntry < ' _ , K , V > { }
311+ pub use self :: raw:: OccupiedEntry ;
503312
313+ // Extra methods that don't threaten the unsafe encapsulation.
504314impl < ' a , K , V > OccupiedEntry < ' a , K , V > {
505- pub fn key ( & self ) -> & K {
506- & self . key
507- }
508-
509- pub fn get ( & self ) -> & V {
510- & self . map . entries [ self . index ( ) ] . value
511- }
512-
513- pub fn get_mut ( & mut self ) -> & mut V {
514- let index = self . index ( ) ;
515- & mut self . map . entries [ index] . value
516- }
517-
518- /// Put the new key in the occupied entry's key slot
519- pub ( crate ) fn replace_key ( self ) -> K {
520- let index = self . index ( ) ;
521- let old_key = & mut self . map . entries [ index] . key ;
522- replace ( old_key, self . key )
523- }
524-
525- /// Return the index of the key-value pair
526- #[ inline]
527- pub fn index ( & self ) -> usize {
528- unsafe { self . raw_bucket . read ( ) }
529- }
530-
531- pub fn into_mut ( self ) -> & ' a mut V {
532- let index = self . index ( ) ;
533- & mut self . map . entries [ index] . value
534- }
535-
536315 /// Sets the value of the entry to `value`, and returns the entry's old value.
537316 pub fn insert ( & mut self , value : V ) -> V {
538317 replace ( self . get_mut ( ) , value)
@@ -573,38 +352,6 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
573352 pub fn remove_entry ( self ) -> ( K , V ) {
574353 self . swap_remove_entry ( )
575354 }
576-
577- /// Remove and return the key, value pair stored in the map for this entry
578- ///
579- /// Like `Vec::swap_remove`, the pair is removed by swapping it with the
580- /// last element of the map and popping it off. **This perturbs
581- /// the postion of what used to be the last element!**
582- ///
583- /// Computes in **O(1)** time (average).
584- pub fn swap_remove_entry ( self ) -> ( K , V ) {
585- // This is safe because it can only happen once (self is consumed)
586- // and map.indices have not been modified since entry construction
587- unsafe {
588- let ( _, key, value) = self . map . swap_remove_bucket ( self . raw_bucket ) ;
589- ( key, value)
590- }
591- }
592-
593- /// Remove and return the key, value pair stored in the map for this entry
594- ///
595- /// Like `Vec::remove`, the pair is removed by shifting all of the
596- /// elements that follow it, preserving their relative order.
597- /// **This perturbs the index of all of those elements!**
598- ///
599- /// Computes in **O(n)** time (average).
600- pub fn shift_remove_entry ( self ) -> ( K , V ) {
601- // This is safe because it can only happen once (self is consumed)
602- // and map.indices have not been modified since entry construction
603- unsafe {
604- let ( _, key, value) = self . map . shift_remove_bucket ( self . raw_bucket ) ;
605- ( key, value)
606- }
607- }
608355}
609356
610357impl < ' a , K : ' a + fmt:: Debug , V : ' a + fmt:: Debug > fmt:: Debug for OccupiedEntry < ' a , K , V > {
0 commit comments