@@ -25,6 +25,7 @@ type EntryIndex = usize;
2525pub struct Dict < T = PyObjectRef > {
2626 inner : PyRwLock < DictInner < T > > ,
2727}
28+
2829impl < T > fmt:: Debug for Dict < T > {
2930 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
3031 f. debug_struct ( "Debug" ) . finish ( )
@@ -37,10 +38,12 @@ enum IndexEntry {
3738 Free ,
3839 Index ( usize ) ,
3940}
41+
4042impl IndexEntry {
4143 const FREE : i64 = -1 ;
4244 const DUMMY : i64 = -2 ;
4345}
46+
4447impl From < i64 > for IndexEntry {
4548 fn from ( idx : i64 ) -> Self {
4649 match idx {
@@ -50,6 +53,7 @@ impl From<i64> for IndexEntry {
5053 }
5154 }
5255}
56+
5357impl From < IndexEntry > for i64 {
5458 fn from ( idx : IndexEntry ) -> Self {
5559 match idx {
@@ -65,7 +69,7 @@ struct DictInner<T> {
6569 used : usize ,
6670 filled : usize ,
6771 indices : Vec < i64 > ,
68- entries : Vec < DictEntry < T > > ,
72+ entries : Vec < Option < DictEntry < T > > > ,
6973}
7074
7175impl < T : Clone > Clone for Dict < T > {
@@ -143,15 +147,19 @@ impl<T> DictInner<T> {
143147 self . indices = vec ! [ IndexEntry :: FREE ; new_size] ;
144148 let mask = ( new_size - 1 ) as i64 ;
145149 for ( entry_idx, entry) in self . entries . iter_mut ( ) . enumerate ( ) {
146- let mut idxs = GenIndexes :: new ( entry. hash , mask) ;
147- loop {
148- let index_index = idxs. next ( ) ;
149- let idx = & mut self . indices [ index_index] ;
150- if * idx == IndexEntry :: FREE {
151- * idx = entry_idx as i64 ;
152- entry. index = index_index;
153- break ;
150+ if let Some ( entry) = entry {
151+ let mut idxs = GenIndexes :: new ( entry. hash , mask) ;
152+ loop {
153+ let index_index = idxs. next ( ) ;
154+ let idx = & mut self . indices [ index_index] ;
155+ if * idx == IndexEntry :: FREE {
156+ * idx = entry_idx as i64 ;
157+ entry. index = index_index;
158+ break ;
159+ }
154160 }
161+ } else {
162+ //removed entry
155163 }
156164 }
157165 self . filled = self . used ;
@@ -172,7 +180,7 @@ impl<T> DictInner<T> {
172180 index,
173181 } ;
174182 let entry_index = self . entries . len ( ) ;
175- self . entries . push ( entry) ;
183+ self . entries . push ( Some ( entry) ) ;
176184 self . indices [ index] = entry_index as i64 ;
177185 self . used += 1 ;
178186 if let IndexEntry :: Free = index_entry {
@@ -213,8 +221,8 @@ impl<T: Clone> Dict<T> {
213221
214222 /// Store a key
215223 pub fn insert < K > ( & self , vm : & VirtualMachine , key : K , value : T ) -> PyResult < ( ) >
216- where
217- K : DictKey ,
224+ where
225+ K : DictKey ,
218226 {
219227 let hash = key. key_hash ( vm) ?;
220228 let _removed = loop {
@@ -223,6 +231,7 @@ impl<T: Clone> Dict<T> {
223231 let mut inner = self . write ( ) ;
224232 // Update existing key
225233 if let Some ( entry) = inner. entries . get_mut ( index) {
234+ let entry = entry. as_mut ( ) . unwrap ( ) ;
226235 if entry. index == index_index {
227236 let removed = std:: mem:: replace ( & mut entry. value , value) ;
228237 // defer dec RC
@@ -266,6 +275,7 @@ impl<T: Clone> Dict<T> {
266275 if let IndexEntry :: Index ( index) = entry {
267276 let inner = self . read ( ) ;
268277 if let Some ( entry) = inner. entries . get ( index) {
278+ let entry = entry. as_ref ( ) . unwrap ( ) ;
269279 if entry. index == index_index {
270280 break Some ( entry. value . clone ( ) ) ;
271281 } else {
@@ -310,8 +320,8 @@ impl<T: Clone> Dict<T> {
310320
311321 /// Delete a key
312322 pub fn delete < K > ( & self , vm : & VirtualMachine , key : K ) -> PyResult < ( ) >
313- where
314- K : DictKey ,
323+ where
324+ K : DictKey ,
315325 {
316326 if self . delete_if_exists ( vm, & key) ? {
317327 Ok ( ( ) )
@@ -321,8 +331,8 @@ impl<T: Clone> Dict<T> {
321331 }
322332
323333 pub fn delete_if_exists < K > ( & self , vm : & VirtualMachine , key : & K ) -> PyResult < bool >
324- where
325- K : DictKey ,
334+ where
335+ K : DictKey ,
326336 {
327337 let hash = key. key_hash ( vm) ?;
328338 let deleted = loop {
@@ -366,9 +376,9 @@ impl<T: Clone> Dict<T> {
366376 }
367377
368378 pub fn setdefault < K , F > ( & self , vm : & VirtualMachine , key : K , default : F ) -> PyResult < T >
369- where
370- K : DictKey ,
371- F : FnOnce ( ) -> T ,
379+ where
380+ K : DictKey ,
381+ F : FnOnce ( ) -> T ,
372382 {
373383 let hash = key. key_hash ( vm) ?;
374384 let res = loop {
@@ -377,6 +387,7 @@ impl<T: Clone> Dict<T> {
377387 if let IndexEntry :: Index ( index) = entry {
378388 let inner = self . read ( ) ;
379389 if let Some ( entry) = inner. entries . get ( index) {
390+ let entry = entry. as_ref ( ) . unwrap ( ) ;
380391 if entry. index == index_index {
381392 break entry. value . clone ( ) ;
382393 } else {
@@ -408,9 +419,9 @@ impl<T: Clone> Dict<T> {
408419 key : K ,
409420 default : F ,
410421 ) -> PyResult < ( PyObjectRef , T ) >
411- where
412- K : DictKey ,
413- F : FnOnce ( ) -> T ,
422+ where
423+ K : DictKey ,
424+ F : FnOnce ( ) -> T ,
414425 {
415426 let hash = key. key_hash ( vm) ?;
416427 let res = loop {
@@ -419,6 +430,7 @@ impl<T: Clone> Dict<T> {
419430 if let IndexEntry :: Index ( index) = entry {
420431 let inner = self . read ( ) ;
421432 if let Some ( entry) = inner. entries . get ( index) {
433+ let entry = entry. as_ref ( ) . unwrap ( ) ;
422434 if entry. index == index_index {
423435 break ( entry. key . clone ( ) , entry. value . clone ( ) ) ;
424436 } else {
@@ -453,10 +465,18 @@ impl<T: Clone> Dict<T> {
453465 }
454466
455467 pub fn next_entry ( & self , position : & mut EntryIndex ) -> Option < ( PyObjectRef , T ) > {
456- self . read ( ) . entries . get ( * position) . map ( |entry| {
457- * position += 1 ;
458- ( entry. key . clone ( ) , entry. value . clone ( ) )
459- } )
468+ let inner = self . read ( ) ;
469+ loop {
470+ let entry = inner. entries . get ( * position) ;
471+ if let Some ( entry) = entry {
472+ * position += 1 ;
473+ if let Some ( entry) = entry {
474+ break Some ( ( entry. key . clone ( ) , entry. value . clone ( ) ) ) ;
475+ }
476+ } else {
477+ break None ;
478+ }
479+ }
460480 }
461481
462482 pub fn len_from_entry_index ( & self , position : EntryIndex ) -> usize {
@@ -469,7 +489,9 @@ impl<T: Clone> Dict<T> {
469489 }
470490
471491 pub fn keys ( & self ) -> Vec < PyObjectRef > {
472- self . read ( ) . entries . iter ( ) . map ( |v| v. key . clone ( ) ) . collect ( )
492+ self . read ( ) . entries . iter ( )
493+ . filter ( |v| v. is_some ( ) )
494+ . map ( |v| v. as_ref ( ) . unwrap ( ) . key . clone ( ) ) . collect ( )
473495 }
474496
475497 /// Lookup the index for the given key.
@@ -505,7 +527,7 @@ impl<T: Clone> Dict<T> {
505527 return Ok ( idxs) ;
506528 }
507529 IndexEntry :: Index ( i) => {
508- let entry = & inner. entries [ i] ;
530+ let entry = & inner. entries [ i] . as_ref ( ) . unwrap ( ) ;
509531 let ret = ( IndexEntry :: Index ( i) , index_index) ;
510532 if key. key_is ( & entry. key ) {
511533 break ' outer ret;
@@ -540,7 +562,7 @@ impl<T: Clone> Dict<T> {
540562 return Ok ( None ) ;
541563 } ;
542564 let mut inner = self . write ( ) ;
543- if matches ! ( inner. entries. get( entry_index) , Some ( entry) if entry. index == index_index) {
565+ if matches ! ( inner. entries. get( entry_index) , Some ( entry) if entry. as_ref ( ) . unwrap ( ) . index == index_index) {
544566 // all good
545567 } else {
546568 // The dict was changed since we did lookup. Let's try again.
@@ -551,12 +573,12 @@ impl<T: Clone> Dict<T> {
551573 let removed = if entry_index == inner. used {
552574 inner. entries . pop ( ) . unwrap ( )
553575 } else {
554- let last_index = inner. entries . last ( ) . unwrap ( ) . index ;
576+ let last_index = inner. entries . last ( ) . unwrap ( ) . as_ref ( ) . unwrap ( ) . index ;
555577 let removed = inner. entries . swap_remove ( entry_index) ;
556578 inner. indices [ last_index] = entry_index as i64 ;
557579 removed
558580 } ;
559- Ok ( Some ( removed) )
581+ Ok ( Some ( removed. unwrap ( ) ) )
560582 }
561583
562584 /// Retrieve and delete a key
@@ -576,6 +598,7 @@ impl<T: Clone> Dict<T> {
576598 pub fn pop_back ( & self ) -> Option < ( PyObjectRef , T ) > {
577599 let mut inner = self . write ( ) ;
578600 inner. entries . pop ( ) . map ( |entry| {
601+ let entry = entry. unwrap ( ) ;
579602 inner. used -= 1 ;
580603 inner. indices [ entry. index ] = IndexEntry :: DUMMY ;
581604 ( entry. key , entry. value )
@@ -638,6 +661,7 @@ impl DictKey for PyStrRef {
638661 }
639662 }
640663}
664+
641665impl DictKey for PyRefExact < PyStr > {
642666 fn key_hash ( & self , vm : & VirtualMachine ) -> PyResult < HashValue > {
643667 ( * * self ) . key_hash ( vm)
0 commit comments