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}