1use std::cell::Cell;
5use std::cell::RefCell;
6use std::collections::HashMap;
7#[cfg(test)]
8use std::collections::HashSet;
9use std::fmt::Debug;
10use std::fmt::Formatter;
11use std::fmt::Result as FmtResult;
12use std::hash::Hash;
13use std::hash::Hasher;
14use std::iter::Map;
15use std::ops::Deref;
16use std::rc::Rc;
17use std::slice;
18
19
20pub type Iter<'db, T, Aux> =
22 Map<slice::Iter<'db, (Rc<T>, Cell<Aux>)>, fn(&'_ (Rc<T>, Cell<Aux>)) -> &'_ Rc<T>>;
23
24
25#[repr(transparent)]
26struct HRc<T>(Rc<T>);
27
28impl<T> Hash for HRc<T> {
29 fn hash<H>(&self, state: &mut H)
30 where
31 H: Hasher,
32 {
33 Rc::as_ptr(&self.0).hash(state)
34 }
35}
36
37impl<T> PartialEq for HRc<T> {
38 fn eq(&self, other: &Self) -> bool {
39 Rc::ptr_eq(&self.0, &other.0)
40 }
41}
42
43impl<T> Eq for HRc<T> {}
44
45impl<T> Deref for HRc<T> {
46 type Target = Rc<T>;
47
48 fn deref(&self) -> &Self::Target {
49 &self.0
50 }
51}
52
53
54#[derive(Clone)]
57pub struct Entry<'db, T, Aux> {
58 data: &'db [(Rc<T>, Cell<Aux>)],
60 index: usize,
62}
63
64impl<'db, T, Aux> Entry<'db, T, Aux> {
65 #[inline]
67 fn new(data: &'db [(Rc<T>, Cell<Aux>)], index: usize) -> Self {
68 Self { data, index }
69 }
70
71 #[inline]
73 pub fn next(&self) -> Option<Entry<'db, T, Aux>> {
74 let index = self.index.checked_add(1)?;
75
76 if index < self.data.len() {
77 Some(Entry::new(self.data, index))
78 } else {
79 None
80 }
81 }
82
83 #[inline]
85 pub fn prev(&self) -> Option<Entry<'db, T, Aux>> {
86 if self.index > 0 {
87 Some(Entry::new(self.data, self.index - 1))
88 } else {
89 None
90 }
91 }
92
93 #[inline]
96 pub fn index(&self) -> usize {
97 self.index
98 }
99}
100
101impl<T, Aux> Entry<'_, T, Aux>
102where
103 Aux: Copy,
104{
105 #[inline]
108 pub fn aux(&self) -> Aux {
109 self.data[self.index].1.get()
110 }
111
112 #[inline]
114 pub fn set_aux(&self, aux: Aux) {
115 let () = self.data[self.index].1.set(aux);
116 }
117}
118
119impl<'db, T, Aux> Deref for Entry<'db, T, Aux> {
120 type Target = Rc<T>;
121
122 fn deref(&self) -> &'db Self::Target {
123 &self.data[self.index].0
124 }
125}
126
127impl<T, Aux> Debug for Entry<'_, T, Aux>
128where
129 T: Debug,
130 Aux: Copy + Debug,
131{
132 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
133 let Self { data, index } = self;
134
135 f.debug_tuple("Entry").field(&data).field(&index).finish()
136 }
137}
138
139
140fn update_ptr_idx<T, U>(by_ptr_idx: &mut HashMap<HRc<T>, ReplayIdx>, data: &[(Rc<T>, U)]) {
142 let iter = data.iter().enumerate().map(|(idx, (rc, _aux))| {
143 let rep_idx = ReplayIdx::new(idx, Gen(0));
144 (HRc(Rc::clone(rc)), rep_idx)
145 });
146
147 let () = by_ptr_idx.clear();
148 let () = by_ptr_idx.extend(iter);
149}
150
151
152#[inline]
155fn make_ptr_idx<T, U>(data: &[(Rc<T>, U)]) -> HashMap<HRc<T>, ReplayIdx> {
156 let mut idx = HashMap::new();
157 let () = update_ptr_idx(&mut idx, data);
158 idx
159}
160
161
162const INSERT_MASK: u32 = 0b1000_0000_0000_0000;
165
166
167#[derive(Debug)]
170#[repr(transparent)]
171struct InsDel(u32);
172
173impl InsDel {
174 #[inline]
176 fn insert(idx: usize) -> Self {
177 let idx = if cfg!(debug_assertions) {
178 u32::try_from(idx).unwrap()
179 } else {
180 idx as u32
181 };
182
183 debug_assert!(idx & INSERT_MASK == 0);
184 Self(INSERT_MASK | idx)
185 }
186
187 #[inline]
189 fn delete(idx: usize) -> Self {
190 let idx = if cfg!(debug_assertions) {
191 u32::try_from(idx).unwrap()
192 } else {
193 idx as u32
194 };
195
196 debug_assert!(idx & INSERT_MASK == 0);
197 Self(idx)
198 }
199
200 #[inline]
203 fn adjust(&self, idx: u32) -> u32 {
204 let op_idx = self.0 & !INSERT_MASK;
205
206 if op_idx <= idx {
209 let insert = (self.0 & INSERT_MASK) != 0;
210
211 if insert {
212 idx + 1
213 } else {
214 idx - 1
215 }
216 } else {
217 idx
218 }
219 }
220}
221
222
223#[derive(Debug)]
225#[repr(transparent)]
226struct Gen(u16);
227
228impl Gen {
229 fn new(r#gen: usize) -> Self {
230 let r#gen = if cfg!(debug_assertions) {
231 r#gen.try_into().unwrap()
232 } else {
233 r#gen as _
234 };
235
236 Self(r#gen)
237 }
238}
239
240
241#[derive(Debug)]
244struct ReplayIdx {
245 idx: u32,
246 r#gen: Gen,
247}
248
249impl ReplayIdx {
250 fn new(idx: usize, r#gen: Gen) -> Self {
251 Self {
252 idx: idx as u32,
253 r#gen,
254 }
255 }
256
257 fn replay(&self, ins_del: &[InsDel]) -> usize {
259 let r#gen = usize::from(self.r#gen.0);
260
261 let idx = if r#gen < ins_del.len() {
262 ins_del[r#gen..]
263 .iter()
264 .fold(self.idx, |idx, op| op.adjust(idx))
265 } else {
266 self.idx
267 };
268
269 idx as usize
270 }
271}
272
273
274pub struct Db<T, Aux = ()> {
284 data: Vec<(Rc<T>, Cell<Aux>)>,
287 by_ptr_idx: RefCell<HashMap<HRc<T>, ReplayIdx>>,
290 ins_del: Vec<InsDel>,
292}
293
294impl<T> Db<T, ()> {
295 #[cfg(test)]
298 pub fn try_from_iter<I>(iter: I) -> Result<Self, Rc<T>>
299 where
300 I: IntoIterator<Item = Rc<T>>,
301 {
302 let data = iter
303 .into_iter()
304 .map(|item| (item, Cell::default()))
305 .collect::<Vec<_>>();
306 let set = HashSet::with_capacity(data.len());
308 let _set = data.iter().try_fold(set, |mut set, (rc, _aux)| {
309 if !set.insert(Rc::as_ptr(rc)) {
310 Err(Rc::clone(rc))
311 } else {
312 Ok(set)
313 }
314 })?;
315
316 let slf = Self {
317 by_ptr_idx: RefCell::new(make_ptr_idx(&data)),
318 data,
319 ins_del: Vec::new(),
320 };
321 Ok(slf)
322 }
323
324 #[cfg(test)]
326 pub fn from_iter<I>(iter: I) -> Self
327 where
328 I: IntoIterator<Item = T>,
329 {
330 Self::from_iter_with_aux(iter.into_iter().map(|item| (item, ())))
331 }
332}
333
334impl<T, Aux> Db<T, Aux> {
335 pub fn from_iter_with_aux<I>(iter: I) -> Self
337 where
338 I: IntoIterator<Item = (T, Aux)>,
339 {
340 let data = iter
341 .into_iter()
342 .map(|(item, aux)| (Rc::new(item), Cell::new(aux)))
343 .collect::<Vec<_>>();
344
345 Self {
346 by_ptr_idx: RefCell::new(make_ptr_idx(&data)),
347 data,
348 ins_del: Vec::new(),
349 }
350 }
351
352 #[inline]
354 fn maybe_rebuild_by_ptr_idx(&mut self) -> bool {
355 if self.ins_del.len() >= 1 << 12 {
359 let by_ptr_idx = self.by_ptr_idx.get_mut();
360 let () = update_ptr_idx(by_ptr_idx, &self.data);
362 let () = self.ins_del.clear();
363 true
364 } else {
365 false
366 }
367 }
368
369 fn index(&mut self, idx: usize) {
375 if self.maybe_rebuild_by_ptr_idx() {
376 return
379 }
380
381 let by_ptr_idx = self.by_ptr_idx.get_mut();
382 let () = self.ins_del.push(InsDel::insert(idx));
383 let r#gen = Gen::new(self.ins_del.len());
384 let rep_idx = ReplayIdx::new(idx, r#gen);
385
386 let rc = &self.data[idx].0;
387 let _prev = by_ptr_idx.insert(HRc(Rc::clone(rc)), rep_idx);
388 debug_assert!(
389 _prev.is_none(),
390 "attempting to index already existing element @ {idx}"
391 );
392 }
393
394 fn deindex(&mut self, idx: usize) {
400 let _rebuilt = self.maybe_rebuild_by_ptr_idx();
401
402 let by_ptr_idx = self.by_ptr_idx.get_mut();
406
407 let () = self.ins_del.push(InsDel::delete(idx));
408
409 let rc = &self.data[idx].0;
410 let _removed = by_ptr_idx.remove(&HRc(Rc::clone(rc)));
412 debug_assert!(
413 _removed.is_some(),
414 "attempting to de-index non-existent element @ {idx}"
415 );
416 }
417
418 #[inline]
420 pub fn find(&self, item: &Rc<T>) -> Option<Entry<'_, T, Aux>> {
421 let mut by_ptr_idx = self.by_ptr_idx.borrow_mut();
422
423 by_ptr_idx
425 .get_mut(&HRc(Rc::clone(item)))
426 .and_then(|rep_idx| {
427 let data_idx = rep_idx.replay(&self.ins_del);
428
429 let r#gen = Gen::new(self.ins_del.len());
430 *rep_idx = ReplayIdx::new(data_idx, r#gen);
431
432 self.get(data_idx)
433 })
434 }
435
436 #[cfg(test)]
438 #[inline]
439 pub fn insert(&mut self, index: usize, item: T) -> Entry<'_, T, Aux>
440 where
441 Aux: Default,
442 {
443 self.insert_with_aux(index, item, Aux::default())
444 }
445
446 #[cfg(test)]
449 #[inline]
450 pub fn insert_with_aux(&mut self, index: usize, item: T, aux: Aux) -> Entry<'_, T, Aux> {
451 let () = self.data.insert(index, (Rc::new(item), Cell::new(aux)));
452 let () = self.index(index);
453 self.get(index).unwrap()
456 }
457
458 #[cfg(test)]
462 #[inline]
463 pub fn try_insert(&mut self, index: usize, item: Rc<T>) -> Option<Entry<'_, T, Aux>>
464 where
465 Aux: Default,
466 {
467 self.try_insert_with_aux(index, item, Aux::default())
468 }
469
470 #[inline]
475 pub fn try_insert_with_aux(
476 &mut self,
477 index: usize,
478 item: Rc<T>,
479 aux: Aux,
480 ) -> Option<Entry<'_, T, Aux>> {
481 if self.find(&item).is_some() {
482 None
483 } else {
484 let () = self.data.insert(index, (item, Cell::new(aux)));
485 let () = self.index(index);
486 self.get(index)
487 }
488 }
489
490 #[cfg(test)]
492 #[inline]
493 pub fn push(&mut self, item: T) -> Entry<'_, T, Aux>
494 where
495 Aux: Default,
496 {
497 self.push_with_aux(item, Aux::default())
498 }
499
500 #[cfg(test)]
503 #[inline]
504 pub fn push_with_aux(&mut self, item: T, aux: Aux) -> Entry<'_, T, Aux> {
505 let rc = Rc::new(item);
506 let idx = self.data.len();
507 let () = self.data.push((rc, Cell::new(aux)));
508 let () = self.index(idx);
509 self.last().unwrap()
512 }
513
514 #[cfg(test)]
518 #[inline]
519 pub fn try_push(&mut self, item: Rc<T>) -> Option<Entry<'_, T, Aux>>
520 where
521 Aux: Default,
522 {
523 self.try_push_with_aux(item, Aux::default())
524 }
525
526 #[cfg(test)]
531 #[inline]
532 pub fn try_push_with_aux(&mut self, item: Rc<T>, aux: Aux) -> Option<Entry<'_, T, Aux>> {
533 if self.find(&item).is_some() {
534 None
535 } else {
536 let idx = self.data.len();
537 let () = self.data.push((item, Cell::new(aux)));
538 let () = self.index(idx);
539 self.last()
540 }
541 }
542
543 #[inline]
545 pub fn remove(&mut self, index: usize) -> (Rc<T>, Aux) {
546 let () = self.deindex(index);
547 let (item, aux) = self.data.remove(index);
548 (item, aux.into_inner())
549 }
550
551 #[inline]
554 pub fn get(&self, index: usize) -> Option<Entry<'_, T, Aux>> {
555 if index < self.data.len() {
556 Some(Entry::new(&self.data, index))
557 } else {
558 None
559 }
560 }
561
562 #[inline]
564 pub fn len(&self) -> usize {
565 self.data.len()
566 }
567
568 #[inline]
570 pub fn last(&self) -> Option<Entry<'_, T, Aux>> {
571 let len = self.data.len();
572 if len > 0 {
573 Some(Entry::new(&self.data, len - 1))
574 } else {
575 None
576 }
577 }
578
579 #[inline]
581 pub fn iter(&self) -> Iter<'_, T, Aux> {
582 fn map<T, Aux>(x: &(T, Cell<Aux>)) -> &T {
583 &x.0
584 }
585
586 self.data.iter().map(map as _)
587 }
588}
589
590impl<T, Aux> Debug for Db<T, Aux>
591where
592 T: Debug,
593 Aux: Copy + Debug,
594{
595 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
596 let Self {
597 data,
598 by_ptr_idx: _,
599 ins_del: _,
600 } = self;
601
602 f.debug_struct("Db").field("data", &data).finish()
603 }
604}
605
606
607#[cfg(test)]
608pub mod tests {
609 use super::*;
610
611 #[cfg(feature = "nightly")]
612 use std::hint::black_box;
613 use std::mem::size_of;
614
615 #[cfg(feature = "nightly")]
616 use unstable_test::Bencher;
617
618
619 #[cfg(feature = "nightly")]
620 const ITEM_CNT: usize = 10000;
621
622
623 #[test]
625 fn type_sizes() {
626 assert_eq!(size_of::<InsDel>(), 4);
627 assert_eq!(size_of::<Gen>(), 2);
628 }
629
630 #[test]
632 fn entry_aux_set_get() {
633 let iter = ["foo", "boo", "blah"]
634 .into_iter()
635 .enumerate()
636 .map(|(idx, item)| (item, idx));
637 let db = Db::from_iter_with_aux(iter);
638 let entry = db.get(1).unwrap();
639 assert_eq!(entry.aux(), 1);
640
641 let () = entry.set_aux(42);
642 assert_eq!(entry.aux(), 42);
643
644 let entry = db.get(1).unwrap();
645 assert_eq!(entry.aux(), 42);
646 }
647
648 #[test]
650 fn entry_navigation() {
651 let db = Db::from_iter(["foo", "boo", "blah"]);
652
653 let entry = db.get(0).unwrap();
654 assert_eq!(entry.deref().deref(), &"foo");
655 assert!(entry.prev().is_none());
656
657 let entry = entry.next().unwrap();
658 assert_eq!(entry.deref().deref(), &"boo");
659
660 let entry = entry.next().unwrap();
661 assert_eq!(entry.deref().deref(), &"blah");
662
663 assert!(entry.next().is_none());
664
665 let entry = entry.prev().unwrap();
666 assert_eq!(entry.deref().deref(), &"boo");
667 }
668
669 #[test]
671 fn create_from_iter() {
672 let items = ["foo", "bar", "baz", "foobar"];
673 let db = Db::from_iter(items);
674 assert_eq!(**db.get(0).unwrap(), "foo");
675 assert_eq!(**db.get(3).unwrap(), "foobar");
676 }
677
678 #[test]
681 fn create_from_iter_duplicate() {
682 let foo = Rc::new("foo");
683 let items = [
684 Rc::clone(&foo),
685 Rc::new("bar"),
686 Rc::new("baz"),
687 Rc::clone(&foo),
688 Rc::new("foobar"),
689 ];
690 let duplicate = Db::try_from_iter(items).unwrap_err();
691 assert!(Rc::ptr_eq(&duplicate, &foo));
692 }
693
694 #[test]
696 fn find_item() {
697 let items = ["foo", "bar", "baz", "foobar"]
698 .into_iter()
699 .map(Rc::new)
700 .collect::<Vec<_>>();
701 let bar = Rc::clone(&items[1]);
702
703 let db = Db::try_from_iter(items.clone()).unwrap();
704 assert_eq!(db.find(&bar).map(|entry| entry.index()), Some(1));
705
706 let hihi = Rc::new("hihi");
707 let db = Db::try_from_iter(items).unwrap();
708 assert_eq!(db.find(&hihi).map(|entry| entry.index()), None);
709 }
710
711 #[test]
713 fn insert_item() {
714 let items = ["foo", "bar", "baz", "foobar"];
715
716 let mut db = Db::from_iter(items);
717 let item = Rc::clone(&db.insert(0, "foobarbaz"));
718 let idx = db.find(&item).unwrap().index();
719 assert_eq!(idx, 0);
720
721 let item = Rc::clone(&db.insert(5, "outoffoos"));
722 let idx = db.find(&item).unwrap().index();
723 assert_eq!(idx, 5);
724 }
725
726 #[test]
728 fn try_insert_item() {
729 let items = ["foo", "bar", "baz", "foobar"];
730
731 let mut db = Db::from_iter(items);
732 let item = Rc::clone(&db.try_insert(0, Rc::new("foobarbaz")).unwrap());
733 let idx = db.find(&item).unwrap().index();
734 assert_eq!(idx, 0);
735
736 let item = Rc::clone(&db.get(0).unwrap());
737 assert!(db.try_insert(5, item).is_none())
738 }
739
740 #[test]
742 fn push_item() {
743 let mut db = Db::from_iter([]);
744 let item = Rc::clone(&db.push("foo"));
745 let idx = db.find(&item).unwrap().index();
746 assert_eq!(idx, 0);
747
748 let item = Rc::clone(&db.push("bar"));
749 let idx = db.find(&item).unwrap().index();
750 assert_eq!(idx, 1);
751
752 let _removed = db.remove(0);
753 let item = Rc::clone(&db.push("baz"));
754 let idx = db.find(&item).unwrap().index();
755 assert_eq!(idx, 1);
756 }
757
758 #[test]
761 fn try_push_item() {
762 let mut db = Db::from_iter(["foo", "boo", "blah"]);
763 let item = Rc::clone(&db.try_push(Rc::new("foo")).unwrap());
764 let idx = db.find(&item).unwrap().index();
765 assert_eq!(idx, 3);
766
767 let item = Rc::clone(&db.get(1).unwrap());
768 assert!(db.try_push(item).is_none())
769 }
770
771 #[test]
773 fn iteration() {
774 let items = ["foo", "bar", "baz", "foobar"];
775
776 let db = Db::from_iter(items);
777 let vec = db.iter().map(|rc| **rc).collect::<Vec<_>>();
778 assert_eq!(vec, items);
779 }
780
781 #[cfg(feature = "nightly")]
783 #[bench]
784 fn bench_insert(b: &mut Bencher) {
785 let () = b.iter(|| {
786 let mut db = Db::from_iter([]);
787 let () = db.data.reserve(ITEM_CNT);
790
791 for i in 1..ITEM_CNT {
792 let _entry = db.insert(0, black_box(i));
793 }
794 });
795 }
796
797 #[cfg(feature = "nightly")]
799 #[bench]
800 fn bench_try_insert(b: &mut Bencher) {
801 let items = (0..ITEM_CNT).map(Rc::new).collect::<Vec<_>>();
802
803 let () = b.iter(|| {
804 let mut db = Db::from_iter([]);
805 let () = db.data.reserve(ITEM_CNT);
806
807 for item in items.iter() {
808 assert!(db
809 .try_insert(black_box(0), black_box(Rc::clone(item)))
810 .is_some());
811 }
812 });
813 }
814
815 #[cfg(feature = "nightly")]
817 #[bench]
818 fn bench_push(b: &mut Bencher) {
819 let () = b.iter(|| {
820 let mut db = Db::from_iter([]);
821 let () = db.data.reserve(ITEM_CNT);
822
823 for i in 1..ITEM_CNT {
824 let _entry = db.push(black_box(i));
825 }
826 });
827 }
828
829 #[cfg(feature = "nightly")]
831 #[bench]
832 fn bench_try_push(b: &mut Bencher) {
833 let items = (0..ITEM_CNT).map(Rc::new).collect::<Vec<_>>();
834
835 let () = b.iter(|| {
836 let mut db = Db::from_iter([]);
837 let () = db.data.reserve(ITEM_CNT);
838
839 for item in items.iter() {
840 assert!(db.try_push(black_box(Rc::clone(item))).is_some());
841 }
842 });
843 }
844
845 #[cfg(feature = "nightly")]
847 #[bench]
848 fn bench_finding(b: &mut Bencher) {
849 let mut db = Db::from_iter([]);
850
851 let items = (1..ITEM_CNT)
852 .map(|i| Rc::clone(db.push(i).deref()))
853 .collect::<HashSet<_>>();
854
855 let () = b.iter(|| {
856 let () = items.iter().for_each(|item| {
858 let _item = db.find(black_box(item)).unwrap();
859 });
860 });
861 }
862
863 #[cfg(feature = "nightly")]
865 #[bench]
866 fn bench_remove_first(b: &mut Bencher) {
867 let () = b.iter(|| {
868 let mut db = Db::from_iter(0..ITEM_CNT);
869 for _ in 0..ITEM_CNT {
870 let _item = db.remove(black_box(0));
871 }
872 });
873 }
874
875 #[cfg(feature = "nightly")]
877 #[bench]
878 fn bench_remove_last(b: &mut Bencher) {
879 let () = b.iter(|| {
880 let mut db = Db::from_iter(0..ITEM_CNT);
881 for _ in 0..ITEM_CNT {
882 let _item = db.remove(black_box(db.len() - 1));
883 }
884 });
885 }
886}