simple_triplestore/mem/
iter.rs

1use std::collections::BTreeMap;
2
3use crate::{
4    prelude::*,
5    traits::{IdType, Property},
6    EdgeOrder, PropsTriple, Triple,
7};
8
9use super::MemTripleStore;
10
11impl<Id: IdType, NodeProps: Property, EdgeProps: Property>
12    MemTripleStore<Id, NodeProps, EdgeProps>
13{
14    fn iter_impl(
15        node_props: &BTreeMap<Id, NodeProps>,
16        edge_props: &BTreeMap<Id, EdgeProps>,
17        triple: Triple<Id>,
18        v: &Id,
19    ) -> Option<Result<PropsTriple<Id, NodeProps, EdgeProps>, ()>> {
20        let sub_data = node_props.get(&triple.sub).cloned();
21        let pred_data = edge_props.get(v).cloned();
22        let obj_data = node_props.get(&triple.obj).cloned();
23
24        match (sub_data, pred_data, obj_data) {
25            (Some(sub_props), Some(prod_props), Some(obj_props)) => Some(Ok(PropsTriple {
26                sub: (triple.sub, sub_props),
27                pred: (triple.pred, prod_props),
28                obj: (triple.obj, obj_props),
29            })),
30            _ => None,
31        }
32    }
33}
34
35impl<Id: IdType, NodeProps: Property, EdgeProps: Property> TripleStoreIter<Id, NodeProps, EdgeProps>
36    for MemTripleStore<Id, NodeProps, EdgeProps>
37{
38    fn vertices(&self) -> Result<impl Iterator<Item = Id>, Self::Error> {
39        Ok(self.node_props.iter().map(|e| e.0.clone()))
40    }
41
42    fn iter_nodes(
43        &self,
44        order: EdgeOrder,
45    ) -> (
46        impl Iterator<Item = Result<(Id, NodeProps), Self::Error>>,
47        impl Iterator<Item = Result<(Triple<Id>, EdgeProps), Self::Error>>,
48    ) {
49        (self.iter_vertices(), self.iter_edges(order))
50    }
51
52    fn iter_vertices<'a>(&'a self) -> impl Iterator<Item = Result<(Id, NodeProps), ()>> + 'a {
53        self.node_props
54            .iter()
55            .map(|(id, props)| Ok((id.clone(), props.clone())))
56    }
57
58    fn iter_edges_with_props<'a>(
59        &'a self,
60        order: EdgeOrder,
61    ) -> impl Iterator<Item = Result<PropsTriple<Id, NodeProps, EdgeProps>, ()>> + 'a {
62        let edges: Box<dyn Iterator<Item = _>> = match order {
63            EdgeOrder::SPO => Box::new(
64                self.spo_data
65                    .iter()
66                    .map(|(k, v)| (Id::decode_spo_triple(k), v)),
67            ),
68            EdgeOrder::POS => Box::new(
69                self.pos_data
70                    .iter()
71                    .map(|(k, v)| (Id::decode_pos_triple(k), v)),
72            ),
73            EdgeOrder::OSP => Box::new(
74                self.osp_data
75                    .iter()
76                    .map(|(k, v)| (Id::decode_osp_triple(k), v)),
77            ),
78        };
79
80        edges.filter_map(|(k, v)| {
81            MemTripleStore::iter_impl(&self.node_props, &self.edge_props, k, &v)
82        })
83    }
84
85    fn iter_edges<'a>(
86        &'a self,
87        order: EdgeOrder,
88    ) -> impl Iterator<Item = Result<(Triple<Id>, EdgeProps), ()>> + 'a {
89        let edges: Box<dyn Iterator<Item = _>> = match order {
90            EdgeOrder::SPO => Box::new(
91                self.spo_data
92                    .iter()
93                    .map(|(k, v)| (Id::decode_spo_triple(k), v)),
94            ),
95            EdgeOrder::POS => Box::new(
96                self.pos_data
97                    .iter()
98                    .map(|(k, v)| (Id::decode_pos_triple(k), v)),
99            ),
100            EdgeOrder::OSP => Box::new(
101                self.osp_data
102                    .iter()
103                    .map(|(k, v)| (Id::decode_osp_triple(k), v)),
104            ),
105        };
106
107        edges.filter_map(|(k, v)| match self.edge_props.get(&v) {
108            Some(v) => Some(Ok((k, v.clone()))),
109            None => None,
110        })
111    }
112}
113
114impl<Id: IdType, NodeProps: Property + PartialEq, EdgeProps: Property + PartialEq>
115    TripleStoreIntoIter<Id, NodeProps, EdgeProps> for MemTripleStore<Id, NodeProps, EdgeProps>
116{
117    fn into_iter_nodes(
118        self,
119        order: EdgeOrder,
120    ) -> (
121        impl Iterator<Item = Result<(Id, NodeProps), Self::Error>>,
122        impl Iterator<Item = Result<(Triple<Id>, EdgeProps), Self::Error>>,
123    ) {
124        let node_iter = self.node_props.into_iter().map(|o| Ok(o));
125        let edge_iter = {
126            let edges: Box<dyn Iterator<Item = _>> = match order {
127                EdgeOrder::SPO => Box::new(
128                    self.spo_data
129                        .into_iter()
130                        .map(|(k, v)| (Id::decode_spo_triple(&k), v)),
131                ),
132                EdgeOrder::POS => Box::new(
133                    self.pos_data
134                        .into_iter()
135                        .map(|(k, v)| (Id::decode_pos_triple(&k), v)),
136                ),
137                EdgeOrder::OSP => Box::new(
138                    self.osp_data
139                        .into_iter()
140                        .map(|(k, v)| (Id::decode_osp_triple(&k), v)),
141                ),
142            };
143
144            edges.filter_map(
145                move |(k, v): (Triple<Id>, Id)| match self.edge_props.get(&v) {
146                    Some(v) => Some(Ok((k, v.clone()))),
147                    None => None,
148                },
149            )
150        };
151        (node_iter, edge_iter)
152    }
153
154    fn into_iter_vertices(self) -> impl Iterator<Item = Result<(Id, NodeProps), ()>> {
155        self.node_props.into_iter().map(|o| Ok(o))
156    }
157
158    fn into_iter_edges_with_props(
159        self,
160        order: EdgeOrder,
161    ) -> impl Iterator<Item = Result<PropsTriple<Id, NodeProps, EdgeProps>, ()>> {
162        let edges: Box<dyn Iterator<Item = _>> = match order {
163            EdgeOrder::SPO => Box::new(
164                self.spo_data
165                    .into_iter()
166                    .map(|(k, v)| (Id::decode_spo_triple(&k), v)),
167            ),
168            EdgeOrder::POS => Box::new(
169                self.pos_data
170                    .into_iter()
171                    .map(|(k, v)| (Id::decode_pos_triple(&k), v)),
172            ),
173            EdgeOrder::OSP => Box::new(
174                self.osp_data
175                    .into_iter()
176                    .map(|(k, v)| (Id::decode_osp_triple(&k), v)),
177            ),
178        };
179
180        edges.filter_map(move |(k, v): (Triple<Id>, Id)| {
181            MemTripleStore::iter_impl(&self.node_props, &self.edge_props, k, &v)
182        })
183    }
184
185    fn into_iter_edges(
186        self,
187        order: EdgeOrder,
188    ) -> impl Iterator<Item = Result<(Triple<Id>, EdgeProps), ()>> {
189        let edges: Box<dyn Iterator<Item = _>> = match order {
190            EdgeOrder::SPO => Box::new(
191                self.spo_data
192                    .into_iter()
193                    .map(|(k, v)| (Id::decode_spo_triple(&k), v)),
194            ),
195            EdgeOrder::POS => Box::new(
196                self.pos_data
197                    .into_iter()
198                    .map(|(k, v)| (Id::decode_pos_triple(&k), v)),
199            ),
200            EdgeOrder::OSP => Box::new(
201                self.osp_data
202                    .into_iter()
203                    .map(|(k, v)| (Id::decode_osp_triple(&k), v)),
204            ),
205        };
206
207        edges.filter_map(move |(k, v)| match self.edge_props.get(&v) {
208            Some(v) => Some(Ok((k, v.clone()))),
209            None => None,
210        })
211    }
212}
213
214#[cfg(test)]
215mod test {
216    use crate::{MemTripleStore, UlidIdGenerator};
217
218    #[test]
219    fn test_iter_spo() {
220        let db = MemTripleStore::new(UlidIdGenerator::new());
221        crate::conformance::iter::test_iter_spo(db);
222    }
223
224    #[test]
225    fn test_iter_pos() {
226        let db = MemTripleStore::new(UlidIdGenerator::new());
227        crate::conformance::iter::test_iter_pos(db);
228    }
229
230    #[test]
231    fn test_iter_osp() {
232        let db = MemTripleStore::new(UlidIdGenerator::new());
233        crate::conformance::iter::test_iter_osp(db);
234    }
235
236    #[test]
237    fn test_iter_edge_spo() {
238        let db = MemTripleStore::new(UlidIdGenerator::new());
239        crate::conformance::iter::test_iter_edge_spo(db);
240    }
241
242    #[test]
243    fn test_iter_edge_pos() {
244        let db = MemTripleStore::new(UlidIdGenerator::new());
245        crate::conformance::iter::test_iter_edge_pos(db);
246    }
247
248    #[test]
249    fn test_iter_edge_osp() {
250        let db = MemTripleStore::new(UlidIdGenerator::new());
251        crate::conformance::iter::test_iter_edge_osp(db);
252    }
253
254    #[test]
255    fn test_iter_node() {
256        let db = MemTripleStore::new(UlidIdGenerator::new());
257        crate::conformance::iter::test_iter_node(db);
258    }
259
260    #[test]
261    fn test_into_iter_spo() {
262        let db = MemTripleStore::new(UlidIdGenerator::new());
263        crate::conformance::iter::test_into_iter_spo(db);
264    }
265
266    #[test]
267    fn test_into_iter_pos() {
268        let db = MemTripleStore::new(UlidIdGenerator::new());
269        crate::conformance::iter::test_into_iter_pos(db);
270    }
271
272    #[test]
273    fn test_into_iter_osp() {
274        let db = MemTripleStore::new(UlidIdGenerator::new());
275        crate::conformance::iter::test_into_iter_osp(db);
276    }
277
278    #[test]
279    fn test_into_iter_edge_spo() {
280        let db = MemTripleStore::new(UlidIdGenerator::new());
281        crate::conformance::iter::test_into_iter_edge_spo(db);
282    }
283
284    #[test]
285    fn test_into_iter_edge_pos() {
286        let db = MemTripleStore::new(UlidIdGenerator::new());
287        crate::conformance::iter::test_into_iter_edge_pos(db);
288    }
289
290    #[test]
291    fn test_into_iter_edge_osp() {
292        let db = MemTripleStore::new(UlidIdGenerator::new());
293        crate::conformance::iter::test_into_iter_edge_osp(db);
294    }
295
296    #[test]
297    fn test_into_iter_node() {
298        let db = MemTripleStore::new(UlidIdGenerator::new());
299        crate::conformance::iter::test_into_iter_node(db);
300    }
301}