1use std::{any::Any, sync::Arc};
7
8#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
12#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
13pub struct TypeId(u64);
14
15impl TypeId {
16 #[inline]
17 pub fn of<T: Any + 'static>() -> Self {
18 std::any::TypeId::of::<T>().into()
19 }
20
21 #[inline(always)]
22 pub(crate) fn value(&self) -> u64 {
23 self.0
24 }
25}
26
27impl From<std::any::TypeId> for TypeId {
28 #[inline]
29 fn from(id: std::any::TypeId) -> Self {
30 Self(epaint::util::hash(id))
31 }
32}
33
34impl nohash_hasher::IsEnabled for TypeId {}
35
36#[cfg(feature = "persistence")]
39pub trait SerializableAny:
40 'static + Any + Clone + serde::Serialize + for<'a> serde::Deserialize<'a> + Send + Sync
41{
42}
43
44#[cfg(feature = "persistence")]
45impl<T> SerializableAny for T where
46 T: 'static + Any + Clone + serde::Serialize + for<'a> serde::Deserialize<'a> + Send + Sync
47{
48}
49
50#[cfg(not(feature = "persistence"))]
51pub trait SerializableAny: 'static + Any + Clone + for<'a> Send + Sync {}
52
53#[cfg(not(feature = "persistence"))]
54impl<T> SerializableAny for T where T: 'static + Any + Clone + for<'a> Send + Sync {}
55
56#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
59#[derive(Clone, Debug)]
60struct SerializedElement {
61 type_id: TypeId,
63
64 ron: Arc<str>,
66
67 generation: usize,
73}
74
75#[cfg(feature = "persistence")]
76type Serializer = fn(&Box<dyn Any + 'static + Send + Sync>) -> Option<String>;
77
78enum Element {
79 Value {
81 value: Box<dyn Any + 'static + Send + Sync>,
83
84 clone_fn: fn(&Box<dyn Any + 'static + Send + Sync>) -> Box<dyn Any + 'static + Send + Sync>,
86
87 #[cfg(feature = "persistence")]
90 serialize_fn: Option<Serializer>,
91 },
92
93 Serialized(SerializedElement),
95}
96
97impl Clone for Element {
98 fn clone(&self) -> Self {
99 match &self {
100 Self::Value {
101 value,
102 clone_fn,
103 #[cfg(feature = "persistence")]
104 serialize_fn,
105 } => Self::Value {
106 value: clone_fn(value),
107 clone_fn: *clone_fn,
108 #[cfg(feature = "persistence")]
109 serialize_fn: *serialize_fn,
110 },
111
112 Self::Serialized(element) => Self::Serialized(element.clone()),
113 }
114 }
115}
116
117impl std::fmt::Debug for Element {
118 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
119 match &self {
120 Self::Value { value, .. } => f
121 .debug_struct("Element::Value")
122 .field("type_id", &(**value).type_id())
123 .finish_non_exhaustive(),
124 Self::Serialized(SerializedElement {
125 type_id,
126 ron,
127 generation,
128 }) => f
129 .debug_struct("Element::Serialized")
130 .field("type_id", type_id)
131 .field("ron", ron)
132 .field("generation", generation)
133 .finish(),
134 }
135 }
136}
137
138impl Element {
139 #[inline]
141 pub(crate) fn new_temp<T: 'static + Any + Clone + Send + Sync>(t: T) -> Self {
142 Self::Value {
143 value: Box::new(t),
144 clone_fn: |x| {
145 let x = x.downcast_ref::<T>().unwrap(); Box::new(x.clone())
147 },
148 #[cfg(feature = "persistence")]
149 serialize_fn: None,
150 }
151 }
152
153 #[inline]
155 pub(crate) fn new_persisted<T: SerializableAny>(t: T) -> Self {
156 Self::Value {
157 value: Box::new(t),
158 clone_fn: |x| {
159 let x = x.downcast_ref::<T>().unwrap(); Box::new(x.clone())
161 },
162 #[cfg(feature = "persistence")]
163 serialize_fn: Some(|x| {
164 let x = x.downcast_ref::<T>().unwrap(); ron::to_string(x).ok()
166 }),
167 }
168 }
169
170 #[inline]
172 pub(crate) fn type_id(&self) -> TypeId {
173 match self {
174 Self::Value { value, .. } => (**value).type_id().into(),
175 Self::Serialized(SerializedElement { type_id, .. }) => *type_id,
176 }
177 }
178
179 #[inline]
180 pub(crate) fn get_temp<T: 'static>(&self) -> Option<&T> {
181 match self {
182 Self::Value { value, .. } => value.downcast_ref(),
183 Self::Serialized(_) => None,
184 }
185 }
186
187 #[inline]
188 pub(crate) fn get_mut_temp<T: 'static>(&mut self) -> Option<&mut T> {
189 match self {
190 Self::Value { value, .. } => value.downcast_mut(),
191 Self::Serialized(_) => None,
192 }
193 }
194
195 #[inline]
196 pub(crate) fn get_temp_mut_or_insert_with<T: 'static + Any + Clone + Send + Sync>(
197 &mut self,
198 insert_with: impl FnOnce() -> T,
199 ) -> &mut T {
200 match self {
201 Self::Value { value, .. } => {
202 if !value.is::<T>() {
203 *self = Self::new_temp(insert_with());
204 }
205 }
206 Self::Serialized(_) => {
207 *self = Self::new_temp(insert_with());
208 }
209 }
210
211 match self {
212 Self::Value { value, .. } => value.downcast_mut().unwrap(), Self::Serialized(_) => unreachable!(),
214 }
215 }
216
217 #[inline]
218 pub(crate) fn get_persisted_mut_or_insert_with<T: SerializableAny>(
219 &mut self,
220 insert_with: impl FnOnce() -> T,
221 ) -> &mut T {
222 match self {
223 Self::Value { value, .. } => {
224 if !value.is::<T>() {
225 *self = Self::new_persisted(insert_with());
226 }
227 }
228
229 #[cfg(feature = "persistence")]
230 Self::Serialized(SerializedElement { ron, .. }) => {
231 *self = Self::new_persisted(from_ron_str::<T>(ron).unwrap_or_else(insert_with));
232 }
233
234 #[cfg(not(feature = "persistence"))]
235 Self::Serialized(_) => {
236 *self = Self::new_persisted(insert_with());
237 }
238 }
239
240 match self {
241 Self::Value { value, .. } => value.downcast_mut().unwrap(), Self::Serialized(_) => unreachable!(),
243 }
244 }
245
246 pub(crate) fn get_mut_persisted<T: SerializableAny>(&mut self) -> Option<&mut T> {
247 match self {
248 Self::Value { value, .. } => value.downcast_mut(),
249
250 #[cfg(feature = "persistence")]
251 Self::Serialized(SerializedElement { ron, .. }) => {
252 *self = Self::new_persisted(from_ron_str::<T>(ron)?);
253
254 match self {
255 Self::Value { value, .. } => value.downcast_mut(),
256 Self::Serialized(_) => unreachable!(),
257 }
258 }
259
260 #[cfg(not(feature = "persistence"))]
261 Self::Serialized(_) => None,
262 }
263 }
264
265 #[cfg(feature = "persistence")]
266 fn to_serialize(&self) -> Option<SerializedElement> {
267 match self {
268 Self::Value {
269 value,
270 serialize_fn,
271 ..
272 } => {
273 if let Some(serialize_fn) = serialize_fn {
274 let ron = serialize_fn(value)?;
275 Some(SerializedElement {
276 type_id: (**value).type_id().into(),
277 ron: ron.into(),
278 generation: 1,
279 })
280 } else {
281 None
282 }
283 }
284 Self::Serialized(element) => Some(element.clone()),
285 }
286 }
287}
288
289#[cfg(feature = "persistence")]
290fn from_ron_str<T: serde::de::DeserializeOwned>(ron: &str) -> Option<T> {
291 match ron::from_str::<T>(ron) {
292 Ok(value) => Some(value),
293 Err(_err) => {
294 #[cfg(feature = "log")]
295 log::warn!(
296 "egui: Failed to deserialize {} from memory: {}, ron error: {:?}",
297 std::any::type_name::<T>(),
298 _err,
299 ron
300 );
301 None
302 }
303 }
304}
305
306use crate::Id;
309
310#[derive(Clone, Debug)]
350pub struct IdTypeMap {
352 map: nohash_hasher::IntMap<u64, Element>,
353
354 max_bytes_per_type: usize,
355}
356
357impl Default for IdTypeMap {
358 fn default() -> Self {
359 Self {
360 map: Default::default(),
361 max_bytes_per_type: 256 * 1024,
362 }
363 }
364}
365
366impl IdTypeMap {
367 #[inline]
369 pub fn insert_temp<T: 'static + Any + Clone + Send + Sync>(&mut self, id: Id, value: T) {
370 let hash = hash(TypeId::of::<T>(), id);
371 self.map.insert(hash, Element::new_temp(value));
372 }
373
374 #[inline]
376 pub fn insert_persisted<T: SerializableAny>(&mut self, id: Id, value: T) {
377 let hash = hash(TypeId::of::<T>(), id);
378 self.map.insert(hash, Element::new_persisted(value));
379 }
380
381 #[inline]
385 pub fn get_temp<T: 'static + Clone>(&self, id: Id) -> Option<T> {
386 let hash = hash(TypeId::of::<T>(), id);
387 self.map.get(&hash).and_then(|x| x.get_temp()).cloned()
388 }
389
390 #[inline]
397 pub fn get_persisted<T: SerializableAny>(&mut self, id: Id) -> Option<T> {
398 let hash = hash(TypeId::of::<T>(), id);
399 self.map
400 .get_mut(&hash)
401 .and_then(|x| x.get_mut_persisted())
402 .cloned()
403 }
404
405 #[inline]
406 pub fn get_temp_mut_or<T: 'static + Any + Clone + Send + Sync>(
407 &mut self,
408 id: Id,
409 or_insert: T,
410 ) -> &mut T {
411 self.get_temp_mut_or_insert_with(id, || or_insert)
412 }
413
414 #[inline]
415 pub fn get_persisted_mut_or<T: SerializableAny>(&mut self, id: Id, or_insert: T) -> &mut T {
416 self.get_persisted_mut_or_insert_with(id, || or_insert)
417 }
418
419 #[inline]
420 pub fn get_temp_mut_or_default<T: 'static + Any + Clone + Send + Sync + Default>(
421 &mut self,
422 id: Id,
423 ) -> &mut T {
424 self.get_temp_mut_or_insert_with(id, Default::default)
425 }
426
427 #[inline]
428 pub fn get_persisted_mut_or_default<T: SerializableAny + Default>(&mut self, id: Id) -> &mut T {
429 self.get_persisted_mut_or_insert_with(id, Default::default)
430 }
431
432 pub fn get_temp_mut_or_insert_with<T: 'static + Any + Clone + Send + Sync>(
433 &mut self,
434 id: Id,
435 insert_with: impl FnOnce() -> T,
436 ) -> &mut T {
437 let hash = hash(TypeId::of::<T>(), id);
438 use std::collections::hash_map::Entry;
439 match self.map.entry(hash) {
440 Entry::Vacant(vacant) => vacant
441 .insert(Element::new_temp(insert_with()))
442 .get_mut_temp()
443 .unwrap(), Entry::Occupied(occupied) => {
445 occupied.into_mut().get_temp_mut_or_insert_with(insert_with)
446 }
447 }
448 }
449
450 pub fn get_persisted_mut_or_insert_with<T: SerializableAny>(
451 &mut self,
452 id: Id,
453 insert_with: impl FnOnce() -> T,
454 ) -> &mut T {
455 let hash = hash(TypeId::of::<T>(), id);
456 use std::collections::hash_map::Entry;
457 match self.map.entry(hash) {
458 Entry::Vacant(vacant) => vacant
459 .insert(Element::new_persisted(insert_with()))
460 .get_mut_persisted()
461 .unwrap(), Entry::Occupied(occupied) => occupied
463 .into_mut()
464 .get_persisted_mut_or_insert_with(insert_with),
465 }
466 }
467
468 #[cfg(feature = "persistence")]
470 #[allow(unused)]
471 fn get_generation<T: SerializableAny>(&self, id: Id) -> Option<usize> {
472 let element = self.map.get(&hash(TypeId::of::<T>(), id))?;
473 match element {
474 Element::Value { .. } => Some(0),
475 Element::Serialized(SerializedElement { generation, .. }) => Some(*generation),
476 }
477 }
478
479 #[inline]
481 pub fn remove<T: 'static>(&mut self, id: Id) {
482 let hash = hash(TypeId::of::<T>(), id);
483 self.map.remove(&hash);
484 }
485
486 #[inline]
488 pub fn remove_temp<T: 'static + Default>(&mut self, id: Id) -> Option<T> {
489 let hash = hash(TypeId::of::<T>(), id);
490 let mut element = self.map.remove(&hash)?;
491 Some(std::mem::take(element.get_mut_temp()?))
492 }
493
494 pub fn remove_by_type<T: 'static>(&mut self) {
496 let key = TypeId::of::<T>();
497 self.map.retain(|_, e| {
498 let e: &Element = e;
499 e.type_id() != key
500 });
501 }
502
503 #[inline]
504 pub fn clear(&mut self) {
505 self.map.clear();
506 }
507
508 #[inline]
509 pub fn is_empty(&self) -> bool {
510 self.map.is_empty()
511 }
512
513 #[inline]
514 pub fn len(&self) -> usize {
515 self.map.len()
516 }
517
518 #[inline]
520 pub fn count_serialized(&self) -> usize {
521 self.map
522 .values()
523 .filter(|e| matches!(e, Element::Serialized(_)))
524 .count()
525 }
526
527 pub fn count<T: 'static>(&self) -> usize {
529 let key = TypeId::of::<T>();
530 self.map
531 .iter()
532 .filter(|(_, e)| {
533 let e: &Element = e;
534 e.type_id() == key
535 })
536 .count()
537 }
538
539 pub fn max_bytes_per_type(&self) -> usize {
553 self.max_bytes_per_type
554 }
555
556 pub fn set_max_bytes_per_type(&mut self, max_bytes_per_type: usize) {
558 self.max_bytes_per_type = max_bytes_per_type;
559 }
560}
561
562#[inline(always)]
563fn hash(type_id: TypeId, id: Id) -> u64 {
564 type_id.value() ^ id.value()
565}
566
567#[cfg(feature = "persistence")]
571#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
572struct PersistedMap(Vec<(u64, SerializedElement)>);
573
574#[cfg(feature = "persistence")]
575impl PersistedMap {
576 fn from_map(map: &IdTypeMap) -> Self {
577 profiling::function_scope!();
578
579 use std::collections::BTreeMap;
580
581 let mut types_map: nohash_hasher::IntMap<TypeId, TypeStats> = Default::default();
582 #[derive(Default)]
583 struct TypeStats {
584 num_bytes: usize,
585 generations: BTreeMap<usize, GenerationStats>,
586 }
587 #[derive(Default)]
588 struct GenerationStats {
589 num_bytes: usize,
590 elements: Vec<(u64, SerializedElement)>,
591 }
592
593 let max_bytes_per_type = map.max_bytes_per_type;
594
595 {
596 profiling::scope!("gather");
597 for (hash, element) in &map.map {
598 if let Some(element) = element.to_serialize() {
599 let stats = types_map.entry(element.type_id).or_default();
600 stats.num_bytes += element.ron.len();
601 let generation_stats = stats.generations.entry(element.generation).or_default();
602 generation_stats.num_bytes += element.ron.len();
603 generation_stats.elements.push((*hash, element));
604 } else {
605 }
607 }
608 }
609
610 let mut persisted = vec![];
611
612 {
613 profiling::scope!("gc");
614 for stats in types_map.values() {
615 let mut bytes_written = 0;
616
617 for generation in stats.generations.values() {
620 if bytes_written == 0
621 || bytes_written + generation.num_bytes <= max_bytes_per_type
622 {
623 persisted.append(&mut generation.elements.clone());
624 bytes_written += generation.num_bytes;
625 } else {
626 break;
628 }
629 }
630 }
631 }
632
633 Self(persisted)
634 }
635
636 fn into_map(self) -> IdTypeMap {
637 profiling::function_scope!();
638 let map = self
639 .0
640 .into_iter()
641 .map(
642 |(
643 hash,
644 SerializedElement {
645 type_id,
646 ron,
647 generation,
648 },
649 )| {
650 (
651 hash,
652 Element::Serialized(SerializedElement {
653 type_id,
654 ron,
655 generation: generation + 1, }),
657 )
658 },
659 )
660 .collect();
661 IdTypeMap {
662 map,
663 ..Default::default()
664 }
665 }
666}
667
668#[cfg(feature = "persistence")]
669impl serde::Serialize for IdTypeMap {
670 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
671 where
672 S: serde::Serializer,
673 {
674 profiling::scope!("IdTypeMap::serialize");
675 PersistedMap::from_map(self).serialize(serializer)
676 }
677}
678
679#[cfg(feature = "persistence")]
680impl<'de> serde::Deserialize<'de> for IdTypeMap {
681 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
682 where
683 D: serde::Deserializer<'de>,
684 {
685 profiling::scope!("IdTypeMap::deserialize");
686 <PersistedMap>::deserialize(deserializer).map(PersistedMap::into_map)
687 }
688}
689
690#[test]
693fn test_two_id_two_type() {
694 let a = Id::new("a");
695 let b = Id::new("b");
696
697 let mut map: IdTypeMap = Default::default();
698 map.insert_persisted(a, 13.37);
699 map.insert_temp(b, 42);
700 assert_eq!(map.get_persisted::<f64>(a), Some(13.37));
701 assert_eq!(map.get_persisted::<i32>(b), Some(42));
702 assert_eq!(map.get_temp::<f64>(a), Some(13.37));
703 assert_eq!(map.get_temp::<i32>(b), Some(42));
704}
705
706#[test]
707fn test_two_id_x_two_types() {
708 #![allow(clippy::approx_constant)]
709
710 let a = Id::new("a");
711 let b = Id::new("b");
712 let mut map: IdTypeMap = Default::default();
713
714 map.insert_persisted(a, 3.14);
716 map.insert_temp(a, 42);
717
718 map.insert_persisted(b, 13.37);
720 map.insert_temp(b, "Hello World".to_owned());
721
722 assert_eq!(map.get_temp::<f64>(a), Some(3.14));
724 assert_eq!(map.get_temp::<i32>(a), Some(42));
725 assert_eq!(map.get_temp::<f64>(b), Some(13.37));
726 assert_eq!(map.get_temp::<String>(b), Some("Hello World".to_owned()));
727
728 assert_eq!(map.get_persisted::<f64>(a), Some(3.14));
730 assert_eq!(map.get_persisted::<i32>(a), Some(42));
731 assert_eq!(map.get_persisted::<f64>(b), Some(13.37));
732 assert_eq!(map.get_temp::<String>(b), Some("Hello World".to_owned()));
733}
734
735#[test]
736fn test_one_id_two_types() {
737 let id = Id::new("a");
738
739 let mut map: IdTypeMap = Default::default();
740 map.insert_persisted(id, 13.37);
741 map.insert_temp(id, 42);
742
743 assert_eq!(map.get_temp::<f64>(id), Some(13.37));
744 assert_eq!(map.get_persisted::<f64>(id), Some(13.37));
745 assert_eq!(map.get_temp::<i32>(id), Some(42));
746
747 map.remove::<i32>(id);
752 assert_eq!(map.get_temp::<i32>(id), None);
753
754 assert_eq!(map.get_temp::<f64>(id), Some(13.37));
756 assert_eq!(map.get_persisted::<f64>(id), Some(13.37));
757
758 map.remove::<f64>(id);
760 assert_eq!(map.get_temp::<f64>(id), None);
761 assert_eq!(map.get_persisted::<f64>(id), None);
762}
763
764#[test]
765fn test_mix() {
766 #[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
767 #[derive(Clone, Debug, PartialEq)]
768 struct Foo(i32);
769
770 #[derive(Clone, Debug, PartialEq)]
771 struct Bar(f32);
772
773 let id = Id::new("a");
774
775 let mut map: IdTypeMap = Default::default();
776 map.insert_persisted(id, Foo(555));
777 map.insert_temp(id, Bar(1.0));
778
779 assert_eq!(map.get_temp::<Foo>(id), Some(Foo(555)));
780 assert_eq!(map.get_persisted::<Foo>(id), Some(Foo(555)));
781 assert_eq!(map.get_temp::<Bar>(id), Some(Bar(1.0)));
782
783 map.remove::<Bar>(id);
788 assert_eq!(map.get_temp::<Bar>(id), None);
789
790 assert_eq!(map.get_temp::<Foo>(id), Some(Foo(555)));
792 assert_eq!(map.get_persisted::<Foo>(id), Some(Foo(555)));
793
794 map.remove::<Foo>(id);
796 assert_eq!(map.get_temp::<Foo>(id), None);
797 assert_eq!(map.get_persisted::<Foo>(id), None);
798}
799
800#[cfg(feature = "persistence")]
801#[test]
802fn test_mix_serialize() {
803 use serde::{Deserialize, Serialize};
804
805 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
806 struct Serializable(i32);
807
808 #[derive(Clone, Debug, PartialEq)]
809 struct NonSerializable(f32);
810
811 let id = Id::new("a");
812
813 let mut map: IdTypeMap = Default::default();
814 map.insert_persisted(id, Serializable(555));
815 map.insert_temp(id, NonSerializable(1.0));
816
817 assert_eq!(map.get_temp::<Serializable>(id), Some(Serializable(555)));
818 assert_eq!(
819 map.get_persisted::<Serializable>(id),
820 Some(Serializable(555))
821 );
822 assert_eq!(
823 map.get_temp::<NonSerializable>(id),
824 Some(NonSerializable(1.0))
825 );
826
827 let serialized = ron::to_string(&map).unwrap();
830
831 map.remove::<NonSerializable>(id);
836 assert_eq!(map.get_temp::<NonSerializable>(id), None);
837
838 assert_eq!(map.get_temp::<Serializable>(id), Some(Serializable(555)));
840 assert_eq!(
841 map.get_persisted::<Serializable>(id),
842 Some(Serializable(555))
843 );
844
845 map.remove::<Serializable>(id);
847 assert_eq!(map.get_temp::<Serializable>(id), None);
848 assert_eq!(map.get_persisted::<Serializable>(id), None);
849
850 let mut map: IdTypeMap = ron::from_str(&serialized).unwrap();
854 assert_eq!(map.get_temp::<Serializable>(id), None);
855 assert_eq!(
856 map.get_persisted::<Serializable>(id),
857 Some(Serializable(555))
858 );
859 assert_eq!(map.get_temp::<Serializable>(id), Some(Serializable(555)));
860}
861
862#[cfg(feature = "persistence")]
863#[test]
864fn test_serialize_generations() {
865 use serde::{Deserialize, Serialize};
866
867 fn serialize_and_deserialize(map: &IdTypeMap) -> IdTypeMap {
868 let serialized = ron::to_string(map).unwrap();
869 ron::from_str(&serialized).unwrap()
870 }
871
872 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
873 struct A(i32);
874
875 let mut map: IdTypeMap = Default::default();
876 for i in 0..3 {
877 map.insert_persisted(Id::new(i), A(i));
878 }
879 for i in 0..3 {
880 assert_eq!(map.get_generation::<A>(Id::new(i)), Some(0));
881 }
882
883 map = serialize_and_deserialize(&map);
884
885 for i in 0..3 {
890 assert_eq!(map.get_generation::<A>(Id::new(i)), Some(2));
891 }
892
893 assert_eq!(map.get_persisted::<A>(Id::new(0)), Some(A(0)));
895 assert_eq!(map.get_generation::<A>(Id::new(0)), Some(0));
896
897 map = serialize_and_deserialize(&map);
899 assert_eq!(map.get_generation::<A>(Id::new(0)), Some(2));
900 assert_eq!(map.get_generation::<A>(Id::new(1)), Some(3));
901}
902
903#[cfg(feature = "persistence")]
904#[test]
905fn test_serialize_gc() {
906 use serde::{Deserialize, Serialize};
907
908 fn serialize_and_deserialize(mut map: IdTypeMap, max_bytes_per_type: usize) -> IdTypeMap {
909 map.set_max_bytes_per_type(max_bytes_per_type);
910 let serialized = ron::to_string(&map).unwrap();
911 ron::from_str(&serialized).unwrap()
912 }
913
914 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
915 struct A(usize);
916
917 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
918 struct B(usize);
919
920 let mut map: IdTypeMap = Default::default();
921
922 let num_a = 1_000;
923 let num_b = 10;
924
925 for i in 0..num_a {
926 map.insert_persisted(Id::new(i), A(i));
927 }
928 for i in 0..num_b {
929 map.insert_persisted(Id::new(i), B(i));
930 }
931
932 map = serialize_and_deserialize(map, 100);
933
934 assert_eq!(map.count::<A>(), num_a);
936 assert_eq!(map.count::<B>(), num_b);
937
938 map.insert_persisted(Id::new(1_000_000), A(1_000_000));
940 map.insert_persisted(Id::new(1_000_000), B(1_000_000));
941
942 assert_eq!(map.count::<A>(), num_a + 1);
943 assert_eq!(map.count::<B>(), num_b + 1);
944
945 assert_eq!(map.get_persisted::<A>(Id::new(0)), Some(A(0)));
947 assert_eq!(map.get_persisted::<B>(Id::new(0)), Some(B(0)));
948
949 map = serialize_and_deserialize(map, 100);
950
951 assert_eq!(
952 map.count::<A>(),
953 2,
954 "We should have dropped the oldest generation, but kept the new value and the read value"
955 );
956 assert_eq!(
957 map.count::<B>(),
958 num_b + 1,
959 "B should fit under the byte limit"
960 );
961
962 map.insert_persisted(Id::new(2_000_000), A(2_000_000));
964 map.insert_persisted(Id::new(2_000_000), B(2_000_000));
965
966 map = serialize_and_deserialize(map, 100);
967
968 assert_eq!(map.count::<A>(), 3); assert_eq!(map.count::<B>(), num_b + 2); map = serialize_and_deserialize(map, 1);
974
975 assert_eq!(map.count::<A>(), 1);
976 assert_eq!(map.count::<B>(), 1);
977
978 assert_eq!(
979 map.get_persisted::<A>(Id::new(2_000_000)),
980 Some(A(2_000_000))
981 );
982 assert_eq!(
983 map.get_persisted::<B>(Id::new(2_000_000)),
984 Some(B(2_000_000))
985 );
986}