1use std::collections::{BTreeMap, HashMap};
2use std::error::Error;
3use std::fmt::Display;
4
5use serde::{Deserialize, Serialize};
6use uniquevec::UniqueVec;
7
8#[cfg(feature = "tracing")]
9use tracing::instrument;
10
11use super::memory_storage::MemoryStorageInterface;
12use super::ron::RonStorageInterface;
13use super::serde_json::JsonStorageInterface;
14use super::sled_database::SledStorageInterface;
15
16#[derive(Debug)]
18pub enum StorageError {
19 IoError(std::io::Error),
21 SerdeJsonError(serde_json::Error),
23 RonError(ron::Error),
25 RonSpannedError(ron::error::SpannedError),
27 SledError(sled::Error),
29 BincodeSeError(bincode::error::EncodeError),
31 BincodeDeError(bincode::error::DecodeError),
33 InitError(String),
35 ParseIntError(std::num::ParseIntError),
37 Utf8Error(std::str::Utf8Error),
39 PoisonError(String),
41}
42
43impl From<serde_json::Error> for StorageError {
44 fn from(err: serde_json::Error) -> Self {
45 StorageError::SerdeJsonError(err)
46 }
47}
48
49impl From<ron::error::SpannedError> for StorageError {
50 fn from(err: ron::error::SpannedError) -> Self {
51 StorageError::RonSpannedError(err)
52 }
53}
54
55impl From<ron::Error> for StorageError {
56 fn from(err: ron::Error) -> Self {
57 StorageError::RonError(err)
58 }
59}
60
61impl From<sled::Error> for StorageError {
62 fn from(err: sled::Error) -> Self {
63 StorageError::SledError(err)
64 }
65}
66
67impl From<bincode::error::EncodeError> for StorageError {
68 fn from(err: bincode::error::EncodeError) -> Self {
69 StorageError::BincodeSeError(err)
70 }
71}
72
73impl From<bincode::error::DecodeError> for StorageError {
74 fn from(err: bincode::error::DecodeError) -> Self {
75 StorageError::BincodeDeError(err)
76 }
77}
78
79impl From<std::io::Error> for StorageError {
80 fn from(err: std::io::Error) -> Self {
81 StorageError::IoError(err)
82 }
83}
84
85impl From<std::str::Utf8Error> for StorageError {
86 fn from(err: std::str::Utf8Error) -> Self {
87 StorageError::Utf8Error(err)
88 }
89}
90
91impl From<std::num::ParseIntError> for StorageError {
92 fn from(err: std::num::ParseIntError) -> Self {
93 StorageError::ParseIntError(err)
94 }
95}
96
97impl<T> From<std::sync::PoisonError<T>> for StorageError {
98 fn from(err: std::sync::PoisonError<T>) -> Self {
99 StorageError::PoisonError(format!("{err}"))
100 }
101}
102
103impl Display for StorageError {
104 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
105 match self {
106 StorageError::SerdeJsonError(message) => write!(f, "{}", message),
107 StorageError::RonError(message) => write!(f, "{}", message),
108 StorageError::RonSpannedError(message) => write!(f, "{}", message),
109 StorageError::SledError(message) => write!(f, "{}", message),
110 StorageError::BincodeSeError(message) => write!(f, "{}", message),
111 StorageError::BincodeDeError(message) => write!(f, "{}", message),
112 StorageError::IoError(message) => write!(f, "{}", message),
113 StorageError::InitError(message) => write!(f, "{}", message),
114 StorageError::Utf8Error(message) => write!(f, "{}", message),
115 StorageError::ParseIntError(message) => write!(f, "{}", message),
116 StorageError::PoisonError(message) => write!(f, "{}", message),
117 }
118 }
119}
120
121impl Error for StorageError {}
122
123#[cfg_attr(feature = "pyo3", pyo3::pyclass(eq, eq_int))]
128#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
129pub enum StorageOption {
130 Sled,
132 SledTemp,
134 SerdeJson,
136 Ron,
140 Memory,
142}
143
144impl StorageOption {
145 pub fn default_priority() -> UniqueVec<Self> {
147 vec![
148 StorageOption::SerdeJson,
149 ]
152 .into()
153 }
154}
155
156#[derive(Clone, Debug, Deserialize, Serialize)]
158pub struct CombinedSaveFormat<Id, Element> {
159 pub identifier: Id,
161 pub element: Element,
163}
164
165#[derive(Clone, Debug, Deserialize, Serialize)]
167pub struct BatchSaveFormat<Id, Element> {
168 pub(super) data: Vec<CombinedSaveFormat<Id, Element>>,
169}
170
171#[derive(Clone, Debug)]
174pub struct StorageManager<Id, Element> {
175 storage_priority: UniqueVec<StorageOption>,
176 builder: StorageBuilder<true>,
177 instance: u64,
178
179 sled_storage: Option<SledStorageInterface<Id, Element>>,
180 sled_temp_storage: Option<SledStorageInterface<Id, Element, true>>,
181 json_storage: Option<StorageWrapper<JsonStorageInterface<Id, Element>>>,
182 ron_storage: Option<StorageWrapper<RonStorageInterface<Id, Element>>>,
183 memory_storage: Option<MemoryStorageInterface<Id, Element>>,
184}
185
186#[derive(Clone, Debug, Deserialize, Serialize)]
202pub struct StorageBuilder<const INIT: bool = false> {
203 location: std::path::PathBuf,
204 priority: UniqueVec<StorageOption>,
205 suffix: std::path::PathBuf,
206 #[cfg(feature = "timestamp")]
207 add_date: bool,
208 #[cfg(feature = "timestamp")]
209 date: std::path::PathBuf,
210}
211
212impl<const INIT: bool> StorageBuilder<INIT> {
213 pub fn priority(self, priority: impl IntoIterator<Item = StorageOption>) -> Self {
215 let (priority, _) = UniqueVec::from_iter(priority);
216 Self { priority, ..self }
217 }
218
219 pub fn get_priority(&self) -> UniqueVec<StorageOption> {
221 self.priority.clone()
222 }
223
224 pub fn suffix(self, suffix: impl Into<std::path::PathBuf>) -> Self {
226 Self {
227 suffix: suffix.into(),
228 ..self
229 }
230 }
231
232 pub fn get_suffix(&self) -> std::path::PathBuf {
234 self.suffix.clone()
235 }
236
237 #[cfg(feature = "timestamp")]
239 pub fn add_date(self, add_date: bool) -> Self {
240 Self { add_date, ..self }
241 }
242
243 #[cfg(feature = "timestamp")]
245 pub fn get_add_date(&self) -> bool {
246 self.add_date
247 }
248}
249
250impl StorageBuilder<false> {
251 #[cfg_attr(feature = "tracing", instrument(skip_all))]
258 pub fn new() -> Self {
259 Self {
260 location: "./out".into(),
261 priority: UniqueVec::from_iter([StorageOption::SerdeJson]).0,
262 suffix: "".into(),
263 #[cfg(feature = "timestamp")]
264 add_date: true,
265 #[cfg(feature = "timestamp")]
266 date: "".into(),
267 }
268 }
269
270 #[cfg_attr(feature = "tracing", instrument(skip_all))]
272 pub fn init(self) -> StorageBuilder<true> {
273 #[cfg(feature = "timestamp")]
274 let date: std::path::PathBuf = if self.add_date {
275 format!("{}", chrono::Local::now().format("%Y-%m-%d-T%H-%M-%S")).into()
276 } else {
277 "".into()
278 };
279 self.init_with_date(&date)
280 }
281
282 #[cfg_attr(feature = "tracing", instrument(skip_all))]
284 pub fn init_with_date(self, date: &std::path::Path) -> StorageBuilder<true> {
285 StorageBuilder::<true> {
286 location: self.location,
287 priority: self.priority,
288 suffix: self.suffix,
289 #[cfg(feature = "timestamp")]
290 add_date: self.add_date,
291 #[cfg(feature = "timestamp")]
292 date: date.into(),
293 }
294 }
295
296 pub fn location<P>(self, location: P) -> Self
301 where
302 std::path::PathBuf: From<P>,
303 {
304 Self {
305 location: location.into(),
306 ..self
307 }
308 }
309
310 pub fn get_location(&self) -> std::path::PathBuf {
315 self.location.clone()
316 }
317}
318
319impl StorageBuilder<true> {
320 #[cfg_attr(feature = "tracing", instrument(skip_all))]
323 pub fn get_full_path(&self) -> std::path::PathBuf {
324 let mut full_path = self.location.clone();
325 #[cfg(feature = "timestamp")]
326 if self.add_date {
327 full_path.extend(&self.date);
328 }
329 full_path.extend(&self.suffix);
330 full_path
331 }
332
333 #[doc(hidden)]
334 pub fn init(self) -> Self {
335 self
336 }
337
338 pub fn de_init(self) -> StorageBuilder<false> {
340 StorageBuilder {
341 location: self.location,
342 priority: self.priority,
343 suffix: self.suffix,
344 #[cfg(feature = "timestamp")]
345 add_date: self.add_date,
346 #[cfg(feature = "timestamp")]
347 date: "".into(),
348 }
349 }
350}
351
352impl<Id, Element> StorageManager<Id, Element> {
353 #[cfg_attr(feature = "tracing", instrument(skip_all))]
366 pub fn open_or_create(
367 storage_builder: StorageBuilder<true>,
368 instance: u64,
369 ) -> Result<Self, StorageError> {
370 let location = storage_builder.get_full_path();
371
372 let mut sled_storage = None;
373 let mut sled_temp_storage = None;
374 let mut json_storage = None;
375 let mut ron_storage = None;
376 let mut memory_storage = None;
377 for storage_variant in storage_builder.priority.iter() {
378 match storage_variant {
379 StorageOption::SerdeJson => {
380 json_storage = Some(StorageWrapper(
381 JsonStorageInterface::<Id, Element>::open_or_create(
382 &location
383 .to_path_buf()
384 .join(JsonStorageInterface::<Id, Element>::EXTENSION),
385 instance,
386 )?,
387 ));
388 }
389 StorageOption::Sled => {
390 sled_storage =
391 Some(SledStorageInterface::<Id, Element, false>::open_or_create(
392 &location.to_path_buf().join("sled"),
393 instance,
394 )?);
395 }
396 StorageOption::SledTemp => {
397 sled_temp_storage =
398 Some(SledStorageInterface::<Id, Element, true>::open_or_create(
399 &location.to_path_buf().join("sled_memory"),
400 instance,
401 )?);
402 }
403 StorageOption::Ron => {
404 ron_storage = Some(StorageWrapper(
405 RonStorageInterface::<Id, Element>::open_or_create(
406 &location
407 .to_path_buf()
408 .join(RonStorageInterface::<Id, Element>::EXTENSION),
409 instance,
410 )?,
411 ));
412 }
413 StorageOption::Memory => {
414 memory_storage = Some(MemoryStorageInterface::<Id, Element>::open_or_create(
415 &location.to_path_buf(),
416 instance,
417 )?);
418 }
419 }
420 }
421 let manager = StorageManager {
422 storage_priority: storage_builder.priority.clone(),
423 builder: storage_builder.clone(),
424 instance,
425
426 sled_storage,
427 sled_temp_storage,
428 json_storage,
429 ron_storage,
430 memory_storage,
431 };
432
433 Ok(manager)
434 }
435
436 pub fn clone_to_new_instance(&self, storage_instance: u64) -> Self {
449 Self {
450 storage_priority: self.storage_priority.clone(),
451 builder: self.builder.clone(),
452 instance: storage_instance,
453
454 sled_storage: self
455 .sled_storage
456 .as_ref()
457 .map(|x| x.clone_to_new_instance(storage_instance)),
458 sled_temp_storage: self
459 .sled_temp_storage
460 .as_ref()
461 .map(|x| x.clone_to_new_instance(storage_instance)),
462 json_storage: self
463 .json_storage
464 .as_ref()
465 .map(|x| StorageWrapper(x.0.clone_to_new_instance(storage_instance))),
466 ron_storage: self
467 .ron_storage
468 .as_ref()
469 .map(|x| StorageWrapper(x.0.clone_to_new_instance(storage_instance))),
470 memory_storage: self
471 .memory_storage
472 .as_ref()
473 .map(|x| x.clone_to_new_instance(storage_instance)),
474 }
475 }
476
477 #[cfg_attr(feature = "tracing", instrument(skip_all))]
479 pub fn extract_builder(&self) -> StorageBuilder<true> {
480 self.builder.clone()
481 }
482
483 pub fn get_instance(&self) -> u64 {
488 self.instance
489 }
490}
491
492macro_rules! exec_for_all_storage_options(
493 (@internal $self:ident, $storage_option:ident, $field:ident, $function:ident, $($args:tt)*) => {
494 {
495 if let Some($field) = &$self.$field {
496 $field.$function($($args)*)
497 } else {
498 Err(StorageError::InitError(
499 stringify!($storage_option, " storage was not initialized but called").into(),
500 ))?
501 }
502 }
503 };
504 (mut $self:ident, $field:ident, $function:ident, $($args:tt)*) => {
505 if let Some($field) = &mut $self.$field {
506 $field.$function($($args)*)?;
507 }
508 };
509 (all mut $self:ident, $function:ident, $($args:tt)*) => {
510 exec_for_all_storage_options!(mut $self, sled_storage, $function, $($args)*);
511 exec_for_all_storage_options!(mut $self, sled_temp_storage, $function, $($args)*);
512 exec_for_all_storage_options!(mut $self, json_storage, $function, $($args)*);
513 exec_for_all_storage_options!(mut $self, ron_storage, $function, $($args)*);
514 exec_for_all_storage_options!(mut $self, memory_storage, $function, $($args)*);
515 };
516 ($self:ident, $priority:ident, $function:ident, $($args:tt)*) => {
517 match $priority {
518 StorageOption::Sled => exec_for_all_storage_options!(
519 @internal $self, Sled, sled_storage, $function, $($args)*
520 ),
521 StorageOption::SledTemp => exec_for_all_storage_options!(
522 @internal $self, SledTemp, sled_temp_storage, $function, $($args)*
523 ),
524 StorageOption::SerdeJson => exec_for_all_storage_options!(
525 @internal $self, SerdeJson, json_storage, $function, $($args)*
526 ),
527 StorageOption::Ron => exec_for_all_storage_options!(
528 @internal $self, Ron, ron_storage, $function, $($args)*
529 ),
530 StorageOption::Memory => exec_for_all_storage_options!(
531 @internal $self, Memory, memory_storage, $function, $($args)*
532 ),
533 }
534 }
535);
536
537impl<Id, Element> StorageInterfaceStore<Id, Element> for StorageManager<Id, Element>
538where
539 Id: core::hash::Hash + core::cmp::Eq + Clone,
540 Element: Clone,
541{
542 #[allow(unused)]
543 fn store_single_element(
544 &mut self,
545 iteration: u64,
546 identifier: &Id,
547 element: &Element,
548 ) -> Result<(), StorageError>
549 where
550 Id: Serialize,
551 Element: Serialize,
552 {
553 exec_for_all_storage_options!(
554 all mut self,
555 store_single_element,
556 iteration, identifier, element
557 );
558 Ok(())
559 }
560
561 #[allow(unused)]
562 fn store_batch_elements<'a, I>(
563 &'a mut self,
564 iteration: u64,
565 identifiers_elements: I,
566 ) -> Result<(), StorageError>
567 where
568 Id: 'a + Serialize,
569 Element: 'a + Serialize,
570 I: Clone + IntoIterator<Item = (&'a Id, &'a Element)>,
571 {
572 exec_for_all_storage_options!(
573 all mut self,
574 store_batch_elements,
575 iteration,
576 identifiers_elements.clone()
577 );
578 Ok(())
579 }
580}
581
582impl<Id, Element> StorageInterfaceLoad<Id, Element> for StorageManager<Id, Element>
583where
584 Id: core::hash::Hash + core::cmp::Eq + Clone,
585 Element: Clone,
586{
587 #[allow(unused)]
588 fn load_single_element(
589 &self,
590 iteration: u64,
591 identifier: &Id,
592 ) -> Result<Option<Element>, StorageError>
593 where
594 Id: Serialize + for<'a> Deserialize<'a>,
595 Element: for<'a> Deserialize<'a>,
596 {
597 for priority in self.storage_priority.iter() {
598 return exec_for_all_storage_options!(
599 self,
600 priority,
601 load_single_element,
602 iteration,
603 identifier
604 );
605 }
606 Ok(None)
607 }
608
609 #[allow(unused)]
610 fn load_all_elements_at_iteration(
611 &self,
612 iteration: u64,
613 ) -> Result<HashMap<Id, Element>, StorageError>
614 where
615 Id: std::hash::Hash + std::cmp::Eq + for<'a> Deserialize<'a>,
616 Element: for<'a> Deserialize<'a>,
617 {
618 for priority in self.storage_priority.iter() {
619 return exec_for_all_storage_options!(
620 self,
621 priority,
622 load_all_elements_at_iteration,
623 iteration
624 );
625 }
626 Ok(HashMap::new())
627 }
628
629 fn get_all_iterations(&self) -> Result<Vec<u64>, StorageError> {
630 for priority in self.storage_priority.iter() {
631 return exec_for_all_storage_options!(self, priority, get_all_iterations,);
632 }
633 Ok(Vec::new())
634 }
635}
636
637pub enum StorageMode {
639 Single,
641 Batch,
643}
644
645impl StorageMode {
646 fn to_str(&self) -> &str {
647 match self {
648 Self::Single => "single",
649 Self::Batch => "batch",
650 }
651 }
652}
653
654pub trait FileBasedStorage<Id, Element> {
656 const EXTENSION: &'static str;
658
659 fn get_path(&self) -> &std::path::Path;
661
662 fn get_storage_instance(&self) -> u64;
665
666 fn to_writer_pretty<V, W>(&self, writer: W, value: &V) -> Result<(), StorageError>
668 where
669 V: Serialize,
670 W: std::io::Write;
671
672 fn from_str<V>(&self, input: &str) -> Result<V, StorageError>
674 where
675 V: for<'a> Deserialize<'a>;
676
677 fn create_or_get_iteration_file_with_prefix(
682 &self,
683 iteration: u64,
684 mode: StorageMode,
685 ) -> Result<std::io::BufWriter<std::fs::File>, StorageError> {
686 let save_path = self.get_iteration_save_path_batch_with_prefix(iteration, mode)?;
687
688 let file = std::fs::OpenOptions::new()
690 .read(true)
691 .write(true)
692 .create(true)
693 .open(&save_path)?;
694
695 Ok(std::io::BufWriter::new(file))
696 }
697
698 fn get_iteration_path(&self, iteration: u64) -> std::path::PathBuf {
703 self.get_path().join(format!("{:020.0}", iteration))
704 }
705
706 fn get_iteration_save_path_batch_with_prefix(
709 &self,
710 iteration: u64,
711 mode: StorageMode,
712 ) -> Result<std::path::PathBuf, StorageError> {
713 let iteration_path = self.get_iteration_path(iteration);
715 std::fs::create_dir_all(&iteration_path)?;
717
718 let prefix = mode.to_str();
721 let create_save_path = |i: usize| -> std::path::PathBuf {
722 iteration_path
723 .join(format!(
724 "{}_{:020.0}_{:020.0}",
725 prefix,
726 self.get_storage_instance(),
727 i
728 ))
729 .with_extension(Self::EXTENSION)
730 };
731 let mut counter = 0;
732 let mut save_path;
733 while {
734 save_path = create_save_path(counter);
735 save_path.exists()
736 } {
737 counter += 1
738 }
739 Ok(save_path)
740 }
741
742 fn folder_name_to_iteration(
746 &self,
747 file: &std::path::Path,
748 ) -> Result<Option<u64>, StorageError> {
749 match file.file_stem() {
750 Some(filename) => match filename.to_str() {
751 Some(filename_string) => Ok(Some(filename_string.parse::<u64>()?)),
752 None => Ok(None),
753 },
754 None => Ok(None),
755 }
756 }
757}
758
759#[derive(Clone, Debug, Deserialize, Serialize)]
760pub(crate) struct StorageWrapper<T>(pub(crate) T);
761
762impl<T, Id, Element> StorageInterfaceStore<Id, Element> for StorageWrapper<T>
763where
764 T: FileBasedStorage<Id, Element>,
765{
766 fn store_batch_elements<'a, I>(
767 &'a mut self,
768 iteration: u64,
769 identifiers_elements: I,
770 ) -> Result<(), StorageError>
771 where
772 Id: 'a + Serialize,
773 Element: 'a + Serialize,
774 I: Clone + IntoIterator<Item = (&'a Id, &'a Element)>,
775 {
776 let iteration_file = self
777 .0
778 .create_or_get_iteration_file_with_prefix(iteration, StorageMode::Batch)?;
779 let batch = BatchSaveFormat {
780 data: identifiers_elements
781 .into_iter()
782 .map(|(id, element)| CombinedSaveFormat {
783 identifier: id,
784 element,
785 })
786 .collect(),
787 };
788 self.0.to_writer_pretty(iteration_file, &batch)?;
789 Ok(())
790 }
791
792 fn store_single_element(
793 &mut self,
794 iteration: u64,
795 identifier: &Id,
796 element: &Element,
797 ) -> Result<(), StorageError>
798 where
799 Id: Serialize,
800 Element: Serialize,
801 {
802 let iteration_file = self
803 .0
804 .create_or_get_iteration_file_with_prefix(iteration, StorageMode::Single)?;
805 let save_format = CombinedSaveFormat {
806 identifier,
807 element,
808 };
809 self.0.to_writer_pretty(iteration_file, &save_format)?;
810 Ok(())
811 }
812}
813
814pub trait StorageInterfaceOpen {
816 fn open_or_create(
821 location: &std::path::Path,
822 storage_instance: u64,
823 ) -> Result<Self, StorageError>
824 where
825 Self: Sized;
826
827 fn clone_to_new_instance(&self, storage_instance: u64) -> Self;
831}
832
833pub trait StorageInterfaceStore<Id, Element> {
835 fn store_single_element(
837 &mut self,
838 iteration: u64,
839 identifier: &Id,
840 element: &Element,
841 ) -> Result<(), StorageError>
842 where
843 Id: Serialize,
844 Element: Serialize;
845
846 fn store_batch_elements<'a, I>(
848 &'a mut self,
849 iteration: u64,
850 identifiers_elements: I,
851 ) -> Result<(), StorageError>
852 where
853 Id: 'a + Serialize,
854 Element: 'a + Serialize,
855 I: Clone + IntoIterator<Item = (&'a Id, &'a Element)>;
856}
857
858pub trait StorageInterfaceLoad<Id, Element> {
860 fn load_single_element(
864 &self,
865 iteration: u64,
866 identifier: &Id,
867 ) -> Result<Option<Element>, StorageError>
868 where
869 Id: Eq + Serialize + for<'a> Deserialize<'a>,
870 Element: for<'a> Deserialize<'a>;
871
872 fn load_element_history(&self, identifier: &Id) -> Result<HashMap<u64, Element>, StorageError>
900 where
901 Id: Eq + Serialize + for<'a> Deserialize<'a>,
902 Element: for<'a> Deserialize<'a>,
903 {
904 let mut iterations = self.get_all_iterations()?;
905 iterations.sort();
906 let mut started_gathering = false;
907 let mut stop_gathering = false;
908 let results = iterations
909 .iter()
910 .filter_map(|&iteration| {
911 if stop_gathering {
912 None
913 } else {
914 match self.load_single_element(iteration, identifier) {
915 Ok(Some(element)) => {
916 started_gathering = true;
917 Some(Ok((iteration, element)))
918 }
919 Ok(None) => {
920 if started_gathering {
921 stop_gathering = true;
922 }
923 None
924 }
925 Err(e) => Some(Err(e)),
926 }
927 }
928 })
929 .collect::<Result<HashMap<u64, _>, StorageError>>()?;
930 Ok(results)
931 }
932
933 fn load_all_elements_at_iteration(
938 &self,
939 iteration: u64,
940 ) -> Result<HashMap<Id, Element>, StorageError>
941 where
942 Id: std::hash::Hash + std::cmp::Eq + for<'a> Deserialize<'a>,
943 Element: for<'a> Deserialize<'a>;
944
945 fn get_all_iterations(&self) -> Result<Vec<u64>, StorageError>;
947
948 fn load_all_elements(&self) -> Result<BTreeMap<u64, HashMap<Id, Element>>, StorageError>
952 where
953 Id: std::hash::Hash + std::cmp::Eq + for<'a> Deserialize<'a>,
954 Element: for<'a> Deserialize<'a>,
955 {
956 let iterations = self.get_all_iterations()?;
957 let all_elements = iterations
958 .iter()
959 .map(|iteration| {
960 let elements = self.load_all_elements_at_iteration(*iteration)?;
961 Ok((*iteration, elements))
962 })
963 .collect::<Result<BTreeMap<_, _>, StorageError>>()?;
964 Ok(all_elements)
965 }
966
967 fn load_all_element_histories(
970 &self,
971 ) -> Result<HashMap<Id, BTreeMap<u64, Element>>, StorageError>
972 where
973 Id: std::hash::Hash + std::cmp::Eq + for<'a> Deserialize<'a>,
974 Element: for<'a> Deserialize<'a>,
975 {
976 let all_elements = self.load_all_elements()?;
977 let reordered_elements: HashMap<Id, BTreeMap<u64, Element>> = all_elements
978 .into_iter()
979 .map(|(iteration, identifier_to_elements)| {
980 identifier_to_elements
981 .into_iter()
982 .map(move |(identifier, element)| (identifier, iteration, element))
983 })
984 .flatten()
985 .fold(
986 HashMap::new(),
987 |mut acc, (identifier, iteration, element)| {
988 let existing_elements = acc.entry(identifier).or_default();
989 existing_elements.insert(iteration, element);
990 acc
991 },
992 );
993 Ok(reordered_elements)
994 }
995}
996
997impl<T, Id, Element> StorageInterfaceLoad<Id, Element> for StorageWrapper<T>
998where
999 T: FileBasedStorage<Id, Element>,
1000{
1001 fn load_single_element(
1002 &self,
1003 iteration: u64,
1004 identifier: &Id,
1005 ) -> Result<Option<Element>, StorageError>
1006 where
1007 Id: Eq + Serialize + for<'a> Deserialize<'a>,
1008 Element: for<'a> Deserialize<'a>,
1009 {
1010 let iterations = self.get_all_iterations()?;
1011 if iterations.contains(&iteration) {
1012 let iteration_path = self.0.get_iteration_path(iteration);
1014
1015 for path in std::fs::read_dir(&iteration_path)? {
1017 let p = path?.path();
1018 let content = std::fs::read_to_string(&p)?;
1019
1020 match p.file_stem() {
1021 Some(stem) => match stem.to_str() {
1022 Some(tail) => {
1023 let first_name_segment = tail.split("_").into_iter().next();
1024 if first_name_segment == Some("batch") {
1025 let result: BatchSaveFormat<Id, Element> =
1026 self.0.from_str(&content)?;
1027 for json_save_format in result.data.into_iter() {
1028 if &json_save_format.identifier == identifier {
1029 return Ok(Some(json_save_format.element));
1030 }
1031 }
1032 } else if first_name_segment == Some("single") {
1033 let result: CombinedSaveFormat<Id, Element> =
1034 self.0.from_str(&content)?;
1035 if &result.identifier == identifier {
1036 return Ok(Some(result.element));
1037 }
1038 }
1039 }
1040 None => (),
1041 },
1042 None => (),
1043 }
1044 }
1045 return Ok(None);
1046 } else {
1047 return Ok(None);
1048 }
1049 }
1050
1051 fn load_all_elements_at_iteration(
1052 &self,
1053 iteration: u64,
1054 ) -> Result<HashMap<Id, Element>, StorageError>
1055 where
1056 Id: std::hash::Hash + std::cmp::Eq + for<'a> Deserialize<'a>,
1057 Element: for<'a> Deserialize<'a>,
1058 {
1059 let iterations = self.get_all_iterations()?;
1060 if iterations.contains(&iteration) {
1061 let mut all_elements_at_iteration = HashMap::new();
1063
1064 let iteration_path = self.0.get_iteration_path(iteration);
1066
1067 for path in std::fs::read_dir(&iteration_path)? {
1069 let p = path?.path();
1070 let content = std::fs::read_to_string(&p)?;
1071
1072 match p.file_stem() {
1073 Some(stem) => match stem.to_str() {
1074 Some(tail) => {
1075 let first_name_segment = tail.split("_").into_iter().next();
1076 if first_name_segment == Some("batch") {
1077 let result: BatchSaveFormat<Id, Element> =
1078 self.0.from_str(&content)?;
1079 all_elements_at_iteration.extend(result.data.into_iter().map(
1080 |json_save_format| {
1081 (json_save_format.identifier, json_save_format.element)
1082 },
1083 ));
1084 } else if first_name_segment == Some("single") {
1085 let result: CombinedSaveFormat<Id, Element> =
1086 self.0.from_str(&content)?;
1087 all_elements_at_iteration
1088 .extend([(result.identifier, result.element)]);
1089 }
1090 }
1091 None => (),
1092 },
1093 None => (),
1094 }
1095 }
1096 return Ok(all_elements_at_iteration);
1097 } else {
1098 return Ok(HashMap::new());
1099 }
1100 }
1101
1102 fn get_all_iterations(&self) -> Result<Vec<u64>, StorageError> {
1103 let paths = std::fs::read_dir(&self.0.get_path())?;
1104 paths
1105 .into_iter()
1106 .filter_map(|path| match path {
1107 Ok(p) => match self.0.folder_name_to_iteration(&p.path()) {
1108 Ok(Some(entry)) => Some(Ok(entry)),
1109 Ok(None) => None,
1110 Err(e) => Some(Err(e)),
1111 },
1112 Err(_) => None,
1113 })
1114 .collect::<Result<Vec<_>, _>>()
1115 }
1116}
1117
1118pub trait StorageInterface<Id, Element>:
1120 StorageInterfaceOpen + StorageInterfaceLoad<Id, Element> + StorageInterfaceStore<Id, Element>
1121{
1122}
1123
1124impl<Id, Element, T> StorageInterface<Id, Element> for T
1125where
1126 T: StorageInterfaceLoad<Id, Element>,
1127 T: StorageInterfaceStore<Id, Element>,
1128 T: StorageInterfaceOpen,
1129{
1130}