1use crate::collections::vec::iter::SVecIter;
2use crate::encoding::{AsFixedSizeBytes, Buffer};
3use crate::mem::allocator::EMPTY_PTR;
4use crate::mem::s_slice::SSlice;
5use crate::mem::StablePtr;
6use crate::primitive::s_ref::SRef;
7use crate::primitive::s_ref_mut::SRefMut;
8use crate::primitive::StableType;
9use crate::{allocate, deallocate, reallocate, OutOfMemory};
10use std::cmp::Ordering;
11use std::fmt::{Debug, Formatter};
12use std::marker::PhantomData;
13
14#[doc(hidden)]
15pub mod iter;
16
17const DEFAULT_CAPACITY: usize = 4;
18
19pub struct SVec<T: StableType + AsFixedSizeBytes> {
31 ptr: u64,
32 len: usize,
33 cap: usize,
34 stable_drop_flag: bool,
35 _marker_t: PhantomData<T>,
36}
37
38impl<T: StableType + AsFixedSizeBytes> SVec<T> {
39 #[inline]
53 pub fn new() -> Self {
54 Self {
55 len: 0,
56 cap: DEFAULT_CAPACITY,
57 ptr: EMPTY_PTR,
58 stable_drop_flag: true,
59 _marker_t: PhantomData::default(),
60 }
61 }
62
63 #[inline]
79 pub fn new_with_capacity(capacity: usize) -> Result<Self, OutOfMemory> {
80 assert!(capacity <= Self::max_capacity());
81
82 Ok(Self {
83 len: 0,
84 cap: capacity,
85 ptr: unsafe { allocate((capacity * T::SIZE) as u64)?.as_ptr() },
86 stable_drop_flag: true,
87 _marker_t: PhantomData::default(),
88 })
89 }
90
91 #[inline]
93 pub fn capacity(&self) -> usize {
94 self.cap
95 }
96
97 #[inline]
99 pub fn len(&self) -> usize {
100 self.len
101 }
102
103 #[inline]
105 pub fn is_empty(&self) -> bool {
106 self.len == 0
107 }
108
109 #[inline]
111 pub const fn max_capacity() -> usize {
112 u32::MAX as usize / T::SIZE
113 }
114
115 #[inline]
120 pub fn push(&mut self, mut element: T) -> Result<(), T> {
121 if self.maybe_reallocate().is_ok() {
122 let elem_ptr = SSlice::_offset(self.ptr, (self.len * T::SIZE) as u64);
123 unsafe { crate::mem::write_fixed(elem_ptr, &mut element) };
124
125 self.len += 1;
126
127 Ok(())
128 } else {
129 Err(element)
130 }
131 }
132
133 #[inline]
137 pub fn pop(&mut self) -> Option<T> {
138 if self.is_empty() {
139 return None;
140 }
141
142 let elem_ptr = self.get_element_ptr(self.len - 1)?;
143 self.len -= 1;
144
145 Some(unsafe { crate::mem::read_fixed_for_move(elem_ptr) })
146 }
147
148 #[inline]
168 pub fn get(&self, idx: usize) -> Option<SRef<'_, T>> {
169 let ptr = self.get_element_ptr(idx)?;
170
171 unsafe { Some(SRef::new(ptr)) }
172 }
173
174 #[inline]
193 pub fn get_mut(&mut self, idx: usize) -> Option<SRefMut<'_, T>> {
194 let ptr = self.get_element_ptr(idx)?;
195
196 unsafe { Some(SRefMut::new(ptr)) }
197 }
198
199 pub fn replace(&mut self, idx: usize, mut element: T) -> T {
219 assert!(idx < self.len(), "Out of bounds");
220
221 let elem_ptr = SSlice::_offset(self.ptr, (idx * T::SIZE) as u64);
222
223 let prev_element = unsafe { crate::mem::read_fixed_for_move(elem_ptr) };
224 unsafe { crate::mem::write_fixed(elem_ptr, &mut element) };
225
226 prev_element
227 }
228
229 pub fn insert(&mut self, idx: usize, mut element: T) -> Result<(), T> {
237 if idx == self.len {
238 return self.push(element);
239 }
240
241 assert!(idx < self.len, "out of bounds");
242
243 if self.maybe_reallocate().is_ok() {
244 let elem_ptr = SSlice::_offset(self.ptr, (idx * T::SIZE) as u64);
245
246 let mut buf = vec![0u8; (self.len - idx) * T::SIZE];
248 unsafe { crate::mem::read_bytes(elem_ptr, &mut buf) };
249 unsafe { crate::mem::write_bytes(elem_ptr + T::SIZE as u64, &buf) };
250
251 unsafe { crate::mem::write_fixed(elem_ptr, &mut element) };
253
254 self.len += 1;
255
256 Ok(())
257 } else {
258 Err(element)
259 }
260 }
261
262 pub fn remove(&mut self, idx: usize) -> T {
267 assert!(idx < self.len, "out of bounds");
268
269 if idx == self.len - 1 {
270 return unsafe { self.pop().unwrap_unchecked() };
271 }
272
273 let elem_ptr = SSlice::_offset(self.ptr, (idx * T::SIZE) as u64);
274 let elem = unsafe { crate::mem::read_fixed_for_move(elem_ptr) };
275
276 let mut buf = vec![0u8; (self.len - idx - 1) * T::SIZE];
277 unsafe { crate::mem::read_bytes(elem_ptr + T::SIZE as u64, &mut buf) };
278 unsafe { crate::mem::write_bytes(elem_ptr, &buf) };
279
280 self.len -= 1;
281
282 elem
283 }
284
285 pub fn swap(&mut self, idx1: usize, idx2: usize) {
290 assert!(
291 idx1 < self.len() && idx2 < self.len() && idx1 != idx2,
292 "invalid idx"
293 );
294
295 let ptr1 = SSlice::_offset(self.ptr, (idx1 * T::SIZE) as u64);
296 let ptr2 = SSlice::_offset(self.ptr, (idx2 * T::SIZE) as u64);
297
298 let mut buf_1 = T::Buf::new(T::SIZE);
299 let mut buf_2 = T::Buf::new(T::SIZE);
300
301 unsafe { crate::mem::read_bytes(ptr1, buf_1._deref_mut()) };
302 unsafe { crate::mem::read_bytes(ptr2, buf_2._deref_mut()) };
303
304 unsafe { crate::mem::write_bytes(ptr2, buf_1._deref()) };
305 unsafe { crate::mem::write_bytes(ptr1, buf_2._deref()) };
306 }
307
308 #[inline]
312 pub fn clear(&mut self) {
313 while self.pop().is_some() {}
314 }
315
316 pub fn binary_search_by<FN>(&self, mut f: FN) -> Result<usize, usize>
337 where
338 FN: FnMut(&T) -> Ordering,
339 {
340 if self.is_empty() {
341 return Err(0);
342 }
343
344 let mut min = 0;
345 let mut max = self.len;
346 let mut mid = (max - min) / 2;
347
348 loop {
349 let elem_ptr = SSlice::_offset(self.ptr, (mid * T::SIZE) as u64);
350 let elem = unsafe { crate::mem::read_fixed_for_reference(elem_ptr) };
351
352 let res = f(&elem);
353
354 match res {
355 Ordering::Equal => return Ok(mid),
356 Ordering::Greater => {
357 max = mid;
358 let new_mid = (max - min) / 2 + min;
359
360 if new_mid == mid {
361 return Err(mid);
362 }
363
364 mid = new_mid;
365 continue;
366 }
367 Ordering::Less => {
368 min = mid;
369 let new_mid = (max - min) / 2 + min;
370
371 if new_mid == mid {
372 return Err(mid + 1);
373 }
374
375 mid = new_mid;
376 continue;
377 }
378 }
379 }
380 }
381
382 #[inline]
401 pub fn iter(&self) -> SVecIter<T> {
402 SVecIter::new(self)
403 }
404
405 pub fn debug_print(&self) {
409 print!("SVec[");
410 for i in 0..self.len {
411 let mut b = T::Buf::new(T::SIZE);
412 unsafe {
413 crate::mem::read_bytes(
414 SSlice::_offset(self.ptr, (i * T::SIZE) as u64),
415 b._deref_mut(),
416 )
417 };
418
419 print!("{:?}", b._deref());
420
421 if i < self.len - 1 {
422 print!(", ");
423 }
424 }
425
426 println!("]");
427 }
428
429 fn maybe_reallocate(&mut self) -> Result<(), OutOfMemory> {
430 if self.ptr == EMPTY_PTR {
431 self.ptr = unsafe { allocate((self.capacity() * T::SIZE) as u64)?.as_ptr() };
432 return Ok(());
433 }
434
435 if self.len() == self.capacity() {
436 self.cap = self.cap.checked_mul(2).unwrap();
437 assert!(self.cap <= Self::max_capacity());
438
439 let slice = unsafe { SSlice::from_ptr(self.ptr).unwrap() };
440
441 self.ptr = unsafe { reallocate(slice, (self.cap * T::SIZE) as u64)?.as_ptr() };
442 }
443
444 Ok(())
445 }
446
447 pub(crate) fn get_element_ptr(&self, idx: usize) -> Option<StablePtr> {
448 if idx < self.len() {
449 Some(SSlice::_offset(self.ptr, (idx * T::SIZE) as u64))
450 } else {
451 None
452 }
453 }
454}
455
456impl<T: StableType + AsFixedSizeBytes> Default for SVec<T> {
457 #[inline]
458 fn default() -> Self {
459 Self::new()
460 }
461}
462
463impl<T: StableType + AsFixedSizeBytes + Debug> Debug for SVec<T> {
464 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
465 f.write_str("[")?;
466 for (idx, item) in self.iter().enumerate() {
467 item.fmt(f)?;
468
469 if idx < self.len - 1 {
470 f.write_str(", ")?;
471 }
472 }
473 f.write_str("]")
474 }
475}
476
477impl<T: StableType + AsFixedSizeBytes> AsFixedSizeBytes for SVec<T> {
478 const SIZE: usize = u64::SIZE + usize::SIZE * 2;
479 type Buf = [u8; u64::SIZE + usize::SIZE * 2];
480
481 fn as_fixed_size_bytes(&self, buf: &mut [u8]) {
482 self.ptr.as_fixed_size_bytes(&mut buf[0..u64::SIZE]);
483 self.len
484 .as_fixed_size_bytes(&mut buf[u64::SIZE..(u64::SIZE + usize::SIZE)]);
485 self.cap.as_fixed_size_bytes(
486 &mut buf[(u64::SIZE + usize::SIZE)..(u64::SIZE + usize::SIZE * 2)],
487 );
488 }
489
490 fn from_fixed_size_bytes(arr: &[u8]) -> Self {
491 let ptr = u64::from_fixed_size_bytes(&arr[0..u64::SIZE]);
492 let len = usize::from_fixed_size_bytes(&arr[u64::SIZE..(u64::SIZE + usize::SIZE)]);
493 let cap = usize::from_fixed_size_bytes(
494 &arr[(u64::SIZE + usize::SIZE)..(u64::SIZE + usize::SIZE * 2)],
495 );
496
497 Self {
498 ptr,
499 len,
500 cap,
501 stable_drop_flag: false,
502 _marker_t: PhantomData::default(),
503 }
504 }
505}
506
507impl<T: StableType + AsFixedSizeBytes> StableType for SVec<T> {
508 #[inline]
509 unsafe fn stable_drop_flag_off(&mut self) {
510 self.stable_drop_flag = false;
511 }
512
513 #[inline]
514 unsafe fn stable_drop_flag_on(&mut self) {
515 self.stable_drop_flag = true;
516 }
517
518 #[inline]
519 fn should_stable_drop(&self) -> bool {
520 self.stable_drop_flag
521 }
522
523 unsafe fn stable_drop(&mut self) {
524 if self.ptr != EMPTY_PTR {
525 self.clear();
526
527 let slice = SSlice::from_ptr(self.ptr).unwrap();
528
529 deallocate(slice);
530 }
531 }
532}
533
534impl<T: StableType + AsFixedSizeBytes> Drop for SVec<T> {
535 fn drop(&mut self) {
536 if self.should_stable_drop() {
537 unsafe {
538 self.stable_drop();
539 }
540 }
541 }
542}
543
544#[cfg(test)]
545mod tests {
546 use crate::collections::vec::{SVec, DEFAULT_CAPACITY};
547 use crate::encoding::{AsFixedSizeBytes, Buffer};
548 use crate::primitive::s_box::SBox;
549 use crate::primitive::StableType;
550 use crate::utils::mem_context::stable;
551 use crate::utils::test::generate_random_string;
552 use crate::utils::DebuglessUnwrap;
553 use crate::{
554 _debug_print_allocator, _debug_validate_allocator, deinit_allocator, get_allocated_size,
555 init_allocator, retrieve_custom_data, stable_memory_init, stable_memory_post_upgrade,
556 stable_memory_pre_upgrade, store_custom_data,
557 };
558 use rand::rngs::ThreadRng;
559 use rand::seq::SliceRandom;
560 use rand::{thread_rng, Rng};
561 use std::fmt::Debug;
562 use std::ops::Deref;
563
564 #[derive(Copy, Clone, Debug)]
565 struct Test {
566 a: usize,
567 b: bool,
568 }
569
570 impl AsFixedSizeBytes for Test {
571 const SIZE: usize = usize::SIZE + bool::SIZE;
572 type Buf = [u8; Self::SIZE];
573
574 fn as_fixed_size_bytes(&self, buf: &mut [u8]) {
575 self.a.as_fixed_size_bytes(&mut buf[0..usize::SIZE]);
576 self.b
577 .as_fixed_size_bytes(&mut buf[usize::SIZE..(usize::SIZE + bool::SIZE)]);
578 }
579
580 fn from_fixed_size_bytes(arr: &[u8]) -> Self {
581 let a = usize::from_fixed_size_bytes(&arr[0..usize::SIZE]);
582 let b = bool::from_fixed_size_bytes(&arr[usize::SIZE..(usize::SIZE + bool::SIZE)]);
583
584 Self { a, b }
585 }
586 }
587
588 impl StableType for Test {}
589
590 #[test]
591 fn create_destroy_work_fine() {
592 stable::clear();
593 stable_memory_init();
594
595 {
596 let mut stable_vec = SVec::new();
597 assert_eq!(stable_vec.capacity(), DEFAULT_CAPACITY);
598 assert_eq!(stable_vec.len(), 0);
599
600 stable_vec.push(10).unwrap();
601 assert_eq!(stable_vec.capacity(), DEFAULT_CAPACITY);
602 assert_eq!(stable_vec.len(), 1);
603 }
604
605 _debug_validate_allocator();
606 assert_eq!(get_allocated_size(), 0);
607 }
608
609 #[test]
610 fn push_pop_work_fine() {
611 stable::clear();
612 stable_memory_init();
613
614 {
615 let mut stable_vec = SVec::new();
616 let count = 10usize;
617
618 for i in 0..count {
619 let it = Test { a: i, b: true };
620
621 stable_vec.push(it).unwrap();
622 }
623
624 assert_eq!(stable_vec.len(), count, "Invalid len after push");
625
626 for i in 0..count {
627 let it = Test { a: i, b: false };
628
629 stable_vec.replace(i, it);
630 }
631
632 stable_vec.debug_print();
633 assert_eq!(stable_vec.len(), count, "Invalid len after push");
634
635 for i in 0..count {
636 println!("{} {}", i, stable_vec.len());
637
638 let it = stable_vec.pop().unwrap();
639
640 assert_eq!(stable_vec.len(), count - i - 1);
641 assert_eq!(it.a, count - 1 - i);
642 assert!(!it.b);
643 }
644
645 assert_eq!(stable_vec.len(), 0, "Invalid len after pop");
646
647 for i in 0..count {
648 let it = Test { a: i, b: true };
649
650 stable_vec.push(it).unwrap();
651 }
652 }
653
654 _debug_validate_allocator();
655 assert_eq!(get_allocated_size(), 0);
656 }
657
658 #[test]
659 fn basic_flow_works_fine() {
660 stable::clear();
661 stable_memory_init();
662
663 {
664 let mut v = SVec::default();
665 assert!(v.get(100).is_none());
666
667 v.push(10).unwrap();
668 v.push(20).unwrap();
669
670 assert_eq!(*v.get(0).unwrap(), 10);
671 assert_eq!(*v.get(1).unwrap(), 20);
672 assert_eq!(v.replace(0, 11), 10);
673 }
674
675 _debug_validate_allocator();
676 assert_eq!(get_allocated_size(), 0);
677 }
678
679 #[test]
680 fn insert_works_fine() {
681 stable::clear();
682 stable_memory_init();
683
684 {
685 let mut array = SVec::default();
686 let mut check = Vec::default();
687
688 for i in 0..30 {
689 array.insert(0, 29 - i).unwrap();
690 check.insert(0, 29 - i);
691 }
692
693 for i in 60..100 {
694 array.insert(array.len(), i).unwrap();
695 check.insert(check.len(), i);
696 }
697
698 for i in 30..60 {
699 array.insert(30 + (i - 30), i).unwrap();
700 check.insert(30 + (i - 30), i);
701 }
702
703 for i in 0..100 {
704 assert_eq!(*array.get(i).unwrap(), i);
705 }
706
707 let mut actual = Vec::new();
708 while let Some(elem) = array.pop() {
709 actual.insert(0, elem);
710 }
711
712 assert_eq!(actual, check);
713 }
714
715 _debug_validate_allocator();
716 assert_eq!(get_allocated_size(), 0);
717 }
718
719 #[test]
720 fn binary_search_work_fine() {
721 stable::clear();
722 stable_memory_init();
723
724 {
725 let initial = vec![
727 3, 24, 46, 92, 2, 21, 34, 95, 82, 22, 88, 32, 59, 13, 73, 51, 12, 83, 28, 17, 9,
728 23, 5, 63, 62, 38, 20, 40, 25, 98, 30, 43, 57, 86, 42, 4, 99, 33, 11, 74, 96, 94,
729 47, 31, 37, 71, 80, 70, 14, 67, 93, 56, 27, 39, 58, 41, 29, 84, 8, 0, 45, 54, 7,
730 26, 97, 6, 81, 65, 79, 10, 91, 68, 36, 60, 76, 75, 15, 87, 49, 35, 78, 64, 69, 52,
731 50, 61, 48, 53, 44, 19, 55, 72, 90, 77, 89, 16, 85, 66, 18, 1,
732 ];
733
734 let mut array = SVec::<i32>::default();
735 let mut check = Vec::<i32>::new();
736
737 for i in 0..100 {
738 match check.binary_search_by(|it| it.cmp(&initial[i])) {
739 Err(idx) => check.insert(idx, initial[i]),
740 _ => unreachable!(),
741 }
742
743 match array.binary_search_by(|it| it.cmp(&initial[i])) {
744 Err(idx) => array.insert(idx, initial[i]).unwrap(),
745 _ => unreachable!(),
746 }
747
748 _debug_print_allocator();
749 }
750
751 let mut actual = Vec::new();
752 while let Some(elem) = array.pop() {
753 actual.insert(0, elem);
754 }
755
756 assert_eq!(actual, check);
757 }
758
759 _debug_validate_allocator();
760 assert_eq!(get_allocated_size(), 0);
761 }
762
763 #[test]
764 fn remove_works_fine() {
765 stable::clear();
766 stable_memory_init();
767
768 {
769 let initial = vec![
770 3, 24, 46, 92, 2, 21, 34, 95, 82, 22, 88, 32, 59, 13, 73, 51, 12, 83, 28, 17, 9,
771 23, 5, 63, 62, 38, 20, 40, 25, 98, 30, 43, 57, 86, 42, 4, 99, 33, 11, 74, 96, 94,
772 47, 31, 37, 71, 80, 70, 14, 67, 93, 56, 27, 39, 58, 41, 29, 84, 8, 0, 45, 54, 7,
773 26, 97, 6, 81, 65, 79, 10, 91, 68, 36, 60, 76, 75, 15, 87, 49, 35, 78, 64, 69, 52,
774 50, 61, 48, 53, 44, 19, 55, 72, 90, 77, 89, 16, 85, 66, 18, 1,
775 ];
776
777 let mut array = SVec::new();
778 for i in 0..initial.len() {
779 array.push(initial[i]);
780 }
781
782 for i in 0..initial.len() {
783 assert_eq!(array.remove(0), initial[i]);
784 }
785 }
786
787 _debug_validate_allocator();
788 assert_eq!(get_allocated_size(), 0);
789 }
790
791 #[test]
792 fn serialization_works_fine() {
793 stable::clear();
794 stable_memory_init();
795
796 {
797 let mut vec = SVec::<u32>::new_with_capacity(10).debugless_unwrap();
798 vec.push(1);
799 vec.push(2);
800 vec.push(3);
801
802 let mut buf = <SVec<u32> as AsFixedSizeBytes>::Buf::new(SVec::<u32>::SIZE);
803 vec.as_fixed_size_bytes(buf._deref_mut());
804 let mut vec1 = SVec::<u32>::from_fixed_size_bytes(buf._deref());
805 unsafe { vec1.stable_drop_flag_off() };
806
807 assert_eq!(vec.ptr, vec1.ptr);
808 assert_eq!(vec.len, vec1.len);
809 assert_eq!(vec.cap, vec1.cap);
810
811 let ptr = vec.ptr;
812 let len = vec.len;
813 let cap = vec.cap;
814
815 let mut buf = <SVec<u32> as AsFixedSizeBytes>::Buf::new(SVec::<u32>::SIZE);
816 vec.as_fixed_size_bytes(buf._deref_mut());
817
818 let mut vec1 = SVec::<u32>::from_fixed_size_bytes(buf._deref());
819 unsafe { vec1.stable_drop_flag_off() };
820
821 assert_eq!(ptr, vec1.ptr);
822 assert_eq!(len, vec1.len);
823 assert_eq!(cap, vec1.cap);
824 }
825
826 _debug_print_allocator();
827 _debug_validate_allocator();
828 assert_eq!(get_allocated_size(), 0);
829 }
830
831 #[test]
832 fn iter_works_fine() {
833 stable::clear();
834 stable_memory_init();
835
836 {
837 let mut vec = SVec::new();
838 for i in 0..100 {
839 vec.push(i);
840 }
841
842 let mut c = 0;
843 vec.debug_print();
844
845 for (idx, mut i) in vec.iter().enumerate() {
846 c += 1;
847
848 assert_eq!(idx as i32, *i);
849 }
850
851 assert_eq!(c, 100);
852 }
853
854 _debug_validate_allocator();
855 assert_eq!(get_allocated_size(), 0);
856 }
857
858 #[test]
859 fn random_works_fine() {
860 stable::clear();
861 stable_memory_init();
862
863 {
864 let mut svec = SVec::new();
865
866 let mut rng = thread_rng();
867 let iterations = 10_000;
868
869 let mut example = Vec::new();
870 for i in 0..iterations {
871 example.push(i);
872 }
873 example.shuffle(&mut rng);
874
875 for i in 0..iterations {
876 svec.push(example[i]);
877 }
878
879 for i in 0..iterations {
880 svec.insert(rng.gen_range(0..svec.len()), example[i]);
881 }
882
883 for _ in 0..iterations {
884 svec.pop().unwrap();
885 }
886
887 for i in 0..iterations {
888 if svec.len() == 1 {
889 svec.remove(0);
890 } else {
891 let range = rng.gen_range(0..(svec.len() - 1));
892 svec.remove(range);
893 }
894 }
895
896 assert!(svec.is_empty());
897 }
898
899 _debug_validate_allocator();
900 assert_eq!(get_allocated_size(), 0);
901 }
902
903 #[test]
904 fn sboxes_work_fine() {
905 stable::clear();
906 stable_memory_init();
907
908 {
909 let mut vec = SVec::new();
910
911 for _ in 0..100 {
912 let b = SBox::new(10).unwrap();
913
914 vec.push(b);
915 }
916
917 vec.debug_print();
918 }
919
920 _debug_validate_allocator();
921 assert_eq!(get_allocated_size(), 0);
922 }
923
924 #[derive(Debug)]
925 enum Action {
926 Push(usize),
927 Pop(usize),
928 Insert(usize, usize),
929 Remove(usize, usize),
930 Swap(usize, usize, usize),
931 Replace(usize, usize),
932 CanisterUpgrade,
933 GetMut(usize, usize),
934 Clear(usize),
935 }
936
937 struct Fuzzer {
938 vec: Option<SVec<SVec<SBox<String>>>>,
939 example: Vec<Vec<String>>,
940 rng: ThreadRng,
941 log: Vec<Action>,
942 }
943
944 impl Fuzzer {
945 fn new() -> Self {
946 let mut svec = SVec::default();
947 let mut vec = Vec::default();
948
949 for i in 0..10 {
950 svec.push(SVec::default());
951 vec.push(Vec::default());
952 }
953
954 Self {
955 vec: Some(svec),
956 example: vec,
957 rng: thread_rng(),
958 log: Vec::default(),
959 }
960 }
961
962 fn vec(&mut self) -> &mut SVec<SVec<SBox<String>>> {
963 self.vec.as_mut().unwrap()
964 }
965
966 fn next(&mut self) {
967 let action = self.rng.gen_range(0..1100);
968
969 match action {
970 0..=250 => {
972 let str = generate_random_string(&mut self.rng);
973
974 if let Ok(data) = SBox::new(str.clone()) {
975 let outer_idx = self.rng.gen_range(0..10);
976
977 if self.vec().get_mut(outer_idx).unwrap().push(data).is_err() {
978 return;
979 };
980
981 self.example.get_mut(outer_idx).unwrap().push(str.clone());
982
983 self.log.push(Action::Push(outer_idx));
984 }
985 }
986 251..=500 => {
988 let str = generate_random_string(&mut self.rng);
989
990 if let Ok(data) = SBox::new(str.clone()) {
991 let outer_idx = self.rng.gen_range(0..10);
992
993 let len = self.vec().get(outer_idx).unwrap().len();
994 let idx = if len == 0 {
995 0
996 } else {
997 self.rng.gen_range(0..len + 1)
998 };
999
1000 if self
1001 .vec()
1002 .get_mut(outer_idx)
1003 .unwrap()
1004 .insert(idx, data)
1005 .is_err()
1006 {
1007 return;
1008 }
1009
1010 self.example
1011 .get_mut(outer_idx)
1012 .unwrap()
1013 .insert(idx, str.clone());
1014
1015 self.log.push(Action::Insert(outer_idx, idx));
1016 }
1017 }
1018 501..=600 => {
1020 let outer_idx = self.rng.gen_range(0..10);
1021
1022 self.vec().get_mut(outer_idx).unwrap().pop();
1023 self.example.get_mut(outer_idx).unwrap().pop();
1024
1025 self.log.push(Action::Pop(outer_idx));
1026 }
1027 601..=700 => {
1029 let outer_idx = self.rng.gen_range(0..10);
1030
1031 let len = self.vec().get(outer_idx).unwrap().len();
1032
1033 if len == 0 {
1034 return self.next();
1035 }
1036
1037 let idx = if len == 1 {
1038 0
1039 } else {
1040 self.rng.gen_range(0..len)
1041 };
1042
1043 self.vec().get_mut(outer_idx).unwrap().remove(idx);
1044 self.example.get_mut(outer_idx).unwrap().remove(idx);
1045
1046 self.log.push(Action::Remove(outer_idx, idx));
1047 }
1048 701..=800 => {
1050 let outer_idx = self.rng.gen_range(0..10);
1051
1052 let len = self.vec().get(outer_idx).unwrap().len();
1053
1054 if len < 2 {
1055 return self.next();
1056 }
1057
1058 let mut idx1 = self.rng.gen_range(0..len);
1059 let mut idx2 = self.rng.gen_range(0..len);
1060
1061 if idx1 == idx2 {
1062 if idx2 < len - 1 {
1063 idx2 += 1;
1064 } else {
1065 idx2 -= 1;
1066 }
1067 }
1068
1069 self.vec().get_mut(outer_idx).unwrap().swap(idx1, idx2);
1070 self.example.get_mut(outer_idx).unwrap().swap(idx1, idx2);
1071
1072 self.log.push(Action::Swap(outer_idx, idx1, idx2));
1073 }
1074 801..=900 => {
1076 let outer_idx = self.rng.gen_range(0..10);
1077
1078 let len = self.vec().get(outer_idx).unwrap().len();
1079
1080 if len == 0 {
1081 return self.next();
1082 }
1083
1084 let idx = self.rng.gen_range(0..len);
1085 let str = generate_random_string(&mut self.rng);
1086
1087 if let Ok(data) = SBox::new(str.clone()) {
1088 self.vec().get_mut(outer_idx).unwrap().replace(idx, data);
1089
1090 std::mem::replace(
1091 self.example
1092 .get_mut(outer_idx)
1093 .unwrap()
1094 .get_mut(idx)
1095 .unwrap(),
1096 str.clone(),
1097 );
1098
1099 self.log.push(Action::Replace(outer_idx, idx));
1100 }
1101 }
1102 901..=1000 => {
1104 let outer_idx = self.rng.gen_range(0..10);
1105
1106 let len = self.vec().get_mut(outer_idx).unwrap().len();
1107
1108 if len == 0 {
1109 return self.next();
1110 }
1111
1112 let idx = self.rng.gen_range(0..len);
1113 let str = generate_random_string(&mut self.rng);
1114
1115 if self
1116 .vec()
1117 .get_mut(outer_idx)
1118 .unwrap()
1119 .get_mut(idx)
1120 .unwrap()
1121 .with(|s: &mut String| {
1122 *s = str.clone();
1123 })
1124 .is_err()
1125 {
1126 return;
1127 }
1128
1129 *self
1130 .example
1131 .get_mut(outer_idx)
1132 .unwrap()
1133 .get_mut(idx)
1134 .unwrap() = str;
1135
1136 self.log.push(Action::GetMut(outer_idx, idx));
1137 }
1138 1001..=1010 => {
1140 let outer_idx = self.rng.gen_range(0..10);
1141
1142 self.vec().get_mut(outer_idx).unwrap().clear();
1143 self.example.get_mut(outer_idx).unwrap().clear();
1144
1145 self.log.push(Action::Clear(outer_idx));
1146 }
1147 _ => match SBox::new(self.vec.take().unwrap()) {
1149 Ok(data) => {
1150 store_custom_data(1, data);
1151
1152 if stable_memory_pre_upgrade().is_ok() {
1153 stable_memory_post_upgrade();
1154 }
1155
1156 self.vec = retrieve_custom_data::<SVec<SVec<SBox<String>>>>(1)
1157 .map(|it| it.into_inner());
1158 self.log.push(Action::CanisterUpgrade);
1159 }
1160 Err(vec) => {
1161 self.vec = Some(vec);
1162 }
1163 },
1164 }
1165
1166 _debug_validate_allocator();
1167 assert_eq!(self.vec().len(), self.example.len());
1168
1169 for i in 0..self.vec().len() {
1170 let svec = self.vec.as_ref().unwrap().get(i).unwrap();
1171 let example = self.example.get(i).unwrap();
1172
1173 assert_eq!(svec.len(), example.len());
1174
1175 for j in 0..svec.len() {
1176 assert_eq!(
1177 svec.get(j).unwrap().clone(),
1178 example.get(j).unwrap().clone()
1179 );
1180 }
1181 }
1182 }
1183 }
1184
1185 #[test]
1186 fn fuzzer_works_fine() {
1187 stable::clear();
1188 init_allocator(0);
1189
1190 {
1191 let mut fuzzer = Fuzzer::new();
1192
1193 for _ in 0..10_000 {
1194 fuzzer.next();
1195 }
1196 }
1197
1198 assert_eq!(get_allocated_size(), 0);
1199 }
1200
1201 #[test]
1202 fn fuzzer_works_fine_limited_memory() {
1203 stable::clear();
1204 init_allocator(10);
1205
1206 {
1207 let mut fuzzer = Fuzzer::new();
1208
1209 for _ in 0..10_000 {
1210 fuzzer.next();
1211 }
1212 }
1213
1214 assert_eq!(get_allocated_size(), 0);
1215 }
1216}