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(
282 new_inner,
283 new_capacity,
284 slot.key,
285 &raw const slot.value,
286 )
287 };
288 if unlikely(res.is_err()) {
289 assert_hint(
290 matches!(res, Err(InsertFailErr::NotEnoughSpace)),
291 "invalid inner state is detected while reallocating: duplicate key",
292 );
293
294 new_capacity = Self::greater_capacity(new_capacity);
296
297 unsafe { dealloc(new_inner.cast(), layout) };
298
299 continue 'allocate;
300 }
301 }
302 }
303
304 let res =
306 unsafe { Self::insert_or_fail(new_inner, new_capacity, key, &raw const value) };
307
308 let mut commit_reallocate = || {
309 unsafe {
310 dealloc(
311 self.inner.cast(),
312 unwrap_or_bug_hint(Layout::array::<Slot<V>>(self.capacity)),
313 );
314 };
315
316 self.inner = new_inner;
317 self.capacity = new_capacity;
318 };
319
320 match res {
321 Ok(()) => {
322 commit_reallocate();
323
324 mem::forget(value);
325
326 break Ok(());
327 }
328
329 Err(InsertFailErr::NotEnoughSpace) => {
330 cold_path();
331
332 new_capacity = Self::greater_capacity(new_capacity);
334
335 unsafe { dealloc(new_inner.cast(), layout) };
336
337 }
339
340 Err(InsertFailErr::KeyAlreadyExists) => {
341 commit_reallocate();
345
346 break Err(value);
347 }
348 }
349 }
350 }
351
352 #[cold]
354 #[inline(never)]
355 fn insert_first(&mut self, key: usize, value: V) {
356 Self::validate_key(key);
357
358 let layout = unwrap_or_bug_hint(Layout::array::<Slot<V>>(1));
359 let inner: *mut Slot<V> = unsafe { alloc(layout) }.cast();
360 unsafe { inner.write(Slot { key, value }) };
361
362 self.inner = inner;
363 self.capacity = 1;
364 }
365
366 pub fn insert(&mut self, key: usize, value: V) -> Result<(), V> {
381 Self::validate_key(key);
382
383 if unlikely(self.inner.is_null()) {
384 self.insert_first(key, value);
385
386 return Ok(());
387 }
388
389 let res = unsafe { Self::insert_or_fail(self.inner, self.capacity, key, &raw const value) };
390 if likely(res.is_ok()) {
391 mem::forget(value);
392
393 return Ok(());
394 }
395
396 self.slow_insert(key, value)
397 }
398
399 pub fn remove(&mut self, key: usize) -> Option<V> {
405 Self::validate_key(key);
406
407 let idx = Self::get_started_slot_idx_for_key(key, self.capacity);
408 let slot = self.get_slot_mut(idx);
409 if unlikely(slot.key == usize::MAX) {
410 return None;
411 }
412
413 slot.key = usize::MAX;
414
415 Some(unsafe { ptr::read(&raw const slot.value) })
416 }
417
418 pub fn clear_with(&mut self, func: impl Fn((usize, V))) {
420 if self.inner.is_null() {
421 return;
422 }
423
424 for i in 0..self.capacity {
425 let slot_ptr = unsafe { self.inner.add(i) };
426 let slot = unsafe { &mut *slot_ptr };
427
428 if slot.key != usize::MAX {
429 func((slot.key, unsafe { ptr::read(&raw const slot.value) }));
430 slot.key = usize::MAX;
431 }
432 }
433 }
434
435 pub fn clear(&mut self) {
437 self.clear_with(drop);
438 }
439}
440
441impl<V> Default for NumberKeyMap<V> {
442 fn default() -> Self {
443 Self::new()
444 }
445}
446
447pub struct IntoIter<V> {
452 start: *mut Slot<V>,
453 i: usize,
454 capacity: usize,
455}
456
457impl<V> Iterator for IntoIter<V> {
458 type Item = (usize, V);
459
460 fn next(&mut self) -> Option<Self::Item> {
461 unsafe {
462 while self.i < self.capacity {
463 let ptr = self.start.add(self.i);
464 let slot = &mut *ptr;
465
466 self.i += 1;
467
468 if slot.key != usize::MAX {
469 return Some((slot.key, ptr::read(&raw const slot.value)));
470 }
471 }
472
473 None
474 }
475 }
476}
477
478impl<V> Drop for IntoIter<V> {
479 fn drop(&mut self) {
480 unsafe {
481 for (_k, v) in self.by_ref() {
483 drop(v);
484 }
485
486 let layout = Layout::array::<Slot<V>>(self.capacity).unwrap();
488
489 dealloc(self.start.cast(), layout);
490 }
491 }
492}
493
494impl<V> NumberKeyMap<V> {
495 pub fn iter(&self) -> impl Iterator<Item = (usize, &V)> {
497 struct Iter<'a, V> {
498 ptr: *mut Slot<V>,
499 end: *mut Slot<V>,
500 _marker: core::marker::PhantomData<&'a V>,
501 }
502
503 impl<'a, V> Iterator for Iter<'a, V> {
504 type Item = (usize, &'a V);
505
506 fn next(&mut self) -> Option<Self::Item> {
507 unsafe {
508 while self.ptr < self.end {
509 let slot = &*self.ptr;
510
511 self.ptr = self.ptr.add(1);
512
513 if slot.key != usize::MAX {
514 return Some((slot.key, &slot.value));
515 }
516 }
517
518 None
519 }
520 }
521 }
522
523 Iter {
524 ptr: self.inner,
525 end: unsafe { self.inner.add(self.capacity) },
526 _marker: core::marker::PhantomData,
527 }
528 }
529
530 pub fn iter_mut(&mut self) -> impl Iterator<Item = (usize, &mut V)> {
532 struct IterMut<'a, V> {
533 ptr: *mut Slot<V>,
534 end: *mut Slot<V>,
535 _marker: core::marker::PhantomData<&'a mut V>,
536 }
537
538 impl<'a, V: 'a> Iterator for IterMut<'a, V> {
539 type Item = (usize, &'a mut V);
540
541 fn next(&mut self) -> Option<Self::Item> {
542 unsafe {
543 while self.ptr < self.end {
544 let slot = &mut *self.ptr;
545
546 self.ptr = self.ptr.add(1);
547
548 if slot.key != usize::MAX {
549 return Some((slot.key, &mut slot.value));
550 }
551 }
552
553 None
554 }
555 }
556 }
557
558 IterMut {
559 ptr: self.inner,
560 end: unsafe { self.inner.add(self.capacity) },
561 _marker: core::marker::PhantomData,
562 }
563 }
564}
565
566impl<V: 'static> NumberKeyMap<V> {
567 pub fn drain(&mut self) -> impl Iterator<Item = (usize, V)> {
569 struct Drain<'a, V> {
570 ptr: *mut Slot<V>,
571 end: *mut Slot<V>,
572 _marker: core::marker::PhantomData<&'a mut V>,
573 }
574
575 impl<V: 'static> Iterator for Drain<'_, V> {
576 type Item = (usize, V);
577
578 fn next(&mut self) -> Option<Self::Item> {
579 unsafe {
580 while self.ptr < self.end {
581 let slot = &mut *self.ptr;
582
583 self.ptr = self.ptr.add(1);
584
585 if slot.key != usize::MAX {
586 let key = slot.key;
587
588 slot.key = usize::MAX;
589
590 return Some((key, ptr::read(&raw const slot.value)));
591 }
592 }
593
594 None
595 }
596 }
597 }
598
599 Drain {
600 ptr: self.inner,
601 end: unsafe { self.inner.add(self.capacity) },
602 _marker: core::marker::PhantomData,
603 }
604 }
605}
606
607impl<V> IntoIterator for NumberKeyMap<V> {
608 type Item = (usize, V);
609 type IntoIter = IntoIter<V>;
610
611 fn into_iter(self) -> Self::IntoIter {
612 let iter = IntoIter {
613 start: self.inner,
614 i: 0,
615 capacity: self.capacity,
616 };
617
618 mem::forget(self);
619
620 iter
621 }
622}
623
624unsafe impl<V> Sync for NumberKeyMap<V> {}
625unsafe impl<V> Send for NumberKeyMap<V> {}
626
627impl<V> Drop for NumberKeyMap<V> {
628 fn drop(&mut self) {
629 if self.inner.is_null() {
630 return;
631 }
632
633 if mem::needs_drop::<V>() {
634 for i in 0..self.capacity {
635 let slot_ptr = unsafe { self.inner.add(i) };
636 let slot = unsafe { &mut *slot_ptr };
637
638 if slot.key != usize::MAX {
639 unsafe { (&raw mut slot.value).drop_in_place() };
640 }
641 }
642 }
643
644 let layout = Layout::array::<Slot<V>>(self.capacity).unwrap();
645 unsafe {
646 dealloc(self.inner.cast(), layout);
647 }
648 }
649}
650
651#[cfg(test)]
652mod tests {
653 use super::*;
654
655 use alloc::rc::Rc;
656 #[cfg(feature = "no_std")]
657 use alloc::vec::Vec;
658 use core::cell::Cell;
659
660 #[derive(Debug)]
661 struct DropCounter(usize, Rc<Cell<usize>>);
662
663 impl Drop for DropCounter {
664 fn drop(&mut self) {
665 self.1.set(self.1.get() + 1);
666 }
667 }
668
669 #[test]
670 fn test_number_key_map_insert_and_get() {
671 const N: usize = 1_000_000;
672
673 let mut m = NumberKeyMap::new();
674 let drops = Rc::new(Cell::new(0));
675
676 for i in 0..N {
677 m.insert(i, DropCounter(i, drops.clone())).unwrap();
678
679 assert_eq!(m.get(i).map(|v| v.0), Some(i));
680 assert_eq!(m.get_mut(i).map(|v| v.0), Some(i));
681 }
682
683 for i in 0..N {
684 assert_eq!(m.get(i).map(|v| v.0), Some(i));
685 }
686
687 assert_eq!(drops.get(), 0);
688
689 for i in 0..N / 2 {
690 assert!(m.remove(i).is_some());
691 assert!(m.remove(i).is_none());
692 }
693
694 assert_eq!(drops.get(), N / 2);
695
696 drop(m);
697
698 assert_eq!(drops.get(), N);
699 }
700
701 #[test]
702 fn test_number_key_map_duplicate_key_returns_err() {
703 let mut m = NumberKeyMap::new();
704 let k = 1usize;
705 let drops = Rc::new(Cell::new(0));
706
707 m.insert(k, DropCounter(10, drops.clone())).unwrap();
708 assert!(m.insert(k, DropCounter(20, drops.clone())).is_err());
709
710 assert_eq!(m.get(k).map(|v| v.0), Some(10));
712
713 assert_eq!(drops.get(), 1);
714
715 drop(m);
716
717 assert_eq!(drops.get(), 2);
718 }
719
720 #[test]
721 fn test_number_key_map_clear() {
722 let mut m = NumberKeyMap::new();
723 let drops = Rc::new(Cell::new(0));
724
725 for i in 0..1_000_000 {
726 m.insert(i, DropCounter(i, drops.clone())).unwrap();
727 }
728
729 assert_eq!(drops.get(), 0);
730
731 m.clear();
732
733 assert_eq!(drops.get(), 1_000_000);
734
735 m.clear_with(|_| panic!("Not cleared"));
736
737 assert_eq!(drops.get(), 1_000_000);
738 }
739
740 #[test]
741 fn test_number_key_map_iter() {
742 let mut m = NumberKeyMap::new();
743 let drops = Rc::new(Cell::new(0));
744
745 for i in 0..10 {
746 m.insert(i, DropCounter(i, drops.clone())).unwrap();
747 }
748
749 let mut seen = Vec::new();
750 for (k, v) in m.iter() {
751 seen.push((k, v.0));
752 }
753
754 seen.sort_by_key(|x| x.0);
755
756 assert_eq!(seen, (0..10).map(|i| (i, i)).collect::<Vec<_>>());
757 assert_eq!(drops.get(), 0); }
759
760 #[test]
761 fn test_number_key_map_iter_mut() {
762 let mut m = NumberKeyMap::new();
763 let drops = Rc::new(Cell::new(0));
764
765 for i in 0..10 {
766 m.insert(i, DropCounter(i, drops.clone())).unwrap();
767 }
768
769 for (_, v) in m.iter_mut() {
770 v.0 *= 2;
771 }
772
773 let mut collected = m.iter().map(|(_, v)| v.0).collect::<Vec<_>>();
774
775 collected.sort_by_key(|x| *x);
776
777 assert_eq!(collected, (0..10).map(|i| i * 2).collect::<Vec<_>>());
778 assert_eq!(drops.get(), 0); }
780
781 #[test]
782 fn test_number_key_map_into_iter() {
783 let drops = Rc::new(Cell::new(0));
784 let mut m = NumberKeyMap::new();
785
786 for i in 0..10 {
787 m.insert(i, DropCounter(i, drops.clone())).unwrap();
788 }
789
790 assert_eq!(drops.get(), 0);
791
792 let mut seen = Vec::new();
793 for (k, v) in m {
794 seen.push((k, v.0));
795 }
796
797 seen.sort_by_key(|x| x.0);
799
800 assert_eq!(seen, (0..10).map(|i| (i, i)).collect::<Vec<_>>());
801
802 assert_eq!(drops.get(), 10);
804 }
805
806 #[test]
807 fn test_number_map_drain() {
808 let drops = Rc::new(Cell::new(0));
809 let mut m = NumberKeyMap::new();
810
811 for i in 0..10 {
812 m.insert(i, DropCounter(i, drops.clone())).unwrap();
813 }
814
815 assert_eq!(drops.get(), 0);
816
817 let mut seen = Vec::new();
818 for (k, v) in m.drain() {
819 seen.push((k, v.0));
820 }
821
822 seen.sort_by_key(|x| x.0);
824
825 assert_eq!(seen, (0..10).map(|i| (i, i)).collect::<Vec<_>>());
826
827 drop(m);
828
829 assert_eq!(drops.get(), 10);
831
832 let mut m = NumberKeyMap::new();
833
834 for i in 0..10 {
835 m.insert(i, DropCounter(i, drops.clone())).unwrap();
836 }
837
838 let iter = m.drain();
839
840 #[allow(clippy::drop_non_drop, reason = "It is tested here")]
841 drop(iter);
842
843 assert_eq!(drops.get(), 10);
844 }
845}