1use 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#[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
200pub 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 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 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 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 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 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 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 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 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 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 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 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 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
380pub 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 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 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 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 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 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 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}