(
&self,
vm: &VirtualMachine,
key: &K,
hash_value: HashValue,
mut lock: Option<PyRwLockReadGuard<'_, DictInner<T>>>,
)
| 660 | /// Lookup the index for the given key. |
| 661 | #[cfg_attr(feature = "flame-it", flame("Dict"))] |
| 662 | fn lookup<K: DictKey + ?Sized>( |
| 663 | &self, |
| 664 | vm: &VirtualMachine, |
| 665 | key: &K, |
| 666 | hash_value: HashValue, |
| 667 | mut lock: Option<PyRwLockReadGuard<'_, DictInner<T>>>, |
| 668 | ) -> PyResult<LookupResult> { |
| 669 | let mut idxs = None; |
| 670 | let mut free_slot = None; |
| 671 | let ret = 'outer: loop { |
| 672 | let (entry_key, ret) = { |
| 673 | let inner = lock.take().unwrap_or_else(|| self.read()); |
| 674 | let mask = (inner.indices.len() - 1) as i64; |
| 675 | let idxs = idxs.get_or_insert_with(|| GenIndexes::new(hash_value, mask)); |
| 676 | if idxs.mask != mask { |
| 677 | // Dict was resized since last probe, restart |
| 678 | *idxs = GenIndexes::new(hash_value, mask); |
| 679 | free_slot = None; |
| 680 | } |
| 681 | loop { |
| 682 | let index_index = idxs.next(); |
| 683 | let index_entry = *unsafe { |
| 684 | // Safety: index_index is generated |
| 685 | inner.indices.get_unchecked(index_index) |
| 686 | }; |
| 687 | match index_entry { |
| 688 | IndexEntry::DUMMY => { |
| 689 | if free_slot.is_none() { |
| 690 | free_slot = Some(index_index); |
| 691 | } |
| 692 | } |
| 693 | IndexEntry::FREE => { |
| 694 | let idxs = match free_slot { |
| 695 | Some(free) => (IndexEntry::DUMMY, free), |
| 696 | None => (IndexEntry::FREE, index_index), |
| 697 | }; |
| 698 | return Ok(idxs); |
| 699 | } |
| 700 | idx => { |
| 701 | let entry = unsafe { |
| 702 | // Safety: DUMMY and FREE are already handled above. |
| 703 | // i is always valid and entry always exists. |
| 704 | let i = idx.index().unwrap_unchecked(); |
| 705 | inner.entries.get_unchecked(i).as_ref().unwrap_unchecked() |
| 706 | }; |
| 707 | let ret = (idx, index_index); |
| 708 | if key.key_is(&entry.key) { |
| 709 | break 'outer ret; |
| 710 | } else if entry.hash == hash_value { |
| 711 | break (entry.key.clone(), ret); |
| 712 | } else { |
| 713 | // entry mismatch |
| 714 | } |
| 715 | } |
| 716 | } |
| 717 | // warn!("Perturb value: {}", i); |
| 718 | } |
| 719 | }; |
no test coverage detected