Skip to main content

terminus_store/layer/internal/
child.rs

1//! Child layer implementation
2//!
3//! A child layer stores a reference to a base layer, as well as
4//! triple additions and removals, and any new dictionary entries that
5//! this layer needs for its additions.
6use super::super::builder::*;
7use super::super::id_map::*;
8use crate::layer::*;
9use crate::storage::*;
10use rayon::prelude::*;
11use tdb_succinct::*;
12
13use std::io;
14use std::pin::Pin;
15use std::sync::Arc;
16
17use futures::stream::{self, Stream, StreamExt};
18use futures::task::{Context, Poll};
19
20/// A child layer.
21///
22/// This layer type has a parent. It stores triple additions and removals.
23#[derive(Clone)]
24pub struct ChildLayer {
25    pub(super) name: [u32; 5],
26    pub(super) parent: Arc<InternalLayer>,
27
28    pub(super) node_dictionary: StringDict,
29    pub(super) predicate_dictionary: StringDict,
30    pub(super) value_dictionary: TypedDict,
31
32    pub(super) node_value_idmap: IdMap,
33    pub(super) predicate_idmap: IdMap,
34
35    pub(super) parent_node_value_count: usize,
36    pub(super) parent_predicate_count: usize,
37
38    pub(super) pos_subjects: MonotonicLogArray,
39    pub(super) pos_objects: MonotonicLogArray,
40    pub(super) pos_s_p_adjacency_list: AdjacencyList,
41    pub(super) pos_sp_o_adjacency_list: AdjacencyList,
42    pub(super) pos_o_ps_adjacency_list: AdjacencyList,
43
44    pub(super) neg_subjects: MonotonicLogArray,
45    pub(super) neg_objects: MonotonicLogArray,
46    pub(super) neg_s_p_adjacency_list: AdjacencyList,
47    pub(super) neg_sp_o_adjacency_list: AdjacencyList,
48    pub(super) neg_o_ps_adjacency_list: AdjacencyList,
49
50    pub(super) pos_predicate_wavelet_tree: WaveletTree,
51    pub(super) neg_predicate_wavelet_tree: WaveletTree,
52}
53
54impl ChildLayer {
55    pub async fn load_from_files<F: FileLoad + FileStore + Clone>(
56        name: [u32; 5],
57        parent: Arc<InternalLayer>,
58        files: &ChildLayerFiles<F>,
59    ) -> io::Result<InternalLayer> {
60        let maps = files.map_all().await?;
61        Ok(Self::load(name, parent, maps))
62    }
63
64    pub fn load(name: [u32; 5], parent: Arc<InternalLayer>, maps: ChildLayerMaps) -> InternalLayer {
65        let node_dictionary = StringDict::parse(
66            maps.node_dictionary_maps.offsets_map,
67            maps.node_dictionary_maps.blocks_map,
68        );
69        let predicate_dictionary = StringDict::parse(
70            maps.predicate_dictionary_maps.offsets_map,
71            maps.predicate_dictionary_maps.blocks_map,
72        );
73        let value_dictionary = TypedDict::from_parts(
74            maps.value_dictionary_maps.types_present_map,
75            maps.value_dictionary_maps.type_offsets_map,
76            maps.value_dictionary_maps.offsets_map,
77            maps.value_dictionary_maps.blocks_map,
78        );
79
80        let parent_node_value_count = parent.node_and_value_count();
81        let parent_predicate_count = parent.predicate_count();
82
83        let node_value_idmap = match maps.id_map_maps.node_value_idmap_maps {
84            None => IdMap::default(),
85            Some(maps) => IdMap::from_maps(
86                maps,
87                util::calculate_width(
88                    (node_dictionary.num_entries() + value_dictionary.num_entries()) as u64,
89                ),
90            ),
91        };
92
93        let predicate_idmap = match maps.id_map_maps.predicate_idmap_maps {
94            None => IdMap::default(),
95            Some(map) => IdMap::from_maps(
96                map,
97                util::calculate_width(predicate_dictionary.num_entries() as u64),
98            ),
99        };
100
101        let pos_subjects =
102            MonotonicLogArray::from_logarray(LogArray::parse(maps.pos_subjects_map).unwrap());
103        let pos_objects =
104            MonotonicLogArray::from_logarray(LogArray::parse(maps.pos_objects_map).unwrap());
105        let neg_subjects =
106            MonotonicLogArray::from_logarray(LogArray::parse(maps.neg_subjects_map).unwrap());
107        let neg_objects =
108            MonotonicLogArray::from_logarray(LogArray::parse(maps.neg_objects_map).unwrap());
109
110        let pos_s_p_adjacency_list = AdjacencyList::parse(
111            maps.pos_s_p_adjacency_list_maps.nums_map,
112            maps.pos_s_p_adjacency_list_maps.bitindex_maps.bits_map,
113            maps.pos_s_p_adjacency_list_maps.bitindex_maps.blocks_map,
114            maps.pos_s_p_adjacency_list_maps.bitindex_maps.sblocks_map,
115        );
116        let pos_sp_o_adjacency_list = AdjacencyList::parse(
117            maps.pos_sp_o_adjacency_list_maps.nums_map,
118            maps.pos_sp_o_adjacency_list_maps.bitindex_maps.bits_map,
119            maps.pos_sp_o_adjacency_list_maps.bitindex_maps.blocks_map,
120            maps.pos_sp_o_adjacency_list_maps.bitindex_maps.sblocks_map,
121        );
122        let pos_o_ps_adjacency_list = AdjacencyList::parse(
123            maps.pos_o_ps_adjacency_list_maps.nums_map,
124            maps.pos_o_ps_adjacency_list_maps.bitindex_maps.bits_map,
125            maps.pos_o_ps_adjacency_list_maps.bitindex_maps.blocks_map,
126            maps.pos_o_ps_adjacency_list_maps.bitindex_maps.sblocks_map,
127        );
128        let neg_s_p_adjacency_list = AdjacencyList::parse(
129            maps.neg_s_p_adjacency_list_maps.nums_map,
130            maps.neg_s_p_adjacency_list_maps.bitindex_maps.bits_map,
131            maps.neg_s_p_adjacency_list_maps.bitindex_maps.blocks_map,
132            maps.neg_s_p_adjacency_list_maps.bitindex_maps.sblocks_map,
133        );
134        let neg_sp_o_adjacency_list = AdjacencyList::parse(
135            maps.neg_sp_o_adjacency_list_maps.nums_map,
136            maps.neg_sp_o_adjacency_list_maps.bitindex_maps.bits_map,
137            maps.neg_sp_o_adjacency_list_maps.bitindex_maps.blocks_map,
138            maps.neg_sp_o_adjacency_list_maps.bitindex_maps.sblocks_map,
139        );
140        let neg_o_ps_adjacency_list = AdjacencyList::parse(
141            maps.neg_o_ps_adjacency_list_maps.nums_map,
142            maps.neg_o_ps_adjacency_list_maps.bitindex_maps.bits_map,
143            maps.neg_o_ps_adjacency_list_maps.bitindex_maps.blocks_map,
144            maps.neg_o_ps_adjacency_list_maps.bitindex_maps.sblocks_map,
145        );
146
147        let pos_predicate_wavelet_tree_width = pos_s_p_adjacency_list.nums().width();
148        let pos_predicate_wavelet_tree = WaveletTree::from_parts(
149            BitIndex::from_maps(
150                maps.pos_predicate_wavelet_tree_maps.bits_map,
151                maps.pos_predicate_wavelet_tree_maps.blocks_map,
152                maps.pos_predicate_wavelet_tree_maps.sblocks_map,
153            ),
154            pos_predicate_wavelet_tree_width,
155        );
156
157        let neg_predicate_wavelet_tree_width = neg_s_p_adjacency_list.nums().width();
158        let neg_predicate_wavelet_tree = WaveletTree::from_parts(
159            BitIndex::from_maps(
160                maps.neg_predicate_wavelet_tree_maps.bits_map,
161                maps.neg_predicate_wavelet_tree_maps.blocks_map,
162                maps.neg_predicate_wavelet_tree_maps.sblocks_map,
163            ),
164            neg_predicate_wavelet_tree_width,
165        );
166
167        InternalLayer::Child(ChildLayer {
168            name,
169            parent,
170
171            node_dictionary,
172            predicate_dictionary,
173            value_dictionary,
174
175            node_value_idmap,
176            predicate_idmap,
177
178            parent_node_value_count,
179            parent_predicate_count,
180
181            pos_subjects,
182            pos_objects,
183            neg_subjects,
184            neg_objects,
185
186            pos_s_p_adjacency_list,
187            pos_sp_o_adjacency_list,
188            pos_o_ps_adjacency_list,
189
190            neg_s_p_adjacency_list,
191            neg_sp_o_adjacency_list,
192            neg_o_ps_adjacency_list,
193
194            pos_predicate_wavelet_tree,
195            neg_predicate_wavelet_tree,
196        })
197    }
198}
199
200/// A builder for a child layer.
201///
202/// This builder takes node, predicate and value strings in lexical
203/// order through the corresponding `add_<thing>` methods. When
204/// they're all added, `into_phase2()` is to be called to turn this
205/// builder into a second builder that takes triple data.
206pub struct ChildLayerFileBuilder<F: 'static + FileLoad + FileStore + Clone + Send + Sync> {
207    parent: Arc<dyn Layer>,
208    files: ChildLayerFiles<F>,
209    builder: DictionarySetFileBuilder<F>,
210}
211
212impl<F: 'static + FileLoad + FileStore + Clone + Send + Sync> ChildLayerFileBuilder<F> {
213    /// Create the builder from the given files.
214    pub async fn from_files(
215        parent: Arc<dyn Layer>,
216        files: &ChildLayerFiles<F>,
217    ) -> io::Result<Self> {
218        let builder = DictionarySetFileBuilder::from_files(
219            files.node_dictionary_files.clone(),
220            files.predicate_dictionary_files.clone(),
221            files.value_dictionary_files.clone(),
222        )
223        .await?;
224
225        Ok(Self {
226            parent,
227            files: files.clone(),
228            builder,
229        })
230    }
231
232    /// Add a node string.
233    ///
234    /// Does nothing if the node already exists in the parent, and
235    /// panics if the given node string is not a lexical successor of
236    /// the previous node string.
237    pub fn add_node(&mut self, node: &str) -> u64 {
238        match self.parent.subject_id(node) {
239            None => self.builder.add_node(node),
240            Some(id) => id,
241        }
242    }
243
244    /// Add a predicate string.
245    ///
246    /// Does nothing if the predicate already exists in the paretn, and
247    /// panics if the given predicate string is not a lexical successor of
248    /// the previous predicate string.
249    pub fn add_predicate(&mut self, predicate: &str) -> u64 {
250        match self.parent.predicate_id(predicate) {
251            None => self.builder.add_predicate(predicate),
252            Some(id) => id,
253        }
254    }
255
256    /// Add a value string.
257    ///
258    /// Does nothing if the value already exists in the paretn, and
259    /// panics if the given value string is not a lexical successor of
260    /// the previous value string.
261    pub fn add_value(&mut self, value: TypedDictEntry) -> u64 {
262        match self.parent.object_value_id(&value) {
263            None => self.builder.add_value(value),
264            Some(id) => id,
265        }
266    }
267
268    /// Add nodes from an iterable.
269    ///
270    /// Panics if the nodes are not in lexical order, or if previous
271    /// added nodes are a lexical succesor of any of these
272    /// nodes. Skips any nodes that are already part of the base
273    /// layer.
274    pub fn add_nodes<I: 'static + IntoIterator<Item = String> + Send>(
275        &mut self,
276        nodes: I,
277    ) -> Vec<u64>
278    where
279        <I as std::iter::IntoIterator>::IntoIter: Send,
280    {
281        // TODO bulk check node existence
282        let mut result = Vec::new();
283        for node in nodes {
284            let id = self.add_node(&node);
285            result.push(id);
286        }
287
288        result
289    }
290
291    /// Add predicates from an iterable.
292    ///
293    /// Panics if the predicates are not in lexical order, or if
294    /// previous added predicates are a lexical succesor of any of
295    /// these predicates. Skips any predicates that are already part
296    /// of the base layer.
297    pub fn add_predicates<I: 'static + IntoIterator<Item = String> + Send>(
298        &mut self,
299        predicates: I,
300    ) -> Vec<u64>
301    where
302        <I as std::iter::IntoIterator>::IntoIter: Send,
303    {
304        // TODO bulk check predicate existence
305        let mut result = Vec::new();
306        for predicate in predicates {
307            let id = self.add_predicate(&predicate);
308            result.push(id);
309        }
310
311        result
312    }
313
314    /// Add values from an iterable.
315    ///
316    /// Panics if the values are not in lexical order, or if previous
317    /// added values are a lexical succesor of any of these
318    /// values. Skips any nodes that are already part of the base
319    /// layer.
320    pub fn add_values<I: 'static + IntoIterator<Item = TypedDictEntry> + Send>(
321        &mut self,
322        values: I,
323    ) -> Vec<u64>
324    where
325        <I as std::iter::IntoIterator>::IntoIter: Send,
326    {
327        // TODO bulk check predicate existence
328        let mut result = Vec::new();
329        for value in values {
330            let id = self.add_value(value);
331            result.push(id);
332        }
333
334        result
335    }
336
337    /// Turn this builder into a phase 2 builder that will take triple data.
338    pub async fn into_phase2(self) -> io::Result<ChildLayerFileBuilderPhase2<F>> {
339        let ChildLayerFileBuilder {
340            parent,
341            files,
342            builder,
343        } = self;
344
345        builder.finalize().await?;
346
347        let node_dict_offsets_map = files.node_dictionary_files.offsets_file.map().await?;
348        let node_dict_blocks_map = files.node_dictionary_files.blocks_file.map().await?;
349        let predicate_dict_offsets_map =
350            files.predicate_dictionary_files.offsets_file.map().await?;
351        let predicate_dict_blocks_map = files.predicate_dictionary_files.blocks_file.map().await?;
352        let value_dict_types_present_map = files
353            .value_dictionary_files
354            .types_present_file
355            .map()
356            .await?;
357        let value_dict_type_offsets_map =
358            files.value_dictionary_files.type_offsets_file.map().await?;
359        let value_dict_offsets_map = files.value_dictionary_files.offsets_file.map().await?;
360        let value_dict_blocks_map = files.value_dictionary_files.blocks_file.map().await?;
361
362        let node_dict = StringDict::parse(node_dict_offsets_map, node_dict_blocks_map);
363        let pred_dict = StringDict::parse(predicate_dict_offsets_map, predicate_dict_blocks_map);
364        let val_dict = TypedDict::from_parts(
365            value_dict_types_present_map,
366            value_dict_type_offsets_map,
367            value_dict_offsets_map,
368            value_dict_blocks_map,
369        );
370
371        // TODO: it is a bit silly to parse the dictionaries just for this. surely we can get the counts in an easier way?
372        let num_nodes = node_dict.num_entries();
373        let num_predicates = pred_dict.num_entries();
374        let num_values = val_dict.num_entries();
375
376        ChildLayerFileBuilderPhase2::new(parent, files, num_nodes, num_predicates, num_values).await
377    }
378}
379
380/// Second phase of child layer building.
381///
382/// This builder takes ordered triple additions and removals. When all
383/// data has been added, `finalize()` will build a layer.
384pub struct ChildLayerFileBuilderPhase2<F: 'static + FileLoad + FileStore + Clone + Send + Sync> {
385    parent: Arc<dyn Layer>,
386
387    files: ChildLayerFiles<F>,
388
389    pos_builder: TripleFileBuilder<F>,
390    neg_builder: TripleFileBuilder<F>,
391}
392
393impl<F: 'static + FileLoad + FileStore + Clone + Send + Sync> ChildLayerFileBuilderPhase2<F> {
394    pub(crate) async fn new(
395        parent: Arc<dyn Layer>,
396        files: ChildLayerFiles<F>,
397
398        num_nodes: usize,
399        num_predicates: usize,
400        num_values: usize,
401    ) -> io::Result<Self> {
402        let parent_counts = parent.all_counts();
403        let pos_builder = TripleFileBuilder::new(
404            files.pos_s_p_adjacency_list_files.clone(),
405            files.pos_sp_o_adjacency_list_files.clone(),
406            num_nodes + parent_counts.node_count,
407            num_predicates + parent_counts.predicate_count,
408            num_values + parent_counts.value_count,
409            Some(files.pos_subjects_file.clone()),
410        )
411        .await?;
412
413        let neg_builder = TripleFileBuilder::new(
414            files.neg_s_p_adjacency_list_files.clone(),
415            files.neg_sp_o_adjacency_list_files.clone(),
416            num_nodes + parent_counts.node_count,
417            num_predicates + parent_counts.predicate_count,
418            num_values + parent_counts.value_count,
419            Some(files.neg_subjects_file.clone()),
420        )
421        .await?;
422
423        Ok(ChildLayerFileBuilderPhase2 {
424            parent,
425            files,
426
427            pos_builder,
428            neg_builder,
429        })
430    }
431
432    pub(crate) async fn add_triple_unchecked(
433        &mut self,
434        subject: u64,
435        predicate: u64,
436        object: u64,
437    ) -> io::Result<()> {
438        self.pos_builder
439            .add_triple(subject, predicate, object)
440            .await
441    }
442
443    /// Add the given subject, predicate and object.
444    ///
445    /// This will panic if a greater triple has already been added,
446    /// and do nothing if the triple is already part of the parent.
447    pub async fn add_triple(
448        &mut self,
449        subject: u64,
450        predicate: u64,
451        object: u64,
452    ) -> io::Result<()> {
453        if !self.parent.triple_exists(subject, predicate, object) {
454            self.add_triple_unchecked(subject, predicate, object).await
455        } else {
456            Ok(())
457        }
458    }
459
460    pub(crate) async fn remove_triple_unchecked(
461        &mut self,
462        subject: u64,
463        predicate: u64,
464        object: u64,
465    ) -> io::Result<()> {
466        self.neg_builder
467            .add_triple(subject, predicate, object)
468            .await
469    }
470
471    /// Remove the given subject, predicate and object.
472    ///
473    /// This will panic if a greater triple has already been removed,
474    /// and do nothing if the parent doesn't know aobut this triple.
475    pub async fn remove_triple(
476        &mut self,
477        subject: u64,
478        predicate: u64,
479        object: u64,
480    ) -> io::Result<()> {
481        if self.parent.triple_exists(subject, predicate, object) {
482            self.remove_triple_unchecked(subject, predicate, object)
483                .await
484        } else {
485            Ok(())
486        }
487    }
488
489    /// Add the given triple.
490    ///
491    /// This will panic if a greater triple has already been added,
492    /// and do nothing if the parent already contains this triple.
493    pub async fn add_id_triples(&mut self, triples: Vec<IdTriple>) -> io::Result<()> {
494        let parent = self.parent.clone();
495        let filtered: Vec<_> = triples
496            .into_par_iter()
497            .filter(move |triple| {
498                !parent.triple_exists(triple.subject, triple.predicate, triple.object)
499            })
500            .collect();
501
502        for triple in filtered {
503            self.add_triple_unchecked(triple.subject, triple.predicate, triple.object)
504                .await?;
505        }
506
507        Ok(())
508    }
509
510    /// Remove the given triple.
511    ///
512    /// This will panic if a greater triple has already been removed,
513    /// and do nothing if the parent doesn't know aobut this triple.
514    pub async fn remove_id_triples(&mut self, triples: Vec<IdTriple>) -> io::Result<()> {
515        let parent = self.parent.clone();
516        let filtered: Vec<_> = triples
517            .into_par_iter()
518            .filter(move |triple| {
519                parent.triple_exists(triple.subject, triple.predicate, triple.object)
520            })
521            .collect();
522
523        for triple in filtered {
524            self.remove_triple_unchecked(triple.subject, triple.predicate, triple.object)
525                .await?;
526        }
527
528        Ok(())
529    }
530
531    /// Write the layer data to storage.
532    pub async fn finalize(self) -> io::Result<()> {
533        let pos_task = tokio::spawn(self.pos_builder.finalize());
534        let neg_task = tokio::spawn(self.neg_builder.finalize());
535
536        pos_task.await??;
537        neg_task.await??;
538
539        let pos_indexes_task = tokio::spawn(build_indexes(
540            self.files.pos_s_p_adjacency_list_files,
541            self.files.pos_sp_o_adjacency_list_files,
542            self.files.pos_o_ps_adjacency_list_files,
543            Some(self.files.pos_objects_file),
544            self.files.pos_predicate_wavelet_tree_files,
545        ));
546        let neg_indexes_task = tokio::spawn(build_indexes(
547            self.files.neg_s_p_adjacency_list_files,
548            self.files.neg_sp_o_adjacency_list_files,
549            self.files.neg_o_ps_adjacency_list_files,
550            Some(self.files.neg_objects_file),
551            self.files.neg_predicate_wavelet_tree_files,
552        ));
553
554        pos_indexes_task.await??;
555        neg_indexes_task.await??;
556
557        Ok(())
558    }
559}
560
561pub struct ChildTripleStream<
562    S1: Stream<Item = io::Result<u64>> + Unpin + Send,
563    S2: Stream<Item = io::Result<(u64, u64)>> + Unpin + Send,
564> {
565    subjects_stream: stream::Peekable<S1>,
566    s_p_stream: stream::Peekable<S2>,
567    sp_o_stream: stream::Peekable<S2>,
568    last_mapped_s: u64,
569    last_s_p: (u64, u64),
570    last_sp: u64,
571}
572
573impl<
574        S1: Stream<Item = io::Result<u64>> + Unpin + Send,
575        S2: Stream<Item = io::Result<(u64, u64)>> + Unpin + Send,
576    > ChildTripleStream<S1, S2>
577{
578    fn new(subjects_stream: S1, s_p_stream: S2, sp_o_stream: S2) -> ChildTripleStream<S1, S2> {
579        ChildTripleStream {
580            subjects_stream: subjects_stream.peekable(),
581            s_p_stream: s_p_stream.peekable(),
582            sp_o_stream: sp_o_stream.peekable(),
583            last_mapped_s: 0,
584            last_s_p: (0, 0),
585            last_sp: 0,
586        }
587    }
588}
589
590impl<
591        S1: Stream<Item = io::Result<u64>> + Unpin + Send,
592        S2: Stream<Item = io::Result<(u64, u64)>> + Unpin + Send,
593    > Stream for ChildTripleStream<S1, S2>
594{
595    type Item = io::Result<(u64, u64, u64)>;
596
597    fn poll_next(
598        mut self: Pin<&mut Self>,
599        cx: &mut Context,
600    ) -> Poll<Option<io::Result<(u64, u64, u64)>>> {
601        let sp_o = Pin::new(&mut self.sp_o_stream).poll_peek(cx);
602        match sp_o {
603            Poll::Ready(Some(Ok((sp, o)))) => {
604                let sp = *sp;
605                let o = *o;
606                if sp > self.last_sp {
607                    let s_p = Pin::new(&mut self.s_p_stream).poll_peek(cx);
608                    match s_p {
609                        Poll::Ready(None) => Poll::Ready(Some(Err(io::Error::new(
610                            io::ErrorKind::UnexpectedEof,
611                            "unexpected end of s_p_stream",
612                        )))),
613                        Poll::Ready(Some(Ok((s, p)))) => {
614                            let s = *s;
615                            let p = *p;
616                            if s > self.last_s_p.0 {
617                                let mapped_s = Pin::new(&mut self.subjects_stream).poll_peek(cx);
618                                match mapped_s {
619                                    Poll::Ready(None) => Poll::Ready(Some(Err(io::Error::new(
620                                        io::ErrorKind::UnexpectedEof,
621                                        "unexpected end of subjects_stream",
622                                    )))),
623                                    Poll::Ready(Some(Ok(mapped_s))) => {
624                                        let mapped_s = *mapped_s;
625                                        util::assert_poll_next(
626                                            Pin::new(&mut self.subjects_stream),
627                                            cx,
628                                        )
629                                        .unwrap();
630                                        util::assert_poll_next(Pin::new(&mut self.s_p_stream), cx)
631                                            .unwrap();
632                                        util::assert_poll_next(Pin::new(&mut self.sp_o_stream), cx)
633                                            .unwrap();
634                                        self.last_mapped_s = mapped_s;
635                                        self.last_s_p = (s, p);
636                                        self.last_sp = sp;
637
638                                        Poll::Ready(Some(Ok((mapped_s, p, o))))
639                                    }
640                                    Poll::Ready(Some(Err(_))) => {
641                                        Poll::Ready(Some(Err(util::assert_poll_next(
642                                            Pin::new(&mut self.subjects_stream),
643                                            cx,
644                                        )
645                                        .err()
646                                        .unwrap())))
647                                    }
648                                    Poll::Pending => Poll::Pending,
649                                }
650                            } else {
651                                util::assert_poll_next(Pin::new(&mut self.s_p_stream), cx).unwrap();
652                                util::assert_poll_next(Pin::new(&mut self.sp_o_stream), cx)
653                                    .unwrap();
654                                self.last_s_p = (s, p);
655                                self.last_sp = sp;
656
657                                Poll::Ready(Some(Ok((self.last_mapped_s, p, o))))
658                            }
659                        }
660                        Poll::Ready(Some(Err(_))) => Poll::Ready(Some(Err(
661                            util::assert_poll_next(Pin::new(&mut self.s_p_stream), cx)
662                                .err()
663                                .unwrap(),
664                        ))),
665                        Poll::Pending => Poll::Pending,
666                    }
667                } else {
668                    util::assert_poll_next(Pin::new(&mut self.sp_o_stream), cx).unwrap();
669                    Poll::Ready(Some(Ok((self.last_mapped_s, self.last_s_p.1, o))))
670                }
671            }
672            Poll::Ready(Some(Err(_))) => Poll::Ready(Some(Err(util::assert_poll_next(
673                Pin::new(&mut self.sp_o_stream),
674                cx,
675            )
676            .err()
677            .unwrap()))),
678            Poll::Ready(None) => Poll::Ready(None),
679            Poll::Pending => Poll::Pending,
680        }
681    }
682}
683
684pub async fn open_child_triple_stream<F: 'static + FileLoad + FileStore>(
685    subjects_file: F,
686    s_p_files: AdjacencyListFiles<F>,
687    sp_o_files: AdjacencyListFiles<F>,
688) -> io::Result<impl Stream<Item = io::Result<(u64, u64, u64)>> + Unpin + Send> {
689    let subjects_stream = logarray_stream_entries(subjects_file).await?;
690    let s_p_stream =
691        adjacency_list_stream_pairs(s_p_files.bitindex_files.bits_file, s_p_files.nums_file)
692            .await?;
693    let sp_o_stream =
694        adjacency_list_stream_pairs(sp_o_files.bitindex_files.bits_file, sp_o_files.nums_file)
695            .await?;
696
697    Ok(ChildTripleStream::new(
698        subjects_stream,
699        s_p_stream,
700        sp_o_stream,
701    ))
702}
703
704#[cfg(test)]
705pub mod child_tests {
706    use super::*;
707    use crate::layer::base::base_tests::*;
708    use crate::storage::memory::*;
709    use futures::stream::TryStreamExt;
710
711    pub fn child_layer_files() -> ChildLayerFiles<MemoryBackedStore> {
712        // TODO inline
713        child_layer_memory_files()
714    }
715
716    #[tokio::test]
717    async fn empty_child_layer_equivalent_to_parent() {
718        let base_layer = example_base_layer().await;
719
720        let parent: Arc<InternalLayer> = Arc::new(base_layer.into());
721
722        let child_files = child_layer_files();
723
724        let child_builder = ChildLayerFileBuilder::from_files(parent.clone(), &child_files)
725            .await
726            .unwrap();
727        let builder = child_builder.into_phase2().await.unwrap();
728        builder.finalize().await.unwrap();
729
730        let child_layer = ChildLayer::load_from_files([5, 4, 3, 2, 1], parent, &child_files)
731            .await
732            .unwrap();
733
734        assert!(child_layer.triple_exists(1, 1, 1));
735        assert!(child_layer.triple_exists(2, 1, 1));
736        assert!(child_layer.triple_exists(2, 1, 3));
737        assert!(child_layer.triple_exists(2, 3, 6));
738        assert!(child_layer.triple_exists(3, 2, 5));
739        assert!(child_layer.triple_exists(3, 3, 6));
740        assert!(child_layer.triple_exists(4, 3, 6));
741
742        assert!(!child_layer.triple_exists(2, 2, 0));
743    }
744
745    #[tokio::test]
746    async fn child_layer_can_have_inserts() {
747        let base_layer = example_base_layer().await;
748
749        let parent: Arc<InternalLayer> = Arc::new(base_layer.into());
750
751        let child_files = child_layer_files();
752
753        let child_builder = ChildLayerFileBuilder::from_files(parent.clone(), &child_files)
754            .await
755            .unwrap();
756        let mut b = child_builder.into_phase2().await.unwrap();
757        b.add_triple(2, 1, 2).await.unwrap();
758        b.add_triple(3, 3, 3).await.unwrap();
759        b.finalize().await.unwrap();
760
761        let child_layer = ChildLayer::load_from_files([5, 4, 3, 2, 1], parent, &child_files)
762            .await
763            .unwrap();
764
765        assert!(child_layer.triple_exists(1, 1, 1));
766        assert!(child_layer.triple_exists(2, 1, 1));
767        assert!(child_layer.triple_exists(2, 1, 2));
768        assert!(child_layer.triple_exists(2, 1, 3));
769        assert!(child_layer.triple_exists(2, 3, 6));
770        assert!(child_layer.triple_exists(3, 2, 5));
771        assert!(child_layer.triple_exists(3, 3, 3));
772        assert!(child_layer.triple_exists(3, 3, 6));
773        assert!(child_layer.triple_exists(4, 3, 6));
774
775        assert!(!child_layer.triple_exists(2, 2, 0));
776    }
777
778    #[tokio::test]
779    async fn child_layer_can_have_deletes() {
780        let base_layer = example_base_layer().await;
781
782        let parent: Arc<InternalLayer> = Arc::new(base_layer.into());
783
784        let child_files = child_layer_files();
785
786        let child_builder = ChildLayerFileBuilder::from_files(parent.clone(), &child_files)
787            .await
788            .unwrap();
789        let mut b = child_builder.into_phase2().await.unwrap();
790        b.remove_triple(2, 1, 1).await.unwrap();
791        b.remove_triple(3, 2, 5).await.unwrap();
792        b.finalize().await.unwrap();
793
794        let child_layer = ChildLayer::load_from_files([5, 4, 3, 2, 1], parent, &child_files)
795            .await
796            .unwrap();
797
798        assert!(child_layer.triple_exists(1, 1, 1));
799        assert!(!child_layer.triple_exists(2, 1, 1));
800        assert!(child_layer.triple_exists(2, 1, 3));
801        assert!(child_layer.triple_exists(2, 3, 6));
802        assert!(!child_layer.triple_exists(3, 2, 5));
803        assert!(child_layer.triple_exists(3, 3, 6));
804        assert!(child_layer.triple_exists(4, 3, 6));
805
806        assert!(!child_layer.triple_exists(2, 2, 0));
807    }
808
809    #[tokio::test]
810    async fn child_layer_can_have_inserts_and_deletes() {
811        let base_layer = example_base_layer().await;
812        let parent: Arc<InternalLayer> = Arc::new(base_layer.into());
813
814        let child_files = child_layer_files();
815
816        let child_builder = ChildLayerFileBuilder::from_files(parent.clone(), &child_files)
817            .await
818            .unwrap();
819        let mut b = child_builder.into_phase2().await.unwrap();
820        b.add_triple(1, 2, 3).await.unwrap();
821        b.add_triple(2, 3, 4).await.unwrap();
822        b.remove_triple(3, 2, 5).await.unwrap();
823        b.finalize().await.unwrap();
824
825        let child_layer = ChildLayer::load_from_files([5, 4, 3, 2, 1], parent, &child_files)
826            .await
827            .unwrap();
828
829        assert!(child_layer.triple_exists(1, 1, 1));
830        assert!(child_layer.triple_exists(1, 2, 3));
831        assert!(child_layer.triple_exists(2, 1, 1));
832        assert!(child_layer.triple_exists(2, 1, 3));
833        assert!(child_layer.triple_exists(2, 3, 4));
834        assert!(child_layer.triple_exists(2, 3, 6));
835        assert!(!child_layer.triple_exists(3, 2, 5));
836        assert!(child_layer.triple_exists(3, 3, 6));
837        assert!(child_layer.triple_exists(4, 3, 6));
838
839        assert!(!child_layer.triple_exists(2, 2, 0));
840    }
841
842    #[tokio::test]
843    async fn iterate_child_layer_triples() {
844        let base_layer = example_base_layer().await;
845        let parent: Arc<InternalLayer> = Arc::new(base_layer.into());
846
847        let child_files = child_layer_files();
848
849        let child_builder = ChildLayerFileBuilder::from_files(parent.clone(), &child_files)
850            .await
851            .unwrap();
852        let mut b = child_builder.into_phase2().await.unwrap();
853        b.add_triple(1, 2, 3).await.unwrap();
854        b.add_triple(2, 3, 4).await.unwrap();
855        b.remove_triple(3, 2, 5).await.unwrap();
856        b.finalize().await.unwrap();
857
858        let child_layer = ChildLayer::load_from_files([5, 4, 3, 2, 1], parent, &child_files)
859            .await
860            .unwrap();
861
862        let subjects: Vec<_> = child_layer
863            .triples()
864            .map(|t| (t.subject, t.predicate, t.object))
865            .collect();
866
867        assert_eq!(
868            vec![
869                (1, 1, 1),
870                (1, 2, 3),
871                (2, 1, 1),
872                (2, 1, 3),
873                (2, 3, 4),
874                (2, 3, 6),
875                (3, 3, 6),
876                (4, 3, 6)
877            ],
878            subjects
879        );
880    }
881
882    #[tokio::test]
883    async fn lookup_child_layer_triples_by_predicate() {
884        let base_layer = example_base_layer().await;
885        let parent: Arc<InternalLayer> = Arc::new(base_layer.into());
886
887        let child_files = child_layer_files();
888
889        let child_builder = ChildLayerFileBuilder::from_files(parent.clone(), &child_files)
890            .await
891            .unwrap();
892        let mut b = child_builder.into_phase2().await.unwrap();
893        b.add_triple(1, 2, 3).await.unwrap();
894        b.add_triple(2, 3, 4).await.unwrap();
895        b.remove_triple(3, 2, 5).await.unwrap();
896        b.finalize().await.unwrap();
897
898        let child_layer = ChildLayer::load_from_files([5, 4, 3, 2, 1], parent, &child_files)
899            .await
900            .unwrap();
901
902        let pairs: Vec<_> = child_layer
903            .triples_p(1)
904            .map(|t| (t.subject, t.predicate, t.object))
905            .collect();
906
907        assert_eq!(vec![(1, 1, 1), (2, 1, 1), (2, 1, 3)], pairs);
908
909        let pairs: Vec<_> = child_layer
910            .triples_p(2)
911            .map(|t| (t.subject, t.predicate, t.object))
912            .collect();
913
914        assert_eq!(vec![(1, 2, 3)], pairs);
915
916        let pairs: Vec<_> = child_layer
917            .triples_p(3)
918            .map(|t| (t.subject, t.predicate, t.object))
919            .collect();
920
921        assert_eq!(vec![(2, 3, 4), (2, 3, 6), (3, 3, 6), (4, 3, 6)], pairs);
922
923        assert!(child_layer.triples_p(4).next().is_none());
924    }
925
926    #[tokio::test]
927    async fn adding_new_nodes_predicates_and_values_in_child() {
928        let base_layer = example_base_layer().await;
929        let parent: Arc<InternalLayer> = Arc::new(base_layer.into());
930
931        let child_files = child_layer_files();
932
933        let child_builder = ChildLayerFileBuilder::from_files(parent.clone(), &child_files)
934            .await
935            .unwrap();
936        let mut b = child_builder.into_phase2().await.unwrap();
937        b.add_triple(11, 2, 3).await.unwrap();
938        b.add_triple(12, 3, 4).await.unwrap();
939        b.finalize().await.unwrap();
940
941        let child_layer = ChildLayer::load_from_files([5, 4, 3, 2, 1], parent, &child_files)
942            .await
943            .unwrap();
944
945        assert!(child_layer.triple_exists(11, 2, 3));
946        assert!(child_layer.triple_exists(12, 3, 4));
947    }
948
949    #[tokio::test]
950    async fn old_dictionary_entries_in_child() {
951        let base_layer = example_base_layer().await;
952        let parent: Arc<InternalLayer> = Arc::new(base_layer.into());
953
954        let child_files = child_layer_files();
955
956        let mut b = ChildLayerFileBuilder::from_files(parent.clone(), &child_files)
957            .await
958            .unwrap();
959        b.add_node("foo");
960        b.add_predicate("bar");
961        b.add_value(String::make_entry(&"baz"));
962
963        let b = b.into_phase2().await.unwrap();
964        b.finalize().await.unwrap();
965
966        let child_layer = ChildLayer::load_from_files([5, 4, 3, 2, 1], parent, &child_files)
967            .await
968            .unwrap();
969
970        assert_eq!(3, child_layer.subject_id("bbbbb").unwrap());
971        assert_eq!(2, child_layer.predicate_id("fghij").unwrap());
972        assert_eq!(1, child_layer.object_node_id("aaaaa").unwrap());
973        assert_eq!(
974            6,
975            child_layer
976                .object_value_id(&String::make_entry(&"chicken"))
977                .unwrap()
978        );
979
980        assert_eq!("bbbbb", child_layer.id_subject(3).unwrap());
981        assert_eq!("fghij", child_layer.id_predicate(2).unwrap());
982        assert_eq!(
983            ObjectType::Node("aaaaa".to_string()),
984            child_layer.id_object(1).unwrap()
985        );
986        assert_eq!(
987            ObjectType::Value(String::make_entry(&"chicken")),
988            child_layer.id_object(6).unwrap()
989        );
990    }
991
992    #[tokio::test]
993    async fn new_dictionary_entries_in_child() {
994        let base_layer = example_base_layer().await;
995        let parent: Arc<InternalLayer> = Arc::new(base_layer.into());
996
997        let child_files = child_layer_files();
998
999        let mut b = ChildLayerFileBuilder::from_files(parent.clone(), &child_files)
1000            .await
1001            .unwrap();
1002        b.add_node("foo");
1003        b.add_predicate("bar");
1004        b.add_value(String::make_entry(&"baz"));
1005        let b = b.into_phase2().await.unwrap();
1006
1007        b.finalize().await.unwrap();
1008
1009        let child_layer = ChildLayer::load_from_files([5, 4, 3, 2, 1], parent, &child_files)
1010            .await
1011            .unwrap();
1012
1013        assert_eq!(11, child_layer.subject_id("foo").unwrap());
1014        assert_eq!(5, child_layer.predicate_id("bar").unwrap());
1015        assert_eq!(11, child_layer.object_node_id("foo").unwrap());
1016        assert_eq!(
1017            12,
1018            child_layer
1019                .object_value_id(&String::make_entry(&"baz"))
1020                .unwrap()
1021        );
1022
1023        assert_eq!("foo", child_layer.id_subject(11).unwrap());
1024        assert_eq!("bar", child_layer.id_predicate(5).unwrap());
1025        assert_eq!(
1026            ObjectType::Node("foo".to_string()),
1027            child_layer.id_object(11).unwrap()
1028        );
1029        assert_eq!(
1030            ObjectType::Value(String::make_entry(&"baz")),
1031            child_layer.id_object(12).unwrap()
1032        );
1033    }
1034
1035    #[tokio::test]
1036    async fn lookup_additions_by_subject() {
1037        let base_layer = example_base_layer().await;
1038        let parent: Arc<InternalLayer> = Arc::new(base_layer.into());
1039
1040        let child_files = child_layer_files();
1041
1042        let child_builder = ChildLayerFileBuilder::from_files(parent.clone(), &child_files)
1043            .await
1044            .unwrap();
1045        let mut b = child_builder.into_phase2().await.unwrap();
1046        b.add_triple(1, 3, 4).await.unwrap();
1047        b.add_triple(2, 2, 2).await.unwrap();
1048        b.add_triple(3, 4, 5).await.unwrap();
1049        b.remove_triple(3, 2, 5).await.unwrap();
1050        b.finalize().await.unwrap();
1051
1052        let child_layer = ChildLayer::load_from_files([5, 4, 3, 2, 1], parent, &child_files)
1053            .await
1054            .unwrap();
1055
1056        let result: Vec<_> = child_layer
1057            .internal_triple_additions()
1058            .map(|t| (t.subject, t.predicate, t.object))
1059            .collect();
1060
1061        assert_eq!(vec![(1, 3, 4), (2, 2, 2), (3, 4, 5)], result);
1062    }
1063
1064    #[tokio::test]
1065    async fn lookup_removals_by_subject() {
1066        let base_layer = example_base_layer().await;
1067        let parent: Arc<InternalLayer> = Arc::new(base_layer.into());
1068
1069        let child_files = child_layer_files();
1070
1071        let child_builder = ChildLayerFileBuilder::from_files(parent.clone(), &child_files)
1072            .await
1073            .unwrap();
1074        let mut b = child_builder.into_phase2().await.unwrap();
1075        b.add_triple(1, 3, 4).await.unwrap();
1076        b.remove_triple(2, 1, 1).await.unwrap();
1077        b.remove_triple(3, 2, 5).await.unwrap();
1078        b.remove_triple(4, 3, 6).await.unwrap();
1079        b.finalize().await.unwrap();
1080
1081        let child_layer = ChildLayer::load_from_files([5, 4, 3, 2, 1], parent, &child_files)
1082            .await
1083            .unwrap();
1084
1085        let result: Vec<_> = child_layer
1086            .internal_triple_removals()
1087            .map(|t| (t.subject, t.predicate, t.object))
1088            .collect();
1089
1090        assert_eq!(vec![(2, 1, 1), (3, 2, 5), (4, 3, 6)], result);
1091    }
1092
1093    #[tokio::test]
1094    async fn create_empty_child_layer() {
1095        let base_layer = example_base_layer().await;
1096        let parent: Arc<InternalLayer> = Arc::new(base_layer.into());
1097
1098        let child_files = child_layer_files();
1099
1100        let child_builder = ChildLayerFileBuilder::from_files(parent.clone(), &child_files)
1101            .await
1102            .unwrap();
1103        let mut b = child_builder.into_phase2().await.unwrap();
1104        b.add_triple(1, 3, 4).await.unwrap();
1105        b.remove_triple(2, 1, 1).await.unwrap();
1106        b.remove_triple(2, 3, 6).await.unwrap();
1107        b.remove_triple(3, 2, 5).await.unwrap();
1108        b.finalize().await.unwrap();
1109
1110        let child_layer =
1111            ChildLayer::load_from_files([5, 4, 3, 2, 1], parent.clone(), &child_files)
1112                .await
1113                .unwrap();
1114
1115        assert_eq!(
1116            parent.node_and_value_count(),
1117            child_layer.node_and_value_count()
1118        );
1119        assert_eq!(parent.predicate_count(), child_layer.predicate_count());
1120    }
1121
1122    #[tokio::test]
1123    async fn stream_child_triples() {
1124        let base_layer = example_base_layer().await;
1125        let parent: Arc<InternalLayer> = Arc::new(base_layer.into());
1126
1127        let child_files = child_layer_files();
1128        let builder = ChildLayerFileBuilder::from_files(parent.clone(), &child_files)
1129            .await
1130            .unwrap();
1131
1132        let mut b = builder.into_phase2().await.unwrap();
1133        b.add_triple(1, 2, 1).await.unwrap();
1134        b.add_triple(3, 1, 5).await.unwrap();
1135        b.add_triple(5, 2, 3).await.unwrap();
1136        b.add_triple(5, 2, 4).await.unwrap();
1137        b.add_triple(5, 2, 5).await.unwrap();
1138        b.add_triple(5, 3, 1).await.unwrap();
1139        b.remove_triple(2, 1, 1).await.unwrap();
1140        b.remove_triple(2, 3, 6).await.unwrap();
1141        b.remove_triple(4, 3, 6).await.unwrap();
1142        b.finalize().await.unwrap();
1143
1144        let addition_stream = open_child_triple_stream(
1145            child_files.pos_subjects_file,
1146            child_files.pos_s_p_adjacency_list_files,
1147            child_files.pos_sp_o_adjacency_list_files,
1148        )
1149        .await
1150        .unwrap();
1151        let removal_stream = open_child_triple_stream(
1152            child_files.neg_subjects_file,
1153            child_files.neg_s_p_adjacency_list_files,
1154            child_files.neg_sp_o_adjacency_list_files,
1155        )
1156        .await
1157        .unwrap();
1158
1159        let addition_triples: Vec<_> = addition_stream.try_collect().await.unwrap();
1160        let removal_triples: Vec<_> = removal_stream.try_collect().await.unwrap();
1161
1162        assert_eq!(
1163            vec![
1164                (1, 2, 1),
1165                (3, 1, 5),
1166                (5, 2, 3),
1167                (5, 2, 4),
1168                (5, 2, 5),
1169                (5, 3, 1)
1170            ],
1171            addition_triples
1172        );
1173
1174        assert_eq!(vec![(2, 1, 1), (2, 3, 6), (4, 3, 6)], removal_triples);
1175    }
1176
1177    #[tokio::test]
1178    async fn count_triples() {
1179        let base_layer = example_base_layer().await;
1180        let parent: Arc<InternalLayer> = Arc::new(base_layer.into());
1181
1182        let child_files = child_layer_files();
1183        let builder = ChildLayerFileBuilder::from_files(parent.clone(), &child_files)
1184            .await
1185            .unwrap();
1186
1187        let mut b = builder.into_phase2().await.unwrap();
1188        b.add_triple(1, 2, 1).await.unwrap();
1189        b.add_triple(3, 1, 5).await.unwrap();
1190        b.add_triple(5, 2, 3).await.unwrap();
1191        b.add_triple(5, 2, 4).await.unwrap();
1192        b.add_triple(5, 2, 5).await.unwrap();
1193        b.add_triple(5, 3, 1).await.unwrap();
1194        b.remove_triple(2, 1, 1).await.unwrap();
1195        b.remove_triple(2, 3, 6).await.unwrap();
1196        b.remove_triple(4, 3, 6).await.unwrap();
1197        b.finalize().await.unwrap();
1198
1199        let child_layer = ChildLayer::load_from_files([5, 4, 3, 2, 1], parent, &child_files)
1200            .await
1201            .unwrap();
1202
1203        assert_eq!(6, child_layer.internal_triple_layer_addition_count());
1204        assert_eq!(3, child_layer.internal_triple_layer_removal_count());
1205        assert_eq!(13, child_layer.triple_addition_count());
1206        assert_eq!(3, child_layer.triple_removal_count());
1207        assert_eq!(10, child_layer.triple_count());
1208    }
1209}