pub struct XvcStore<T>where
T: Storable,{ /* private fields */ }
Expand description
A database table like store for type T
It’s used as the general purpose persistence data structure for all components.
It contains an XvcEntity -> T
map, and an index T -> Vec<XvcEntity>
for these entries for
quick reverse lookup.
It loads these data from EventLog collections.
It has basic functionality to insert, delete, filter and iterate over the elements.
Implementations§
Source§impl<T> XvcStore<T>where
T: Storable,
impl<T> XvcStore<T>where
T: Storable,
Sourcepub fn from_event_logs(
previous: EventLog<T>,
current: EventLog<T>,
) -> XvcStore<T>
pub fn from_event_logs( previous: EventLog<T>, current: EventLog<T>, ) -> XvcStore<T>
Creates a store from previous and current EventLog.
This is used when conversions between stores are required.
When elements are inserted with XvcStore::insert, they are added to current
and
serialized to disk over and over.
See https://github.com/iesahin/xvc/issues/45
Sourcepub fn all_event_log_for_entity(
&self,
entity: XvcEntity,
) -> Result<EventLog<T>, Error>
pub fn all_event_log_for_entity( &self, entity: XvcEntity, ) -> Result<EventLog<T>, Error>
Returns all events associated with the entity
Sourcepub fn previous_event_log_for_entity(
&self,
entity: XvcEntity,
) -> Result<EventLog<T>, Error>
pub fn previous_event_log_for_entity( &self, entity: XvcEntity, ) -> Result<EventLog<T>, Error>
Returns (loaded) previous events for the entity
Doesn’t return events in the current invocation
Sourcepub fn insert(&mut self, entity: XvcEntity, value: T) -> Option<T>
pub fn insert(&mut self, entity: XvcEntity, value: T) -> Option<T>
Inserts an entity into the current event log, the map and the index.
Note that this shouldn’t be used in store conversions (from crate::VStore or
crate::HStore). This function adds events to current
set, and these are serialized.
See https://github.com/iesahin/xvc/issues/45
Sourcepub fn update(&mut self, entity: XvcEntity, value: T) -> Option<T>
pub fn update(&mut self, entity: XvcEntity, value: T) -> Option<T>
Updates the data associated with an entity.
This is equivalent to [remove] and [insert], and adds two events to the event log. Returns the previous value if there is one.
Sourcepub fn remove(&mut self, entity: XvcEntity) -> Option<T>
pub fn remove(&mut self, entity: XvcEntity) -> Option<T>
Removes the data associated with entity.
It returns the value if found, otherwise returns None
.
Sourcepub fn from_dir(dir: &Path) -> Result<XvcStore<T>, Error>
pub fn from_dir(dir: &Path) -> Result<XvcStore<T>, Error>
Loads the timestamp named EventLog files from dir
and replays them to build maps.
Sourcepub fn to_dir(&self, dir: &Path) -> Result<(), Error>
pub fn to_dir(&self, dir: &Path) -> Result<(), Error>
Saves the current EventLog to the directory. This is enough to reload it to the saved state.
Sourcepub fn subset<I>(&self, keys: I) -> Result<HStore<T>, Error>
pub fn subset<I>(&self, keys: I) -> Result<HStore<T>, Error>
A subset of this maps identified by XvcEntity
elements of the iterator.
This can be used to split the map arbitrarily.
Sourcepub fn filter<F>(&self, predicate: F) -> HStore<T>
pub fn filter<F>(&self, predicate: F) -> HStore<T>
Creates a new map by calling the predicate
with each value.
predicate
must be a function or closure that returns bool
.
This returns HStore not to create a new event log.
Sourcepub fn any<F>(&self, predicate: F) -> bool
pub fn any<F>(&self, predicate: F) -> bool
Runs predicate
for all elements and returns true if one of them is true.
predicate
must be a function or closure that returns bool
.
Sourcepub fn first(&self) -> Option<(&XvcEntity, &T)>
pub fn first(&self) -> Option<(&XvcEntity, &T)>
Returns the first element of the map
This is useful when there is only one element after Self::filter
Sourcepub fn entities_for(&self, value: &T) -> Option<&Vec<XvcEntity>>where
T: PartialEq,
pub fn entities_for(&self, value: &T) -> Option<&Vec<XvcEntity>>where
T: PartialEq,
Returns the entities for a value
.
There may be more than one entity for a given value, hence it returns a Vec
.
It uses internal reverse index for fast lookup.
Sourcepub fn entity_by_value(&self, value: &T) -> Option<XvcEntity>
pub fn entity_by_value(&self, value: &T) -> Option<XvcEntity>
Returns the first entity matched with Self::entities_for
Sourcepub fn previous_events(&self) -> &EventLog<T>
pub fn previous_events(&self) -> &EventLog<T>
Sourcepub fn current_events(&self) -> &EventLog<T>
pub fn current_events(&self) -> &EventLog<T>
Sourcepub fn left_join<U>(&self, other: XvcStore<U>) -> XvcStore<(T, Option<U>)>where
U: Storable,
pub fn left_join<U>(&self, other: XvcStore<U>) -> XvcStore<(T, Option<U>)>where
U: Storable,
Performs a left join with XvcEntity keys.
The returned store contains (T, Option<U>)
values that correspond to the identical
XvcEntity
values.
In SQL terms, this is a LEFT JOIN.
Note that, it may be more convenient to keep this relationship in a crate::R11Store relative to your use case.
use xvc_ecs::{XvcEntity, XvcStore};
let mut store1 = XvcStore::<String>::new();
store1.insert(10u128.into(), "John Doe".into());
store1.insert(12u128.into(), "George Mason".into());
store1.insert(19u128.into(), "Ali Canfield".into());
let mut store2 = XvcStore::<String>::new();
store2.insert(10u128.into(), "Carpenter".into());
store2.insert(17u128.into(), "Developer".into());
store2.insert(15u128.into(), "Plumber".into());
store2.insert(19u128.into(), "Artist".into());
let result = store1.left_join(store2);
assert_eq!(result.len(), 3);
assert_eq!(result[&10u128.into()], ("John Doe".into(), Some("Carpenter".into())));
assert_eq!(result[&12u128.into()], ("George Mason".into(), None));
assert_eq!(result[&19u128.into()], ("Ali Canfield".into(), Some("Artist".into())));
Sourcepub fn index_map(&self) -> Result<BTreeMap<T, XvcEntity>, Error>
pub fn index_map(&self) -> Result<BTreeMap<T, XvcEntity>, Error>
Returns an inverted map to get entity values quickly
This uses entity_index with a caveat:
- Each value of T must be unique.
Otherwise this panics
Sourcepub fn load_store(store_root: &Path) -> Result<XvcStore<T>, Error>
pub fn load_store(store_root: &Path) -> Result<XvcStore<T>, Error>
Loads a store from the directory built from store_root
and the type name.
Methods from Deref<Target = BTreeMap<XvcEntity, T>>§
1.0.0 · Sourcepub fn get<Q>(&self, key: &Q) -> Option<&V>
pub fn get<Q>(&self, key: &Q) -> Option<&V>
Returns a reference to the value corresponding to the key.
The key may be any borrowed form of the map’s key type, but the ordering on the borrowed form must match the ordering on the key type.
§Examples
use std::collections::BTreeMap;
let mut map = BTreeMap::new();
map.insert(1, "a");
assert_eq!(map.get(&1), Some(&"a"));
assert_eq!(map.get(&2), None);
1.40.0 · Sourcepub fn get_key_value<Q>(&self, k: &Q) -> Option<(&K, &V)>
pub fn get_key_value<Q>(&self, k: &Q) -> Option<(&K, &V)>
Returns the key-value pair corresponding to the supplied key. This is potentially useful:
- for key types where non-identical keys can be considered equal;
- for getting the
&K
stored key value from a borrowed&Q
lookup key; or - for getting a reference to a key with the same lifetime as the collection.
The supplied key may be any borrowed form of the map’s key type, but the ordering on the borrowed form must match the ordering on the key type.
§Examples
use std::cmp::Ordering;
use std::collections::BTreeMap;
#[derive(Clone, Copy, Debug)]
struct S {
id: u32,
name: &'static str, // ignored by equality and ordering operations
}
impl PartialEq for S {
fn eq(&self, other: &S) -> bool {
self.id == other.id
}
}
impl Eq for S {}
impl PartialOrd for S {
fn partial_cmp(&self, other: &S) -> Option<Ordering> {
self.id.partial_cmp(&other.id)
}
}
impl Ord for S {
fn cmp(&self, other: &S) -> Ordering {
self.id.cmp(&other.id)
}
}
let j_a = S { id: 1, name: "Jessica" };
let j_b = S { id: 1, name: "Jess" };
let p = S { id: 2, name: "Paul" };
assert_eq!(j_a, j_b);
let mut map = BTreeMap::new();
map.insert(j_a, "Paris");
assert_eq!(map.get_key_value(&j_a), Some((&j_a, &"Paris")));
assert_eq!(map.get_key_value(&j_b), Some((&j_a, &"Paris"))); // the notable case
assert_eq!(map.get_key_value(&p), None);
1.66.0 · Sourcepub fn first_key_value(&self) -> Option<(&K, &V)>where
K: Ord,
pub fn first_key_value(&self) -> Option<(&K, &V)>where
K: Ord,
Returns the first key-value pair in the map. The key in this pair is the minimum key in the map.
§Examples
use std::collections::BTreeMap;
let mut map = BTreeMap::new();
assert_eq!(map.first_key_value(), None);
map.insert(1, "b");
map.insert(2, "a");
assert_eq!(map.first_key_value(), Some((&1, &"b")));
1.66.0 · Sourcepub fn last_key_value(&self) -> Option<(&K, &V)>where
K: Ord,
pub fn last_key_value(&self) -> Option<(&K, &V)>where
K: Ord,
Returns the last key-value pair in the map. The key in this pair is the maximum key in the map.
§Examples
use std::collections::BTreeMap;
let mut map = BTreeMap::new();
map.insert(1, "b");
map.insert(2, "a");
assert_eq!(map.last_key_value(), Some((&2, &"a")));
1.0.0 · Sourcepub fn contains_key<Q>(&self, key: &Q) -> bool
pub fn contains_key<Q>(&self, key: &Q) -> bool
Returns true
if the map contains a value for the specified key.
The key may be any borrowed form of the map’s key type, but the ordering on the borrowed form must match the ordering on the key type.
§Examples
use std::collections::BTreeMap;
let mut map = BTreeMap::new();
map.insert(1, "a");
assert_eq!(map.contains_key(&1), true);
assert_eq!(map.contains_key(&2), false);
1.17.0 · Sourcepub fn range<T, R>(&self, range: R) -> Range<'_, K, V>
pub fn range<T, R>(&self, range: R) -> Range<'_, K, V>
Constructs a double-ended iterator over a sub-range of elements in the map.
The simplest way is to use the range syntax min..max
, thus range(min..max)
will
yield elements from min (inclusive) to max (exclusive).
The range may also be entered as (Bound<T>, Bound<T>)
, so for example
range((Excluded(4), Included(10)))
will yield a left-exclusive, right-inclusive
range from 4 to 10.
§Panics
Panics if range start > end
.
Panics if range start == end
and both bounds are Excluded
.
§Examples
use std::collections::BTreeMap;
use std::ops::Bound::Included;
let mut map = BTreeMap::new();
map.insert(3, "a");
map.insert(5, "b");
map.insert(8, "c");
for (&key, &value) in map.range((Included(&4), Included(&8))) {
println!("{key}: {value}");
}
assert_eq!(Some((&5, &"b")), map.range(4..).next());
1.0.0 · Sourcepub fn iter(&self) -> Iter<'_, K, V>
pub fn iter(&self) -> Iter<'_, K, V>
Gets an iterator over the entries of the map, sorted by key.
§Examples
use std::collections::BTreeMap;
let mut map = BTreeMap::new();
map.insert(3, "c");
map.insert(2, "b");
map.insert(1, "a");
for (key, value) in map.iter() {
println!("{key}: {value}");
}
let (first_key, first_value) = map.iter().next().unwrap();
assert_eq!((*first_key, *first_value), (1, "a"));
1.0.0 · Sourcepub fn keys(&self) -> Keys<'_, K, V>
pub fn keys(&self) -> Keys<'_, K, V>
Gets an iterator over the keys of the map, in sorted order.
§Examples
use std::collections::BTreeMap;
let mut a = BTreeMap::new();
a.insert(2, "b");
a.insert(1, "a");
let keys: Vec<_> = a.keys().cloned().collect();
assert_eq!(keys, [1, 2]);
1.0.0 · Sourcepub fn values(&self) -> Values<'_, K, V>
pub fn values(&self) -> Values<'_, K, V>
Gets an iterator over the values of the map, in order by key.
§Examples
use std::collections::BTreeMap;
let mut a = BTreeMap::new();
a.insert(1, "hello");
a.insert(2, "goodbye");
let values: Vec<&str> = a.values().cloned().collect();
assert_eq!(values, ["hello", "goodbye"]);
1.0.0 · Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the number of elements in the map.
§Examples
use std::collections::BTreeMap;
let mut a = BTreeMap::new();
assert_eq!(a.len(), 0);
a.insert(1, "a");
assert_eq!(a.len(), 1);
1.0.0 · Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true
if the map contains no elements.
§Examples
use std::collections::BTreeMap;
let mut a = BTreeMap::new();
assert!(a.is_empty());
a.insert(1, "a");
assert!(!a.is_empty());
Sourcepub fn lower_bound<Q>(&self, bound: Bound<&Q>) -> Cursor<'_, K, V>
🔬This is a nightly-only experimental API. (btree_cursors
)
pub fn lower_bound<Q>(&self, bound: Bound<&Q>) -> Cursor<'_, K, V>
btree_cursors
)Returns a Cursor
pointing at the gap before the smallest key
greater than the given bound.
Passing Bound::Included(x)
will return a cursor pointing to the
gap before the smallest key greater than or equal to x
.
Passing Bound::Excluded(x)
will return a cursor pointing to the
gap before the smallest key greater than x
.
Passing Bound::Unbounded
will return a cursor pointing to the
gap before the smallest key in the map.
§Examples
#![feature(btree_cursors)]
use std::collections::BTreeMap;
use std::ops::Bound;
let map = BTreeMap::from([
(1, "a"),
(2, "b"),
(3, "c"),
(4, "d"),
]);
let cursor = map.lower_bound(Bound::Included(&2));
assert_eq!(cursor.peek_prev(), Some((&1, &"a")));
assert_eq!(cursor.peek_next(), Some((&2, &"b")));
let cursor = map.lower_bound(Bound::Excluded(&2));
assert_eq!(cursor.peek_prev(), Some((&2, &"b")));
assert_eq!(cursor.peek_next(), Some((&3, &"c")));
let cursor = map.lower_bound(Bound::Unbounded);
assert_eq!(cursor.peek_prev(), None);
assert_eq!(cursor.peek_next(), Some((&1, &"a")));
Sourcepub fn upper_bound<Q>(&self, bound: Bound<&Q>) -> Cursor<'_, K, V>
🔬This is a nightly-only experimental API. (btree_cursors
)
pub fn upper_bound<Q>(&self, bound: Bound<&Q>) -> Cursor<'_, K, V>
btree_cursors
)Returns a Cursor
pointing at the gap after the greatest key
smaller than the given bound.
Passing Bound::Included(x)
will return a cursor pointing to the
gap after the greatest key smaller than or equal to x
.
Passing Bound::Excluded(x)
will return a cursor pointing to the
gap after the greatest key smaller than x
.
Passing Bound::Unbounded
will return a cursor pointing to the
gap after the greatest key in the map.
§Examples
#![feature(btree_cursors)]
use std::collections::BTreeMap;
use std::ops::Bound;
let map = BTreeMap::from([
(1, "a"),
(2, "b"),
(3, "c"),
(4, "d"),
]);
let cursor = map.upper_bound(Bound::Included(&3));
assert_eq!(cursor.peek_prev(), Some((&3, &"c")));
assert_eq!(cursor.peek_next(), Some((&4, &"d")));
let cursor = map.upper_bound(Bound::Excluded(&3));
assert_eq!(cursor.peek_prev(), Some((&2, &"b")));
assert_eq!(cursor.peek_next(), Some((&3, &"c")));
let cursor = map.upper_bound(Bound::Unbounded);
assert_eq!(cursor.peek_prev(), Some((&4, &"d")));
assert_eq!(cursor.peek_next(), None);
Trait Implementations§
Auto Trait Implementations§
impl<T> Freeze for XvcStore<T>
impl<T> RefUnwindSafe for XvcStore<T>where
T: RefUnwindSafe,
impl<T> Send for XvcStore<T>where
T: Send,
impl<T> Sync for XvcStore<T>where
T: Sync,
impl<T> Unpin for XvcStore<T>where
T: Unpin,
impl<T> UnwindSafe for XvcStore<T>where
T: RefUnwindSafe + UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more