use std::ops::Range; pub mod naive; pub mod ops; /// Should be a monoid: /// * Identity element: for all a: combine(new_for_empty_range(), a) = combine(a, new_for_empty_range()) = a /// * Associativity: for all a, b, c: combine(combine(a, b), c) == combine(a, combine(b, c)) pub trait RangeQueryResult: Sized { fn new_for_empty_range() -> Self; // Contract: left_range.end == right_range.start // left_range.start == left_range.end == right_range.start == right_range.end is still possible fn combine( left: &Self, left_range: &Range, right: &Self, right_range: &Range, ) -> Self; fn add(left: &mut Self, left_range: &Range, right: &Self, right_range: &Range); } pub trait LazyRangeInitializer, Key> { fn get(&self, range: &Range) -> Result; } /// Should be a monoid: /// * Identity element: for all op: compose(no_op(), op) == compose(op, no_op()) == op /// * Associativity: for all op_1, op_2, op_3: compose(compose(op_1, op_2), op_3) == compose(op_1, compose(op_2, op_3)) /// /// Should left act on Result: /// * Identity operation: for all r: no_op().apply(r) == r /// * Compatibility: for all op_1, op_2, r: op_1.apply(op_2.apply(r)) == compose(op_1, op_2).apply(r) pub trait RangeModification { type Result: RangeQueryResult; fn no_op() -> Self; fn apply(&self, result: &mut Self::Result, range: &Range); fn compose(later: &Self, earlier: &mut Self); } pub trait VecVersion, Key>: Clone { fn get(&self, keys: Range) -> Modification::Result; fn modify(&mut self, keys: Range, modification: Modification); } pub trait PersistentVecStorage< Modification: RangeModification, Initializer: LazyRangeInitializer, Key, > { type Version: VecVersion; fn new(all_keys: Range, initializer: Initializer) -> Self::Version; }