1use crate::hints::{assert_hint, cold_path, likely, unlikely, unwrap_or_bug_hint};
11use alloc::alloc::{alloc, dealloc, Layout};
12use core::ptr::null_mut;
13use core::{mem, ptr};
14
15enum InsertFailErr {
20 NotEnoughSpace,
22 KeyAlreadyExists,
24}
25
26struct Slot<V> {
31 key: usize,
32 value: V,
33}
34
35pub struct NumberKeyMap<V> {
79 inner: *mut Slot<V>,
82 capacity: usize,
83}
84
85impl<V> NumberKeyMap<V> {
86 pub const fn new() -> Self {
88 Self {
89 inner: null_mut(),
90 capacity: 0,
91 }
92 }
93
94 fn get_started_slot_idx_for_key(key: usize, capacity: usize) -> usize {
98 key % capacity
99 }
100
101 fn validate_key(key: usize) {
106 assert_hint(key != usize::MAX, "`key` should be not equal to usize::MAX");
107 }
108
109 fn get_slot_ptr(inner: *mut Slot<V>, capacity: usize, idx: usize) -> *mut Slot<V> {
117 assert_hint(
118 !inner.is_null(),
119 "NumberKeyMap is allocated at `get_slot_ptr`",
120 );
121 assert_hint(idx < capacity, "`idx` is out of bounds at `get_slot_ptr`");
122
123 unsafe { inner.add(idx) }
124 }
125
126 fn get_slot(&self, idx: usize) -> &Slot<V> {
128 unsafe { &*Self::get_slot_ptr(self.inner, self.capacity, idx) }
129 }
130
131 fn get_slot_mut(&mut self, idx: usize) -> &mut Slot<V> {
133 unsafe { &mut *Self::get_slot_ptr(self.inner, self.capacity, idx) }
134 }
135
136 pub fn get(&self, key: usize) -> Option<&V> {
145 Self::validate_key(key);
146
147 if unlikely(self.inner.is_null()) {
148 return None;
149 }
150
151 let idx = Self::get_started_slot_idx_for_key(key, self.capacity);
152 let slot = self.get_slot(idx);
153
154 if likely(slot.key == key) {
155 return Some(&slot.value);
156 }
157
158 None
159 }
160
161 pub fn get_mut(&mut self, key: usize) -> Option<&mut V> {
170 Self::validate_key(key);
171
172 if unlikely(self.inner.is_null()) {
173 return None;
174 }
175
176 let idx = Self::get_started_slot_idx_for_key(key, self.capacity);
177 let slot = self.get_slot_mut(idx);
178
179 if likely(slot.key == key) {
180 return Some(&mut slot.value);
181 }
182
183 None
184 }
185
186 fn greater_capacity(capacity: usize) -> usize {
192 if unlikely(capacity < 16) {
193 return capacity * 2 + 2; }
195
196 let new_capacity = capacity * 8 / 7;
197 if unlikely(new_capacity.is_power_of_two()) {
198 new_capacity + 1
199 } else {
200 new_capacity
201 }
202 }
203
204 unsafe fn insert_or_fail(
215 inner: *mut Slot<V>,
216 capacity: usize,
217 key: usize,
218 value_ptr: *const V,
219 ) -> Result<(), InsertFailErr> {
220 assert_hint(
221 !inner.is_null(),
222 "null pointer is provided to `insert_or_fail`",
223 );
224
225 let idx = Self::get_started_slot_idx_for_key(key, capacity);
226 let slot_ptr = Self::get_slot_ptr(inner, capacity, idx);
227 let slot = unsafe { &mut *slot_ptr };
228
229 if likely(slot.key == usize::MAX) {
230 unsafe {
231 slot_ptr.write(Slot {
232 key,
233 value: value_ptr.read(),
234 });
235 }
236
237 Ok(())
238 } else if unlikely(key == slot.key) {
239 Err(InsertFailErr::KeyAlreadyExists)
240 } else {
241 Err(InsertFailErr::NotEnoughSpace)
243 }
244 }
245
246 #[cold]
257 #[inline(never)]
258 fn slow_insert(&mut self, key: usize, value: V) -> Result<(), V> {
259 let mut new_capacity = Self::greater_capacity(self.capacity);
260
261 'allocate: loop {
262 let layout = unwrap_or_bug_hint(Layout::array::<Slot<V>>(new_capacity));
263 let new_inner: *mut Slot<V> = unsafe { alloc(layout) }.cast();
267
268 for i in 0..new_capacity {
269 unsafe {
270 let slot = new_inner.add(i);
271
272 (*slot).key = usize::MAX;
273 };
274 }
275
276 for idx in 0..self.capacity {
277 let slot = self.get_slot(idx);
278
279 if slot.key != usize::MAX {
280 let res = unsafe {
281 Self::insert_or_fail(new_inner, new_capacity, slot.key, &slot.value)
282 };
283 if unlikely(res.is_err()) {
284 assert_hint(
285 matches!(res, Err(InsertFailErr::NotEnoughSpace)),
286 "invalid inner state is detected while reallocating: duplicate key",
287 );
288
289 new_capacity = Self::greater_capacity(new_capacity);
291
292 unsafe { dealloc(new_inner.cast(), layout) };
293
294 continue 'allocate;
295 }
296 }
297 }
298
299 let res = unsafe { Self::insert_or_fail(new_inner, new_capacity, key, &value) };
301
302 let mut commit_reallocate = || {
303 unsafe {
304 dealloc(
305 self.inner.cast(),
306 unwrap_or_bug_hint(Layout::array::<Slot<V>>(self.capacity)),
307 );
308 };
309
310 self.inner = new_inner;
311 self.capacity = new_capacity;
312 };
313
314 match res {
315 Ok(()) => {
316 commit_reallocate();
317
318 mem::forget(value);
319
320 break Ok(());
321 }
322
323 Err(InsertFailErr::NotEnoughSpace) => {
324 cold_path();
325
326 new_capacity = Self::greater_capacity(new_capacity);
328
329 unsafe { dealloc(new_inner.cast(), layout) };
330
331 continue 'allocate;
332 }
333
334 Err(InsertFailErr::KeyAlreadyExists) => {
335 commit_reallocate();
339
340 break Err(value);
341 }
342 }
343 }
344 }
345
346 #[cold]
348 #[inline(never)]
349 fn insert_first(&mut self, key: usize, value: V) {
350 Self::validate_key(key);
351
352 let layout = unwrap_or_bug_hint(Layout::array::<Slot<V>>(1));
353 let inner: *mut Slot<V> = unsafe { alloc(layout) }.cast();
354 unsafe { inner.write(Slot { key, value }) };
355
356 self.inner = inner;
357 self.capacity = 1;
358 }
359
360 pub fn insert(&mut self, key: usize, value: V) -> Result<(), V> {
375 Self::validate_key(key);
376
377 if unlikely(self.inner.is_null()) {
378 self.insert_first(key, value);
379
380 return Ok(());
381 }
382
383 let res = unsafe { Self::insert_or_fail(self.inner, self.capacity, key, &value) };
384 if likely(res.is_ok()) {
385 mem::forget(value);
386
387 return Ok(());
388 }
389
390 self.slow_insert(key, value)
391 }
392
393 pub fn remove(&mut self, key: usize) -> Option<V> {
399 Self::validate_key(key);
400
401 let idx = Self::get_started_slot_idx_for_key(key, self.capacity);
402 let slot = self.get_slot_mut(idx);
403 if unlikely(slot.key == usize::MAX) {
404 return None;
405 }
406
407 slot.key = usize::MAX;
408
409 Some(unsafe { ptr::read(&slot.value) })
410 }
411
412 pub fn clear_with(&mut self, func: impl Fn((usize, V))) {
414 if self.inner.is_null() {
415 return;
416 }
417
418 for i in 0..self.capacity {
419 let slot_ptr = unsafe { self.inner.add(i) };
420 let slot = unsafe { &mut *slot_ptr };
421
422 if slot.key != usize::MAX {
423 func((slot.key, unsafe { ptr::read(&slot.value) }));
424 slot.key = usize::MAX;
425 }
426 }
427 }
428
429 pub fn clear(&mut self) {
431 self.clear_with(drop);
432 }
433}
434
435impl<V> Default for NumberKeyMap<V> {
436 fn default() -> Self {
437 Self::new()
438 }
439}
440
441pub struct IntoIter<V> {
446 start: *mut Slot<V>,
447 i: usize,
448 capacity: usize,
449}
450
451impl<V> Iterator for IntoIter<V> {
452 type Item = (usize, V);
453
454 fn next(&mut self) -> Option<Self::Item> {
455 unsafe {
456 while self.i < self.capacity {
457 let ptr = self.start.add(self.i);
458 let slot = &mut *ptr;
459
460 self.i += 1;
461
462 if slot.key != usize::MAX {
463 return Some((slot.key, ptr::read(&slot.value)));
464 }
465 }
466
467 None
468 }
469 }
470}
471
472impl<V> Drop for IntoIter<V> {
473 fn drop(&mut self) {
474 unsafe {
475 for (_k, v) in self.by_ref() {
477 drop(v);
478 }
479
480 let layout = Layout::array::<Slot<V>>(self.capacity).unwrap();
482
483 dealloc(self.start.cast(), layout);
484 }
485 }
486}
487
488impl<V> NumberKeyMap<V> {
489 pub fn iter(&self) -> impl Iterator<Item = (usize, &V)> {
491 struct Iter<'a, V> {
492 ptr: *mut Slot<V>,
493 end: *mut Slot<V>,
494 _marker: core::marker::PhantomData<&'a V>,
495 }
496
497 impl<'a, V> Iterator for Iter<'a, V> {
498 type Item = (usize, &'a V);
499
500 fn next(&mut self) -> Option<Self::Item> {
501 unsafe {
502 while self.ptr < self.end {
503 let slot = &*self.ptr;
504
505 self.ptr = self.ptr.add(1);
506
507 if slot.key != usize::MAX {
508 return Some((slot.key, &slot.value));
509 }
510 }
511
512 None
513 }
514 }
515 }
516
517 Iter {
518 ptr: self.inner,
519 end: unsafe { self.inner.add(self.capacity) },
520 _marker: core::marker::PhantomData,
521 }
522 }
523
524 pub fn iter_mut(&mut self) -> impl Iterator<Item = (usize, &mut V)> {
526 struct IterMut<'a, V> {
527 ptr: *mut Slot<V>,
528 end: *mut Slot<V>,
529 _marker: core::marker::PhantomData<&'a mut V>,
530 }
531
532 impl<'a, V: 'a> Iterator for IterMut<'a, V> {
533 type Item = (usize, &'a mut V);
534
535 fn next(&mut self) -> Option<Self::Item> {
536 unsafe {
537 while self.ptr < self.end {
538 let slot = &mut *self.ptr;
539
540 self.ptr = self.ptr.add(1);
541
542 if slot.key != usize::MAX {
543 return Some((slot.key, &mut slot.value));
544 }
545 }
546
547 None
548 }
549 }
550 }
551
552 IterMut {
553 ptr: self.inner,
554 end: unsafe { self.inner.add(self.capacity) },
555 _marker: core::marker::PhantomData,
556 }
557 }
558}
559
560impl<V: 'static> NumberKeyMap<V> {
561 pub fn drain(&mut self) -> impl Iterator<Item = (usize, V)> {
563 struct Drain<'a, V> {
564 ptr: *mut Slot<V>,
565 end: *mut Slot<V>,
566 _marker: core::marker::PhantomData<&'a mut V>,
567 }
568
569 impl<V: 'static> Iterator for Drain<'_, V> {
570 type Item = (usize, V);
571
572 fn next(&mut self) -> Option<Self::Item> {
573 unsafe {
574 while self.ptr < self.end {
575 let slot = &mut *self.ptr;
576
577 self.ptr = self.ptr.add(1);
578
579 if slot.key != usize::MAX {
580 let key = slot.key;
581
582 slot.key = usize::MAX;
583
584 return Some((key, ptr::read(&slot.value)));
585 }
586 }
587
588 None
589 }
590 }
591 }
592
593 Drain {
594 ptr: self.inner,
595 end: unsafe { self.inner.add(self.capacity) },
596 _marker: core::marker::PhantomData,
597 }
598 }
599}
600
601impl<V> IntoIterator for NumberKeyMap<V> {
602 type Item = (usize, V);
603 type IntoIter = IntoIter<V>;
604
605 fn into_iter(self) -> Self::IntoIter {
606 let iter = IntoIter {
607 start: self.inner,
608 i: 0,
609 capacity: self.capacity,
610 };
611
612 mem::forget(self);
613
614 iter
615 }
616}
617
618unsafe impl<V> Sync for NumberKeyMap<V> {}
619unsafe impl<V> Send for NumberKeyMap<V> {}
620
621impl<V> Drop for NumberKeyMap<V> {
622 fn drop(&mut self) {
623 if self.inner.is_null() {
624 return;
625 }
626
627 if mem::needs_drop::<V>() {
628 for i in 0..self.capacity {
629 let slot_ptr = unsafe { self.inner.add(i) };
630 let slot = unsafe { &mut *slot_ptr };
631
632 if slot.key != usize::MAX {
633 unsafe { (&raw mut slot.value).drop_in_place() };
634 }
635 }
636 }
637
638 let layout = Layout::array::<Slot<V>>(self.capacity).unwrap();
639 unsafe {
640 dealloc(self.inner.cast(), layout);
641 }
642 }
643}
644
645#[cfg(test)]
646mod tests {
647 use super::*;
648
649 use alloc::rc::Rc;
650 #[cfg(feature = "no_std")]
651 use alloc::vec::Vec;
652 use core::cell::Cell;
653
654 #[derive(Debug)]
655 struct DropCounter(usize, Rc<Cell<usize>>);
656
657 impl Drop for DropCounter {
658 fn drop(&mut self) {
659 self.1.set(self.1.get() + 1);
660 }
661 }
662
663 #[test]
664 fn test_number_key_map_insert_and_get() {
665 const N: usize = 1_000_000;
666
667 let mut m = NumberKeyMap::new();
668 let drops = Rc::new(Cell::new(0));
669
670 for i in 0..N {
671 m.insert(i, DropCounter(i, drops.clone())).unwrap();
672
673 assert_eq!(m.get(i).map(|v| v.0), Some(i));
674 assert_eq!(m.get_mut(i).map(|v| v.0), Some(i));
675 }
676
677 for i in 0..N {
678 assert_eq!(m.get(i).map(|v| v.0), Some(i));
679 }
680
681 assert_eq!(drops.get(), 0);
682
683 for i in 0..N / 2 {
684 assert!(m.remove(i).is_some());
685 assert!(m.remove(i).is_none());
686 }
687
688 assert_eq!(drops.get(), N / 2);
689
690 drop(m);
691
692 assert_eq!(drops.get(), N);
693 }
694
695 #[test]
696 fn test_number_key_map_duplicate_key_returns_err() {
697 let mut m = NumberKeyMap::new();
698 let k = 1usize;
699 let drops = Rc::new(Cell::new(0));
700
701 m.insert(k, DropCounter(10, drops.clone())).unwrap();
702 assert!(m.insert(k, DropCounter(20, drops.clone())).is_err());
703
704 assert_eq!(m.get(k).map(|v| v.0), Some(10));
706
707 assert_eq!(drops.get(), 1);
708
709 drop(m);
710
711 assert_eq!(drops.get(), 2);
712 }
713
714 #[test]
715 fn test_number_key_map_clear() {
716 let mut m = NumberKeyMap::new();
717 let drops = Rc::new(Cell::new(0));
718
719 for i in 0..1_000_000 {
720 m.insert(i, DropCounter(i, drops.clone())).unwrap();
721 }
722
723 assert_eq!(drops.get(), 0);
724
725 m.clear();
726
727 assert_eq!(drops.get(), 1_000_000);
728
729 m.clear_with(|_| panic!("Not cleared"));
730
731 assert_eq!(drops.get(), 1_000_000);
732 }
733
734 #[test]
735 fn test_number_key_map_iter() {
736 let mut m = NumberKeyMap::new();
737 let drops = Rc::new(Cell::new(0));
738
739 for i in 0..10 {
740 m.insert(i, DropCounter(i, drops.clone())).unwrap();
741 }
742
743 let mut seen = Vec::new();
744 for (k, v) in m.iter() {
745 seen.push((k, v.0));
746 }
747
748 seen.sort_by_key(|x| x.0);
749
750 assert_eq!(seen, (0..10).map(|i| (i, i)).collect::<Vec<_>>());
751 assert_eq!(drops.get(), 0); }
753
754 #[test]
755 fn test_number_key_map_iter_mut() {
756 let mut m = NumberKeyMap::new();
757 let drops = Rc::new(Cell::new(0));
758
759 for i in 0..10 {
760 m.insert(i, DropCounter(i, drops.clone())).unwrap();
761 }
762
763 for (_, v) in m.iter_mut() {
764 v.0 *= 2;
765 }
766
767 let mut collected = m.iter().map(|(_, v)| v.0).collect::<Vec<_>>();
768
769 collected.sort_by_key(|x| *x);
770
771 assert_eq!(collected, (0..10).map(|i| i * 2).collect::<Vec<_>>());
772 assert_eq!(drops.get(), 0); }
774
775 #[test]
776 fn test_number_key_map_into_iter() {
777 let drops = Rc::new(Cell::new(0));
778 let mut m = NumberKeyMap::new();
779
780 for i in 0..10 {
781 m.insert(i, DropCounter(i, drops.clone())).unwrap();
782 }
783
784 assert_eq!(drops.get(), 0);
785
786 let mut seen = Vec::new();
787 for (k, v) in m {
788 seen.push((k, v.0));
789 }
790
791 seen.sort_by_key(|x| x.0);
793
794 assert_eq!(seen, (0..10).map(|i| (i, i)).collect::<Vec<_>>());
795
796 assert_eq!(drops.get(), 10);
798 }
799
800 #[test]
801 fn test_number_map_drain() {
802 let drops = Rc::new(Cell::new(0));
803 let mut m = NumberKeyMap::new();
804
805 for i in 0..10 {
806 m.insert(i, DropCounter(i, drops.clone())).unwrap();
807 }
808
809 assert_eq!(drops.get(), 0);
810
811 let mut seen = Vec::new();
812 for (k, v) in m.drain() {
813 seen.push((k, v.0));
814 }
815
816 seen.sort_by_key(|x| x.0);
818
819 assert_eq!(seen, (0..10).map(|i| (i, i)).collect::<Vec<_>>());
820
821 drop(m);
822
823 assert_eq!(drops.get(), 10);
825
826 let mut m = NumberKeyMap::new();
827
828 for i in 0..10 {
829 m.insert(i, DropCounter(i, drops.clone())).unwrap();
830 }
831
832 let iter = m.drain();
833
834 #[allow(clippy::drop_non_drop, reason = "It is tested here")]
835 drop(iter);
836
837 assert_eq!(drops.get(), 10);
838 }
839}