1use std::marker::PhantomData;
17use std::ptr;
18
19#[derive(Debug)]
20struct Entry<T> {
21 index: usize,
22 data: Option<T>,
23 next: *mut Entry<T>,
25 prev: *mut Entry<T>,
26 _pin: std::marker::PhantomPinned,
27}
28
29#[derive(Debug)]
31pub struct Persist<T> {
32 entries: Vec<Entry<T>>,
33 free: Option<*mut Entry<T>>,
36 used: Option<*mut Entry<T>>,
39 length: usize,
40}
41
42impl<T> Persist<T> {
43 #[inline(always)]
45 fn link_to_prev(i: usize, entries: &mut Vec<Entry<T>>) {
46 entries[i - 1].next = &mut entries[i];
47 entries[i].prev = &mut entries[i - 1];
48 }
49
50 #[inline]
59 pub fn with_capacity(capacity: usize) -> Persist<T> {
60 let mut entries = Vec::with_capacity(capacity);
61 for i in 0..capacity {
62 entries.push(Entry {
63 index: i,
64 data: None,
65 next: ptr::null_mut(),
66 prev: ptr::null_mut(),
67 _pin: std::marker::PhantomPinned,
68 });
69 if i > 0 {
70 Persist::link_to_prev(i, &mut entries);
71 }
72 }
73 let first = &mut entries[0] as *mut Entry<T>;
74 Persist {
75 entries,
76 free: Some(first),
77 used: None,
78 length: 0,
79 }
80 }
81
82 #[inline]
92 pub fn with_capacity_filled_by<F>(capacity: usize, func: F) -> Persist<T>
93 where
94 F: Fn() -> T,
95 {
96 let mut entries = Vec::with_capacity(capacity);
97 for i in 0..capacity {
98 entries.push(Entry {
99 index: i,
100 data: Some(func()),
101 next: ptr::null_mut(),
102 prev: ptr::null_mut(),
103 _pin: std::marker::PhantomPinned,
104 });
105 if i > 0 {
106 Persist::link_to_prev(i, &mut entries);
107 }
108 }
109 let first = &mut entries[0] as *mut Entry<T>;
110 Persist {
111 entries,
112 free: None,
113 used: Some(first),
114 length: capacity,
115 }
116 }
117
118 #[inline]
119 pub fn from(slice: &[T]) -> Persist<T>
120 where
121 T: Clone,
122 {
123 let mut entries = Vec::with_capacity(slice.len());
124 for (i, obj) in slice.iter().enumerate() {
125 entries.push(Entry {
126 index: i,
127 data: Some(obj.clone()),
128 next: ptr::null_mut(),
129 prev: ptr::null_mut(),
130 _pin: std::marker::PhantomPinned,
131 });
132 if i > 0 {
133 Persist::link_to_prev(i, &mut entries);
134 }
135 }
136 let first = &mut entries[0] as *mut Entry<T>;
137 Persist {
138 entries,
139 free: None,
140 used: Some(first),
141 length: slice.len(),
142 }
143 }
144
145 #[inline]
177 pub fn len(&self) -> usize {
178 self.length
179 }
180
181 #[inline]
182 pub fn is_empty(&self) -> bool {
183 self.length == 0
184 }
185
186 #[inline]
188 pub fn capacity(&self) -> usize {
189 self.entries.capacity()
190 }
191
192 #[inline]
196 pub fn clear(&mut self) {
197 for i in 0..self.entries.len() {
198 self.entries[i].data = None;
199 if i > 0 {
200 self.entries[i - 1].next = &mut self.entries[i];
201 self.entries[i].prev = &mut self.entries[i - 1];
202 }
203 if i == 0 {
205 self.entries[i].prev = ptr::null_mut();
206 }
207 if i == self.entries.len() - 1 {
208 self.entries[i].next = ptr::null_mut();
209 }
210 }
211 self.free = Some(&mut self.entries[0]);
212 self.used = None;
213 self.length = 0;
214 }
215
216 #[inline]
217 pub fn get(&self, index: usize) -> Option<&T> {
218 if let Some(entry) = self.entries.get(index) {
219 return entry.data.as_ref();
220 }
221 None
222 }
223
224 #[inline]
225 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
226 if let Some(entry) = self.entries.get_mut(index) {
227 return entry.data.as_mut();
228 }
229 None
230 }
231
232 #[inline]
234 pub fn is_index_live(&self, index: usize) -> bool {
235 if let Some(entry) = self.entries.get(index) {
236 if entry.data.is_some() {
237 return true;
238 }
239 }
240 false
241 }
242
243 #[inline]
252 pub fn push(&mut self, value: T) -> Option<usize> {
253 unsafe {
254 if let Some(into_used) = self.free.as_ref() {
255 if let Some(mut into_used) = into_used.as_mut() {
256 into_used.data = Some(value);
257 let next_free = into_used.next;
259 Persist::disassociate_entry(into_used);
260 self.free = Some(next_free);
261 if let Some(head_free) = self.free {
263 if let Some(head_free) = head_free.as_mut() {
264 head_free.prev = ptr::null_mut();
265 }
266 }
267
268 if let Some(used) = self.used {
269 into_used.next = used;
270 (*used).prev = into_used;
271 }
272 self.used = Some(into_used);
273 self.length += 1;
274 return Some(into_used.index);
275 }
276 }
277 }
278 None
279 }
280
281 #[inline(always)]
283 fn disassociate_entry(slot: &mut Entry<T>) {
284 unsafe {
285 if let Some(mut prev) = slot.prev.as_mut() {
286 if let Some(mut next) = slot.next.as_mut() {
287 prev.next = next;
288 next.prev = prev;
289 } else {
290 prev.next = ptr::null_mut();
292 }
293 } else if let Some(mut next) = slot.next.as_mut() {
294 next.prev = ptr::null_mut();
296 }
297 }
298 slot.next = ptr::null_mut();
299 slot.prev = ptr::null_mut();
300 }
301
302 #[inline]
308 pub fn insert(&mut self, index: usize, value: T) -> Option<T> {
309 if self.entries[index].data.is_none() {
311 let mut slot = &mut self.entries[index];
312 Persist::disassociate_entry(slot);
314 slot.prev = ptr::null_mut();
316 unsafe {
318 if let Some(first_used) = self.used {
319 slot.next = first_used;
320 (*first_used).prev = slot
321 }
322 }
323
324 self.used = Some(&mut self.entries[index]);
325 }
326
327 let mut data: Option<T> = Some(value);
328 std::mem::swap(&mut self.entries[index].data, &mut data);
329 self.length += 1;
330 data
331 }
332
333 #[inline]
336 pub fn pop(&mut self) -> Option<T> {
337 unsafe {
338 if let Some(slot) = self.used {
339 if let Some(mut next) = (*slot).next.as_mut() {
341 next.prev = ptr::null_mut();
342 self.used = Some(next);
343 }
344 self.length -= 1;
345 return std::mem::take(&mut (*slot).data);
347 }
348 }
349 None
350 }
351
352 #[inline]
355 pub fn remove(&mut self, index: usize) -> Option<T> {
356 let mut slot = &mut self.entries[index];
357 Persist::disassociate_entry(slot);
359 slot.prev = ptr::null_mut();
361 unsafe {
363 if let Some(first_free) = self.free {
364 if let Some(first_free) = first_free.as_mut() {
365 slot.next = first_free;
366 (*first_free).prev = slot;
367 }
368 }
369 }
370
371 self.length -= 1;
372 self.free = Some(&mut self.entries[index]);
373 std::mem::take(&mut self.entries[index].data)
375 }
376
377 #[inline]
378 pub fn iter(&self) -> Iter<T> {
379 if let Some(entry) = self.used {
380 return Iter {
381 entry,
382 n_entries: self.length,
383 phantom: PhantomData,
384 };
385 };
386
387 Iter {
388 entry: &self.entries[0],
389 n_entries: self.length,
390 phantom: PhantomData,
391 }
392 }
393
394 #[inline]
395 pub fn iter_mut(&mut self) -> IterMut<T> {
396 if let Some(entry) = self.used {
397 return IterMut {
398 entry,
399 n_entries: self.length,
400 phantom: PhantomData,
401 };
402 };
403 IterMut {
404 entry: &mut self.entries[0],
405 n_entries: self.length,
406 phantom: PhantomData,
407 }
408 }
409}
410
411#[derive(Debug)]
412pub struct Iter<'a, T> {
413 entry: *const Entry<T>,
414 n_entries: usize,
415 phantom: PhantomData<&'a T>,
416}
417
418impl<'a, T> Iterator for Iter<'a, T> {
419 type Item = &'a T;
420
421 #[inline]
422 fn next(&mut self) -> Option<&'a T> {
423 if self.n_entries == 0 {
424 return None;
425 }
426
427 unsafe {
428 let data: Option<&'a T> = (*self.entry).data.as_ref();
429 self.entry = (*self.entry).next;
430 self.n_entries -= 1;
431 data
432 }
433 }
434}
435
436#[derive(Debug)]
437pub struct IterMut<'a, T> {
438 entry: *mut Entry<T>,
439 n_entries: usize,
440 phantom: PhantomData<&'a mut T>,
441}
442
443impl<'a, T> Iterator for IterMut<'a, T> {
444 type Item = &'a mut T;
445
446 #[inline]
447 fn next(&mut self) -> Option<&'a mut T> {
448 if self.n_entries == 0 {
449 return None;
450 }
451
452 unsafe {
453 let data: Option<&'a mut T> = (*self.entry).data.as_mut();
454 self.entry = (*self.entry).next;
455 self.n_entries -= 1;
456 data
457 }
458 }
459}
460
461impl<T: Clone> From<&[T]> for Persist<T> {
463 fn from(s: &[T]) -> Persist<T> {
464 Persist::from(s)
465 }
466}
467
468impl<T: Clone> From<&mut [T]> for Persist<T> {
470 fn from(s: &mut [T]) -> Persist<T> {
471 Persist::from(s)
472 }
473}
474
475#[cfg(test)]
476mod tests {
477 use crate::{Entry, Persist};
478
479 #[test]
480 fn with_capacity() {
481 let p: Persist<u32> = Persist::with_capacity(10);
482 assert_eq!(p.entries.capacity(), 10);
483 }
484
485 #[test]
486 fn get() {
487 let mut p: Persist<u32> = Persist::with_capacity(10);
488
489 p.push(13);
490 p.push(14);
491 p.push(15);
492
493 let two = p.get(1).unwrap();
494 assert_eq!(*two, 14);
495 }
496
497 #[test]
498 fn get_mut() {
499 let mut p: Persist<u32> = Persist::with_capacity(10);
500
501 p.push(13);
502 p.push(14);
503 p.push(15);
504
505 {
506 let two = p.get_mut(1).unwrap();
507 *two *= 2;
508 }
509 let two = p.get(1).unwrap();
510 assert_eq!(*two, 28);
511 }
512
513 #[test]
514 fn index_validation() {
515 let mut p: Persist<u32> = Persist::with_capacity(10);
516
517 p.push(13);
518 p.push(14);
519
520 assert!(p.is_index_live(0));
521 assert!(p.is_index_live(1));
522 assert!(!p.is_index_live(3));
523 }
524
525 #[test]
539 fn clear() {
540 let _p: Persist<u32> = Persist::with_capacity(10);
541 }
542
543 #[test]
544 fn pop() {
545 let mut p: Persist<u32> = Persist::with_capacity(10);
546
547 p.push(13);
548 p.push(14);
549 p.push(15);
550
551 p.pop();
552 }
553
554 #[test]
555 fn push_to_full_then_pop_all() {
556 #[derive(Debug, PartialOrd, PartialEq)]
557 struct Heading {
558 x: u32,
559 }
560
561 let mut p: Persist<Heading> = Persist::with_capacity(50_000);
562
563 for i in 0..50_000 {
564 p.push(Heading { x: i });
565 }
566
567 for i in (0..50_000).rev() {
568 assert_eq!(p.pop().unwrap().x, i);
569 }
570 }
571
572 #[test]
573 fn remove() {
574 #[derive(Debug, PartialOrd, PartialEq)]
575 struct Heading {
576 x: u32,
577 }
578
579 let mut p: Persist<Heading> = Persist::with_capacity(50);
580
581 for i in 0..50 {
582 p.push(Heading { x: i });
583 }
584
585 let r = p.remove(10);
586 assert_eq!(r, Some(Heading { x: 10 }));
587
588 let r = p.remove(20);
589 assert_eq!(r, Some(Heading { x: 20 }));
590
591 let r = p.remove(30);
592 assert_eq!(r, Some(Heading { x: 30 }));
593
594 let r = p.remove(22);
595 assert_eq!(r, Some(Heading { x: 22 }));
596 }
597
598 #[test]
599 fn insert() {
600 let mut p: Persist<u32> = Persist::with_capacity(10);
601
602 p.push(13);
603 p.push(14);
604 p.push(15);
605
606 let previous = p.insert(0, 16).unwrap();
607 assert_eq!(previous, 13);
608 assert_eq!(p.get(0), Some(&16));
609
610 assert!(p.insert(5, 17).is_none());
611 assert_eq!(p.get(5), Some(&17));
612 }
613
614 #[test]
615 fn iter() {
616 #[derive(Debug)]
617 struct Heading {
618 x: usize,
619 }
620
621 dbg!(std::mem::size_of::<Heading>());
622 dbg!(std::mem::size_of::<Option<Heading>>());
623 dbg!(std::mem::size_of::<usize>());
624 dbg!(std::mem::size_of::<Entry<Heading>>());
625
626 let mut p: Persist<Heading> = Persist::with_capacity(10);
627
628 p.push(Heading { x: 13 });
629 p.push(Heading { x: 14 });
630 p.push(Heading { x: 15 });
631
632 let mut accum = 0;
633 for x in p.iter() {
634 accum += x.x;
635 }
636 assert_eq!(accum, 42);
637 }
638
639 #[test]
640 fn iter_mut() {
641 #[derive(Debug)]
642 struct Heading {
643 x: u32,
644 }
645
646 let mut p: Persist<Heading> = Persist::with_capacity(10);
647
648 p.push(Heading { x: 6 });
649 p.push(Heading { x: 6 });
650 p.push(Heading { x: 6 });
651 p.push(Heading { x: 6 });
652
653 for x in p.iter_mut() {
654 x.x += 1;
655 }
656
657 for x in p.iter() {
658 assert_eq!(x.x, 7);
659 }
660 }
661
662 #[test]
663 fn iter_over_removed() {
664 #[derive(Debug, PartialOrd, PartialEq)]
665 struct Heading {
666 x: u32,
667 }
668
669 let mut p: Persist<Heading> = Persist::with_capacity(50);
670
671 for i in 0..50 {
672 p.push(Heading { x: i });
673 }
674
675 let r = p.remove(10);
676 assert_eq!(r, Some(Heading { x: 10 }));
677
678 let r = p.remove(20);
679 assert_eq!(r, Some(Heading { x: 20 }));
680
681 let r = p.remove(30);
682 assert_eq!(r, Some(Heading { x: 30 }));
683
684 for head in p.iter() {
685 assert_ne!(head.x, 10);
686 assert_ne!(head.x, 20);
687 assert_ne!(head.x, 30);
688 }
689 }
690
691 #[test]
692 fn pst_remove_and_push() {
693 const LIMIT: usize = 100_000; struct Velocity(u32);
696
697 let mut persist = Persist::with_capacity(LIMIT);
698
699 for _ in 0..LIMIT {
700 persist.push(Velocity(1));
701 }
702
703 let mut accum = 0;
704 for x in persist.iter() {
705 accum += x.0;
706 }
707 assert_eq!(accum, LIMIT as u32);
708 }
709
710 #[test]
711 fn from_slice_reserve() {
712 let ar = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
713 let persist = Persist::from(&ar[..]);
714 assert_eq!(persist.entries.len(), 10);
716 }
717
718 #[test]
719 #[should_panic]
720 fn panic_out_of_bounds() {
721 let ar = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
722 let mut persist = Persist::from(&ar[..]);
723 persist.insert(10, 10);
724 }
725
726 #[test]
727 fn insert_at_end() {
728 let mut p: Persist<u32> = Persist::with_capacity(10);
729
730 p.insert(9, 15);
731
732 let x = p.get(9).unwrap();
733 assert_eq!(*x, 15);
734
735 let mut accum = 0;
736 for (i, v) in p.iter().enumerate() {
737 assert_eq!(i, 0);
738 assert_eq!(*v, 15);
739 accum += 1;
740 }
741 assert_eq!(accum, 1);
742
743 let mut accum = 0;
744 for (i, v) in p.iter_mut().enumerate() {
745 assert_eq!(i, 0);
746 assert_eq!(*v, 15);
747 accum += 1;
748 }
749 assert_eq!(accum, 1);
750 }
751}