1use super::event::{Event, EventLog};
4use super::hstore::HStore;
5use crate::error::{Error, Result};
6use crate::XvcEntity;
7use crate::{Storable, XvcStore};
8use serde::{Deserialize, Serialize};
9
10use std::collections::HashMap;
11
12use std::fmt::Debug;
13use std::iter::FromIterator;
14use std::ops::Deref;
15use std::path::{Path, PathBuf};
16
17#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
19#[serde(bound = "T: Serialize, for<'lt> T: Deserialize<'lt>")]
20pub struct VStore<T>
21where
22 T: Storable,
23{
24 vec: Vec<(XvcEntity, T)>,
25 previous: EventLog<T>,
26 current: EventLog<T>,
27}
28
29impl<T> Default for VStore<T>
30where
31 T: Storable,
32{
33 fn default() -> Self {
34 Self::new()
35 }
36}
37
38impl<T> VStore<T>
39where
40 T: Storable,
41{
42 pub fn new() -> Self {
44 Self {
45 vec: Vec::<(XvcEntity, T)>::new(),
46 current: EventLog::new(),
47 previous: EventLog::new(),
48 }
49 }
50
51 pub fn with_capacity(capacity: usize) -> Self {
53 Self {
54 vec: Vec::<(XvcEntity, T)>::with_capacity(capacity),
55 current: EventLog::new(),
57 previous: EventLog::new(),
58 }
59 }
60
61 fn build_vec(events: &EventLog<T>) -> Vec<(XvcEntity, T)> {
62 let mut map = HashMap::<XvcEntity, T>::new();
63
64 for event in events.iter() {
65 match event {
66 Event::Add { entity, value } => map.insert(*entity, value.clone()),
67 Event::Remove { entity } => map.remove(entity),
68 };
69 }
70
71 Vec::from_iter(map)
72 }
73
74 pub fn from_dir(dir: &Path) -> Result<Self> {
77 let previous = EventLog::<T>::from_dir(dir)?;
78 let vec = Self::build_vec(&previous);
79
80 Ok(Self {
81 vec,
82 previous,
83 current: EventLog::new(),
84 })
85 }
86
87 pub fn to_dir(&self, dir: &Path) -> Result<()> {
90 self.current.to_dir(dir)
91 }
92
93 pub fn values_of(&self, parent: &XvcEntity) -> Vec<T> {
100 self.vec
101 .iter()
102 .filter_map(|(e, v)| if *e == *parent { Some(v.clone()) } else { None })
103 .collect()
104 }
105
106 pub fn insert(&mut self, entity: XvcEntity, value: T) {
109 self.current.push_event(Event::Add {
110 entity,
111 value: value.clone(),
112 });
113 self.vec.push((entity, value))
114 }
115
116 pub fn to_store(&self) -> Result<XvcStore<T>> {
120 let store = XvcStore::from_event_logs(self.previous.clone(), self.current.clone());
121 Ok(store)
122 }
123}
124
125impl<T> Deref for VStore<T>
126where
127 T: Storable,
128{
129 type Target = Vec<(XvcEntity, T)>;
130
131 fn deref(&self) -> &Self::Target {
132 &self.vec
133 }
134}
135
136impl<T> From<HStore<T>> for VStore<T>
137where
138 T: Storable,
139{
140 fn from(store: HStore<T>) -> Self {
141 match store.to_vstore() {
142 Ok(vs) => vs,
143 Err(_) => {
144 Error::StoreConversionError.error();
145 Self::new()
146 }
147 }
148 }
149}
150
151impl<T> FromIterator<(XvcEntity, T)> for VStore<T>
152where
153 T: Storable,
154{
155 fn from_iter<I: IntoIterator<Item = (XvcEntity, T)>>(iter: I) -> Self {
156 let mut s = Self::new();
157 for (e, v) in iter {
158 s.insert(e, v.clone());
159 }
160 s
161 }
162}
163
164impl<T> VStore<T>
165where
166 T: Storable,
167{
168 fn vstore_path(store_root: &Path) -> PathBuf {
169 store_root.join(format!("{}-vstore", <T as Storable>::type_description()))
170 }
171
172 pub fn load_vstore(store_root: &Path) -> Result<VStore<T>> {
175 let dir = Self::vstore_path(store_root);
176 VStore::<T>::from_dir(&dir)
177 }
178
179 pub fn save_vstore(&self, store_root: &Path) -> Result<()> {
182 let dir = Self::vstore_path(store_root);
183 self.to_dir(&dir)
184 }
185}
186
187#[cfg(test)]
188mod test {
189 use super::*;
190
191 #[test]
192 fn new() -> Result<()> {
193 let mut store = VStore::<String>::new();
194 store.insert((0, 12398012938).into(), "0".into());
195 store.insert((1, 12398012938).into(), "1".into());
196 assert_eq!(store.len(), 2);
197
198 assert_eq!(store.vec.pop().unwrap().1, "1".to_string());
199 assert_eq!(store.vec.pop().unwrap().1, "0".to_string());
200 Ok(())
201 }
202}