diff --git a/libs/persistent_range_query/src/lib.rs b/libs/persistent_range_query/src/lib.rs index cef8d65806..64c9634215 100644 --- a/libs/persistent_range_query/src/lib.rs +++ b/libs/persistent_range_query/src/lib.rs @@ -42,17 +42,25 @@ pub trait RangeModification { fn compose(later: &Self, earlier: &mut Self); } -pub trait VecVersion, Key>: Clone { +pub trait VecReadableVersion, Key> { fn get(&self, keys: Range) -> Modification::Result; - fn modify(&mut self, keys: Range, modification: Modification); +} + +pub trait VecFrozenVersion, Key>: + Clone + VecReadableVersion +{ } pub trait PersistentVecStorage< Modification: RangeModification, Initializer: LazyRangeInitializer, Key, -> +>: VecReadableVersion { - type Version: VecVersion; - fn new(all_keys: Range, initializer: Initializer) -> Self::Version; + fn new(all_keys: Range, initializer: Initializer) -> Self; + + type FrozenVersion: VecFrozenVersion; + + fn modify(&mut self, keys: Range, modification: Modification); + fn freeze(&mut self) -> Self::FrozenVersion; } diff --git a/libs/persistent_range_query/src/naive.rs b/libs/persistent_range_query/src/naive.rs index 732f7576a1..a89622687c 100644 --- a/libs/persistent_range_query/src/naive.rs +++ b/libs/persistent_range_query/src/naive.rs @@ -1,16 +1,49 @@ use crate::{ - LazyRangeInitializer, PersistentVecStorage, RangeModification, RangeQueryResult, VecVersion, + LazyRangeInitializer, PersistentVecStorage, RangeModification, RangeQueryResult, + VecFrozenVersion, VecReadableVersion, }; +use std::marker::PhantomData; use std::ops::Range; +use std::rc::Rc; -pub struct NaiveVecVersion, Key> { +pub struct NaiveFrozenVersion, Key> { all_keys: Range, - values: Vec, + values: Rc>>, } -impl, Key: Clone> Clone for NaiveVecVersion -where - Modification::Result: Clone, +pub trait IndexableKey: Clone { + fn index(all_keys: &Range, key: &Self) -> usize; + fn element_range(all_keys: &Range, index: usize) -> Range; +} + +fn get, Key: IndexableKey>( + all_keys: &Range, + values: &Vec, + keys: Range, +) -> Modification::Result { + let mut result = Modification::Result::new_for_empty_range(); + let mut result_range = keys.start.clone()..keys.start.clone(); + for index in + IndexableKey::index(&all_keys, &keys.start)..IndexableKey::index(&all_keys, &keys.end) + { + let element_range = IndexableKey::element_range(&all_keys, index); + Modification::Result::add(&mut result, &result_range, &values[index], &element_range); + result_range.end = element_range.end; + } + result +} + +impl, Key: IndexableKey> VecReadableVersion + for NaiveFrozenVersion +{ + fn get(&self, keys: Range) -> Modification::Result { + get::(&self.all_keys, &self.values, keys) + } +} + +// Manual implementation of `Clone` becase `derive` requires `Modification: Clone` +impl<'a, Modification: RangeModification, Key: Clone> Clone + for NaiveFrozenVersion { fn clone(&self) -> Self { Self { @@ -20,61 +53,72 @@ where } } -pub trait IndexableKey: Clone { - fn index(all_keys: &Range, key: &Self) -> usize; - fn element_range(all_keys: &Range, index: usize) -> Range; +impl<'a, Modification: RangeModification, Key: IndexableKey> + VecFrozenVersion for NaiveFrozenVersion +{ } -impl, Key: IndexableKey> VecVersion - for NaiveVecVersion +// TODO: is it at all possible to store previous versions in this struct, +// without any Rc<>? +pub struct NaiveVecStorage< + Modification: RangeModification, + Initializer: LazyRangeInitializer, + Key: IndexableKey, +> { + all_keys: Range, + last_version: Vec, + _initializer: PhantomData, +} + +impl< + Modification: RangeModification, + Initializer: LazyRangeInitializer, + Key: IndexableKey, + > VecReadableVersion for NaiveVecStorage where Modification::Result: Clone, { fn get(&self, keys: Range) -> Modification::Result { - let mut result = Modification::Result::new_for_empty_range(); - let mut result_range = keys.start.clone()..keys.start.clone(); - for index in IndexableKey::index(&self.all_keys, &keys.start) - ..IndexableKey::index(&self.all_keys, &keys.end) - { - let element_range = IndexableKey::element_range(&self.all_keys, index); - Modification::Result::add( - &mut result, - &result_range, - &self.values[index], - &element_range, - ); - result_range.end = element_range.end; - } - result + get::(&self.all_keys, &self.last_version, keys) } +} + +impl< + Modification: RangeModification, + Initializer: LazyRangeInitializer, + Key: IndexableKey, + > PersistentVecStorage + for NaiveVecStorage +where + Modification::Result: Clone, +{ + fn new(all_keys: Range, initializer: Initializer) -> Self { + let mut values = Vec::with_capacity(IndexableKey::index(&all_keys, &all_keys.end)); + for index in 0..values.capacity() { + values.push(initializer.get(&IndexableKey::element_range(&all_keys, index))); + } + NaiveVecStorage { + all_keys, + last_version: values, + _initializer: PhantomData, + } + } + + type FrozenVersion = NaiveFrozenVersion; fn modify(&mut self, keys: Range, modification: Modification) { for index in IndexableKey::index(&self.all_keys, &keys.start) ..IndexableKey::index(&self.all_keys, &keys.end) { let element_range = IndexableKey::element_range(&self.all_keys, index); - modification.apply(&mut self.values[index], &element_range); + modification.apply(&mut self.last_version[index], &element_range); + } + } + + fn freeze(&mut self) -> Self::FrozenVersion { + NaiveFrozenVersion:: { + all_keys: self.all_keys.clone(), + values: Rc::new(Box::new(self.last_version.clone())), } } } - -pub struct NaiveVecStorage; - -impl< - Modification: RangeModification, - Initializer: LazyRangeInitializer, - Key: IndexableKey, - > PersistentVecStorage for NaiveVecStorage -where - Modification::Result: Clone, -{ - type Version = NaiveVecVersion; - - fn new(all_keys: Range, initializer: Initializer) -> Self::Version { - let mut values = Vec::with_capacity(IndexableKey::index(&all_keys, &all_keys.end)); - for index in 0..values.capacity() { - values.push(initializer.get(&IndexableKey::element_range(&all_keys, index))); - } - NaiveVecVersion { all_keys, values } - } -} diff --git a/libs/persistent_range_query/tests/rsq_test.rs b/libs/persistent_range_query/tests/rsq_test.rs index a9e95220e3..196c1c1f10 100644 --- a/libs/persistent_range_query/tests/rsq_test.rs +++ b/libs/persistent_range_query/tests/rsq_test.rs @@ -1,7 +1,7 @@ use persistent_range_query::naive::*; use persistent_range_query::ops::rsq::*; use persistent_range_query::ops::SameElementsInitializer; -use persistent_range_query::{PersistentVecStorage, VecVersion}; +use persistent_range_query::{PersistentVecStorage, VecReadableVersion}; use std::ops::Range; #[derive(Copy, Clone, Debug)] @@ -25,13 +25,13 @@ impl SumOfSameElements for i32 { #[test] fn test_naive() { - let mut s: NaiveVecVersion, _> = + let mut s: NaiveVecStorage, _, _> = NaiveVecStorage::new(K(0)..K(12), SameElementsInitializer::new(0i32)); assert_eq!(*s.get(K(0)..K(12)).sum(), 0); s.modify(K(2)..K(5), AddAssignModification::Add(3)); assert_eq!(*s.get(K(0)..K(12)).sum(), 3 + 3 + 3); - let s_old = s.clone(); + let s_old = s.freeze(); s.modify(K(3)..K(6), AddAssignModification::Assign(10)); assert_eq!(*s.get(K(0)..K(12)).sum(), 3 + 10 + 10 + 10);