simple_triplestore/sled/
iter.rs

1use serde::{de::DeserializeOwned, Serialize};
2use sled::IVec;
3
4use crate::{prelude::*, traits::IdType, traits::Property};
5use crate::{EdgeOrder, PropsTriple, Triple};
6
7use super::SledTripleStore;
8use super::SledTripleStoreError;
9
10fn decode_id<Id: IdType>(id: IVec) -> Result<Id, SledTripleStoreError> {
11    Id::try_from_be_bytes(id.as_ref()).ok_or(SledTripleStoreError::KeySizeError)
12}
13
14impl<
15        Id: IdType,
16        NodeProps: Property + Serialize + DeserializeOwned,
17        EdgeProps: Property + Serialize + DeserializeOwned,
18    > SledTripleStore<Id, NodeProps, EdgeProps>
19{
20    fn get_node_data_internal(
21        &self,
22        id: &Id::ByteArrayType,
23    ) -> Result<Option<NodeProps>, SledTripleStoreError> {
24        self.node_props
25            .get(id)
26            .map_err(|e| SledTripleStoreError::SledError(e))?
27            .map(|data| {
28                bincode::deserialize(&data).map_err(|e| SledTripleStoreError::SerializationError(e))
29            })
30            .transpose()
31    }
32
33    fn get_node_data_by_id(&self, id: &Id) -> Result<Option<NodeProps>, SledTripleStoreError> {
34        self.get_node_data_internal(&id.to_be_bytes())
35    }
36
37    fn get_edge_data_internal(
38        &self,
39        id: &sled::IVec,
40    ) -> Result<Option<EdgeProps>, SledTripleStoreError> {
41        self.edge_props
42            .get(id)
43            .map_err(|e| SledTripleStoreError::SledError(e))?
44            .map(|data| {
45                bincode::deserialize(&data).map_err(|e| SledTripleStoreError::SerializationError(e))
46            })
47            .transpose()
48    }
49
50    fn iter_impl(
51        &self,
52        triple: Triple<Id>,
53        v: IVec,
54    ) -> Result<PropsTriple<Id, NodeProps, EdgeProps>, SledTripleStoreError> {
55        match (
56            self.get_node_data_by_id(&triple.sub)?,
57            self.get_edge_data_internal(&v)?,
58            self.get_node_data_by_id(&triple.obj)?,
59        ) {
60            (Some(sub_props), Some(prod_props), Some(obj_props)) => Ok(PropsTriple {
61                sub: (triple.sub, sub_props),
62                pred: (triple.pred, prod_props),
63                obj: (triple.obj, obj_props),
64            }),
65            _ => Err(SledTripleStoreError::MissingPropertyData),
66        }
67    }
68}
69impl<
70        Id: IdType,
71        NodeProps: Property + Serialize + DeserializeOwned,
72        EdgeProps: Property + Serialize + DeserializeOwned,
73    > TripleStoreIter<Id, NodeProps, EdgeProps> for SledTripleStore<Id, NodeProps, EdgeProps>
74{
75    fn vertices(&self) -> Result<impl Iterator<Item = Id>, Self::Error> {
76        self.node_props
77            .iter()
78            .map(|r| match r {
79                Ok((k, _)) => {
80                    let k = decode_id(k)?;
81                    Ok(k)
82                }
83                Err(e) => Err(SledTripleStoreError::SledError(e)),
84            })
85            .collect::<Result<Vec<_>, _>>()
86            .map(|v| v.into_iter())
87    }
88
89    fn iter_nodes(
90        &self,
91        order: EdgeOrder,
92    ) -> (
93        impl Iterator<Item = Result<(Id, NodeProps), Self::Error>>,
94        impl Iterator<Item = Result<(Triple<Id>, EdgeProps), Self::Error>>,
95    ) {
96        (self.iter_vertices(), self.iter_edges(order))
97    }
98
99    fn iter_vertices<'a>(
100        &'a self,
101    ) -> impl Iterator<Item = Result<(Id, NodeProps), SledTripleStoreError>> {
102        self.node_props.iter().map(|r| match r {
103            Ok((k, v)) => {
104                let k = decode_id(k)?;
105                let v = bincode::deserialize(&v)
106                    .map_err(|e| SledTripleStoreError::SerializationError(e))?;
107                Ok((k, v))
108            }
109            Err(e) => Err(SledTripleStoreError::SledError(e)),
110        })
111    }
112
113    fn iter_edges_with_props<'a>(
114        &'a self,
115        order: EdgeOrder,
116    ) -> impl Iterator<Item = Result<PropsTriple<Id, NodeProps, EdgeProps>, SledTripleStoreError>> + 'a
117    {
118        let edges: Box<dyn Iterator<Item = _>> = match order {
119            EdgeOrder::SPO => Box::new(self.spo_data.iter().map(|r| {
120                r.map_err(|e| SledTripleStoreError::SledError(e))
121                    .and_then(|(k, v)| {
122                        Ok((
123                            Id::decode_spo_triple(
124                                &k[..]
125                                    .try_into()
126                                    .map_err(|_| SledTripleStoreError::KeySizeError)?,
127                            ),
128                            v,
129                        ))
130                    })
131            })),
132            EdgeOrder::POS => Box::new(self.pos_data.iter().map(|r| {
133                r.map_err(|e| SledTripleStoreError::SledError(e))
134                    .and_then(|(k, v)| {
135                        Ok((
136                            Id::decode_pos_triple(
137                                &k[..]
138                                    .try_into()
139                                    .map_err(|_| SledTripleStoreError::KeySizeError)?,
140                            ),
141                            v,
142                        ))
143                    })
144            })),
145            EdgeOrder::OSP => Box::new(self.osp_data.iter().map(|r| {
146                r.map_err(|e| SledTripleStoreError::SledError(e))
147                    .and_then(|(k, v)| {
148                        Ok((
149                            Id::decode_osp_triple(
150                                &k[..]
151                                    .try_into()
152                                    .map_err(|_| SledTripleStoreError::KeySizeError)?,
153                            ),
154                            v,
155                        ))
156                    })
157            })),
158        };
159        edges.map(|r| r.and_then(|(k, v)| self.iter_impl(k, v)))
160    }
161
162    fn iter_edges<'a>(
163        &'a self,
164        order: EdgeOrder,
165    ) -> impl Iterator<Item = Result<(Triple<Id>, EdgeProps), SledTripleStoreError>> + 'a {
166        let edges: Box<dyn Iterator<Item = _>> = match order {
167            EdgeOrder::SPO => Box::new(self.spo_data.iter().map(|r| {
168                r.map_err(|e| SledTripleStoreError::SledError(e))
169                    .and_then(|(k, v)| {
170                        Ok((
171                            Id::decode_spo_triple(
172                                &k[..]
173                                    .try_into()
174                                    .map_err(|_| SledTripleStoreError::KeySizeError)?,
175                            ),
176                            v,
177                        ))
178                    })
179            })),
180            EdgeOrder::POS => Box::new(self.pos_data.iter().map(|r| {
181                r.map_err(|e| SledTripleStoreError::SledError(e))
182                    .and_then(|(k, v)| {
183                        Ok((
184                            Id::decode_pos_triple(
185                                &k[..]
186                                    .try_into()
187                                    .map_err(|_| SledTripleStoreError::KeySizeError)?,
188                            ),
189                            v,
190                        ))
191                    })
192            })),
193            EdgeOrder::OSP => Box::new(self.osp_data.iter().map(|r| {
194                r.map_err(|e| SledTripleStoreError::SledError(e))
195                    .and_then(|(k, v)| {
196                        Ok((
197                            Id::decode_osp_triple(
198                                &k[..]
199                                    .try_into()
200                                    .map_err(|_| SledTripleStoreError::KeySizeError)?,
201                            ),
202                            v,
203                        ))
204                    })
205            })),
206        };
207
208        edges.map(|r| {
209            r.and_then(|(k, v)| {
210                if let Some(pred_data) = self.get_edge_data_internal(&v)? {
211                    Ok((k, pred_data))
212                } else {
213                    Err(SledTripleStoreError::MissingPropertyData)
214                }
215            })
216        })
217    }
218}
219
220impl<
221        Id: IdType,
222        NodeProps: Property + Serialize + DeserializeOwned,
223        EdgeProps: Property + Serialize + DeserializeOwned,
224    > TripleStoreIntoIter<Id, NodeProps, EdgeProps> for SledTripleStore<Id, NodeProps, EdgeProps>
225{
226    fn into_iter_nodes(
227        self,
228        order: EdgeOrder,
229    ) -> (
230        impl Iterator<Item = Result<(Id, NodeProps), Self::Error>>,
231        impl Iterator<Item = Result<(Triple<Id>, EdgeProps), Self::Error>>,
232    ) {
233        let node_iter = self.node_props.into_iter().map(|r| match r {
234            Ok((k, v)) => {
235                let k = decode_id(k)?;
236                let v = bincode::deserialize(&v)
237                    .map_err(|e| SledTripleStoreError::SerializationError(e))?;
238                Ok((k, v))
239            }
240            Err(e) => Err(SledTripleStoreError::SledError(e)),
241        });
242
243        let edges: Box<dyn Iterator<Item = _>> = match order {
244            EdgeOrder::SPO => Box::new(self.spo_data.iter().map(|r| {
245                r.map_err(|e| SledTripleStoreError::SledError(e))
246                    .and_then(|(k, v)| {
247                        Ok((
248                            Id::decode_spo_triple(
249                                &k[..]
250                                    .try_into()
251                                    .map_err(|_| SledTripleStoreError::KeySizeError)?,
252                            ),
253                            v,
254                        ))
255                    })
256            })),
257            EdgeOrder::POS => Box::new(self.pos_data.iter().map(|r| {
258                r.map_err(|e| SledTripleStoreError::SledError(e))
259                    .and_then(|(k, v)| {
260                        Ok((
261                            Id::decode_pos_triple(
262                                &k[..]
263                                    .try_into()
264                                    .map_err(|_| SledTripleStoreError::KeySizeError)?,
265                            ),
266                            v,
267                        ))
268                    })
269            })),
270            EdgeOrder::OSP => Box::new(self.osp_data.iter().map(|r| {
271                r.map_err(|e| SledTripleStoreError::SledError(e))
272                    .and_then(|(k, v)| {
273                        Ok((
274                            Id::decode_osp_triple(
275                                &k[..]
276                                    .try_into()
277                                    .map_err(|_| SledTripleStoreError::KeySizeError)?,
278                            ),
279                            v,
280                        ))
281                    })
282            })),
283        };
284
285        let edge_iter = edges.map(move |r| {
286            r.and_then(|(k, v)| {
287                let pred_data = self
288                    .edge_props
289                    .get(v)
290                    .map_err(|e| SledTripleStoreError::SledError(e))?
291                    .map(|data| {
292                        bincode::deserialize(&data)
293                            .map_err(|e| SledTripleStoreError::SerializationError(e))
294                    })
295                    .transpose();
296
297                if let Some(pred_data) = pred_data? {
298                    Ok((k, pred_data))
299                } else {
300                    Err(SledTripleStoreError::MissingPropertyData)
301                }
302            })
303        });
304        (node_iter, edge_iter)
305    }
306
307    fn into_iter_vertices(self) -> impl Iterator<Item = Result<(Id, NodeProps), Self::Error>> {
308        self.node_props.into_iter().map(|r| match r {
309            Ok((k, v)) => {
310                let k = decode_id(k)?;
311                let v = bincode::deserialize(&v)
312                    .map_err(|e| SledTripleStoreError::SerializationError(e))?;
313                Ok((k, v))
314            }
315            Err(e) => Err(SledTripleStoreError::SledError(e)),
316        })
317    }
318
319    fn into_iter_edges_with_props(
320        self,
321        order: EdgeOrder,
322    ) -> impl Iterator<Item = Result<PropsTriple<Id, NodeProps, EdgeProps>, Self::Error>> {
323        let edges: Box<dyn Iterator<Item = _>> = match order {
324            EdgeOrder::SPO => Box::new(self.spo_data.into_iter().map(|r| {
325                r.map_err(|e| SledTripleStoreError::SledError(e))
326                    .and_then(|(k, v)| {
327                        Ok((
328                            Id::decode_spo_triple(
329                                &k[..]
330                                    .try_into()
331                                    .map_err(|_| SledTripleStoreError::KeySizeError)?,
332                            ),
333                            v,
334                        ))
335                    })
336            })),
337            EdgeOrder::POS => Box::new(self.pos_data.into_iter().map(|r| {
338                r.map_err(|e| SledTripleStoreError::SledError(e))
339                    .and_then(|(k, v)| {
340                        Ok((
341                            Id::decode_pos_triple(
342                                &k[..]
343                                    .try_into()
344                                    .map_err(|_| SledTripleStoreError::KeySizeError)?,
345                            ),
346                            v,
347                        ))
348                    })
349            })),
350            EdgeOrder::OSP => Box::new(self.osp_data.into_iter().map(|r| {
351                r.map_err(|e| SledTripleStoreError::SledError(e))
352                    .and_then(|(k, v)| {
353                        Ok((
354                            Id::decode_osp_triple(
355                                &k[..]
356                                    .try_into()
357                                    .map_err(|_| SledTripleStoreError::KeySizeError)?,
358                            ),
359                            v,
360                        ))
361                    })
362            })),
363        };
364        edges.map(move |r| r.and_then(|(k, v)| self.iter_impl(k, v)))
365    }
366
367    fn into_iter_edges(
368        self,
369        order: EdgeOrder,
370    ) -> impl Iterator<Item = Result<(Triple<Id>, EdgeProps), Self::Error>> {
371        let edges: Box<dyn Iterator<Item = _>> = match order {
372            EdgeOrder::SPO => Box::new(self.spo_data.iter().map(|r| {
373                r.map_err(|e| SledTripleStoreError::SledError(e))
374                    .and_then(|(k, v)| {
375                        Ok((
376                            Id::decode_spo_triple(
377                                &k[..]
378                                    .try_into()
379                                    .map_err(|_| SledTripleStoreError::KeySizeError)?,
380                            ),
381                            v,
382                        ))
383                    })
384            })),
385            EdgeOrder::POS => Box::new(self.pos_data.iter().map(|r| {
386                r.map_err(|e| SledTripleStoreError::SledError(e))
387                    .and_then(|(k, v)| {
388                        Ok((
389                            Id::decode_pos_triple(
390                                &k[..]
391                                    .try_into()
392                                    .map_err(|_| SledTripleStoreError::KeySizeError)?,
393                            ),
394                            v,
395                        ))
396                    })
397            })),
398            EdgeOrder::OSP => Box::new(self.osp_data.iter().map(|r| {
399                r.map_err(|e| SledTripleStoreError::SledError(e))
400                    .and_then(|(k, v)| {
401                        Ok((
402                            Id::decode_osp_triple(
403                                &k[..]
404                                    .try_into()
405                                    .map_err(|_| SledTripleStoreError::KeySizeError)?,
406                            ),
407                            v,
408                        ))
409                    })
410            })),
411        };
412
413        edges.map(move |r| {
414            r.and_then(|(k, v)| {
415                if let Some(pred_data) = self.get_edge_data_internal(&v)? {
416                    Ok((k, pred_data))
417                } else {
418                    Err(SledTripleStoreError::MissingPropertyData)
419                }
420            })
421        })
422    }
423}
424
425#[cfg(test)]
426mod test {
427    use crate::{SledTripleStore, UlidIdGenerator};
428
429    #[test]
430    fn test_iter_spo() {
431        let (_tempdir, db) = crate::sled::create_test_db().expect("ok");
432        let sled_db = SledTripleStore::new(&db, UlidIdGenerator::new()).expect("ok");
433        crate::conformance::iter::test_iter_spo(sled_db);
434    }
435
436    #[test]
437    fn test_iter_pos() {
438        let (_tempdir, db) = crate::sled::create_test_db().expect("ok");
439        let sled_db = SledTripleStore::new(&db, UlidIdGenerator::new()).expect("ok");
440        crate::conformance::iter::test_iter_pos(sled_db);
441    }
442
443    #[test]
444    fn test_iter_osp() {
445        let (_tempdir, db) = crate::sled::create_test_db().expect("ok");
446        let sled_db = SledTripleStore::new(&db, UlidIdGenerator::new()).expect("ok");
447        crate::conformance::iter::test_iter_osp(sled_db);
448    }
449
450    #[test]
451    fn test_iter_edge_spo() {
452        let (_tempdir, db) = crate::sled::create_test_db().expect("ok");
453        let sled_db = SledTripleStore::new(&db, UlidIdGenerator::new()).expect("ok");
454        crate::conformance::iter::test_iter_edge_spo(sled_db);
455    }
456
457    #[test]
458    fn test_iter_edge_pos() {
459        let (_tempdir, db) = crate::sled::create_test_db().expect("ok");
460        let sled_db = SledTripleStore::new(&db, UlidIdGenerator::new()).expect("ok");
461        crate::conformance::iter::test_iter_edge_pos(sled_db);
462    }
463
464    #[test]
465    fn test_iter_edge_osp() {
466        let (_tempdir, db) = crate::sled::create_test_db().expect("ok");
467        let sled_db = SledTripleStore::new(&db, UlidIdGenerator::new()).expect("ok");
468        crate::conformance::iter::test_iter_edge_osp(sled_db);
469    }
470
471    #[test]
472    fn test_iter_node() {
473        let (_tempdir, db) = crate::sled::create_test_db().expect("ok");
474        let sled_db = SledTripleStore::new(&db, UlidIdGenerator::new()).expect("ok");
475        crate::conformance::iter::test_iter_node(sled_db);
476    }
477
478    #[test]
479    fn test_into_iter_spo() {
480        let (_tempdir, db) = crate::sled::create_test_db().expect("ok");
481        let sled_db = SledTripleStore::new(&db, UlidIdGenerator::new()).expect("ok");
482        crate::conformance::iter::test_into_iter_spo(sled_db);
483    }
484
485    #[test]
486    fn test_into_iter_pos() {
487        let (_tempdir, db) = crate::sled::create_test_db().expect("ok");
488        let sled_db = SledTripleStore::new(&db, UlidIdGenerator::new()).expect("ok");
489        crate::conformance::iter::test_into_iter_pos(sled_db);
490    }
491
492    #[test]
493    fn test_into_iter_osp() {
494        let (_tempdir, db) = crate::sled::create_test_db().expect("ok");
495        let sled_db = SledTripleStore::new(&db, UlidIdGenerator::new()).expect("ok");
496        crate::conformance::iter::test_into_iter_osp(sled_db);
497    }
498
499    #[test]
500    fn test_into_iter_edge_spo() {
501        let (_tempdir, db) = crate::sled::create_test_db().expect("ok");
502        let sled_db = SledTripleStore::new(&db, UlidIdGenerator::new()).expect("ok");
503        crate::conformance::iter::test_into_iter_edge_spo(sled_db);
504    }
505
506    #[test]
507    fn test_into_iter_edge_pos() {
508        let (_tempdir, db) = crate::sled::create_test_db().expect("ok");
509        let sled_db = SledTripleStore::new(&db, UlidIdGenerator::new()).expect("ok");
510        crate::conformance::iter::test_into_iter_edge_pos(sled_db);
511    }
512
513    #[test]
514    fn test_into_iter_edge_osp() {
515        let (_tempdir, db) = crate::sled::create_test_db().expect("ok");
516        let sled_db = SledTripleStore::new(&db, UlidIdGenerator::new()).expect("ok");
517        crate::conformance::iter::test_into_iter_edge_osp(sled_db);
518    }
519
520    #[test]
521    fn test_into_iter_node() {
522        let (_tempdir, db) = crate::sled::create_test_db().expect("ok");
523        let sled_db = SledTripleStore::new(&db, UlidIdGenerator::new()).expect("ok");
524        crate::conformance::iter::test_into_iter_node(sled_db);
525    }
526}