Skip to main content

terminus_store/layer/internal/
mod.rs

1pub mod base;
2pub mod base_merge;
3pub mod child;
4mod object_iterator;
5mod predicate_iterator;
6pub mod rollup;
7mod subject_iterator;
8
9use super::id_map::*;
10use super::layer::*;
11use tdb_succinct::*;
12
13use std::collections::HashSet;
14use std::convert::TryInto;
15
16pub use base::*;
17pub use child::*;
18pub use object_iterator::*;
19pub use predicate_iterator::*;
20pub use rollup::*;
21pub use subject_iterator::*;
22
23#[derive(Clone)]
24pub enum InternalLayer {
25    Base(BaseLayer),
26    Child(ChildLayer),
27    Rollup(RollupLayer),
28}
29
30use tfc::block::IdLookupResult;
31use InternalLayer::*;
32
33impl InternalLayer {
34    pub fn name(&self) -> [u32; 5] {
35        match self {
36            Base(base) => base.name,
37            Child(child) => child.name,
38            Rollup(rollup) => rollup.original,
39        }
40    }
41
42    pub fn parent_name(&self) -> Option<[u32; 5]> {
43        match self {
44            Base(_) => None,
45            Child(child) => Some(child.parent.name()),
46            Rollup(rollup) => rollup.original_parent,
47        }
48    }
49
50    pub fn immediate_parent(&self) -> Option<&InternalLayer> {
51        match self {
52            Base(_) => None,
53            Child(child) => Some(&*child.parent),
54            Rollup(rollup) => rollup.internal.immediate_parent(),
55        }
56    }
57
58    pub fn layer_stack_size(&self) -> usize {
59        let mut count = 1;
60        let mut l = self;
61        while let Some(p) = l.immediate_parent() {
62            l = p;
63            count += 1;
64        }
65
66        count
67    }
68
69    pub fn node_dictionary(&self) -> &StringDict {
70        match self {
71            Base(base) => &base.node_dictionary,
72            Child(child) => &child.node_dictionary,
73            Rollup(rollup) => rollup.internal.node_dictionary(),
74        }
75    }
76
77    pub fn predicate_dictionary(&self) -> &StringDict {
78        match self {
79            Base(base) => &base.predicate_dictionary,
80            Child(child) => &child.predicate_dictionary,
81            Rollup(rollup) => rollup.internal.predicate_dictionary(),
82        }
83    }
84
85    pub fn value_dictionary(&self) -> &TypedDict {
86        match self {
87            Base(base) => &base.value_dictionary,
88            Child(child) => &child.value_dictionary,
89            Rollup(rollup) => rollup.internal.value_dictionary(),
90        }
91    }
92
93    pub fn node_value_id_map(&self) -> &IdMap {
94        match self {
95            Base(base) => &base.node_value_idmap,
96            Child(child) => &child.node_value_idmap,
97            Rollup(rollup) => rollup.internal.node_value_id_map(),
98        }
99    }
100
101    pub fn predicate_id_map(&self) -> &IdMap {
102        match self {
103            Base(base) => &base.predicate_idmap,
104            Child(child) => &child.predicate_idmap,
105            Rollup(rollup) => rollup.internal.predicate_id_map(),
106        }
107    }
108
109    pub fn parent_node_value_count(&self) -> usize {
110        match self {
111            Base(_) => 0,
112            Child(child) => child.parent_node_value_count,
113            Rollup(rollup) => rollup.internal.parent_node_value_count(),
114        }
115    }
116
117    pub fn parent_predicate_count(&self) -> usize {
118        match self {
119            Base(_) => 0,
120            Child(child) => child.parent_predicate_count,
121            Rollup(rollup) => rollup.internal.parent_predicate_count(),
122        }
123    }
124
125    pub fn pos_s_p_adjacency_list(&self) -> &AdjacencyList {
126        match self {
127            Base(base) => &base.s_p_adjacency_list,
128            Child(child) => &child.pos_s_p_adjacency_list,
129            Rollup(rollup) => rollup.internal.pos_s_p_adjacency_list(),
130        }
131    }
132
133    pub fn pos_sp_o_adjacency_list(&self) -> &AdjacencyList {
134        match self {
135            Base(base) => &base.sp_o_adjacency_list,
136            Child(child) => &child.pos_sp_o_adjacency_list,
137            Rollup(rollup) => rollup.internal.pos_sp_o_adjacency_list(),
138        }
139    }
140
141    pub fn pos_o_ps_adjacency_list(&self) -> &AdjacencyList {
142        match self {
143            Base(base) => &base.o_ps_adjacency_list,
144            Child(child) => &child.pos_o_ps_adjacency_list,
145            Rollup(rollup) => rollup.internal.pos_o_ps_adjacency_list(),
146        }
147    }
148
149    pub fn neg_s_p_adjacency_list(&self) -> Option<&AdjacencyList> {
150        match self {
151            Base(_) => None,
152            Child(child) => Some(&child.neg_s_p_adjacency_list),
153            Rollup(rollup) => rollup.internal.neg_s_p_adjacency_list(),
154        }
155    }
156
157    pub fn neg_sp_o_adjacency_list(&self) -> Option<&AdjacencyList> {
158        match self {
159            Base(_) => None,
160            Child(child) => Some(&child.neg_sp_o_adjacency_list),
161            Rollup(rollup) => rollup.internal.neg_sp_o_adjacency_list(),
162        }
163    }
164
165    pub fn neg_o_ps_adjacency_list(&self) -> Option<&AdjacencyList> {
166        match self {
167            Base(_) => None,
168            Child(child) => Some(&child.neg_o_ps_adjacency_list),
169            Rollup(rollup) => rollup.internal.neg_o_ps_adjacency_list(),
170        }
171    }
172
173    pub fn pos_predicate_wavelet_tree(&self) -> &WaveletTree {
174        match self {
175            Base(base) => &base.predicate_wavelet_tree,
176            Child(child) => &child.pos_predicate_wavelet_tree,
177            Rollup(rollup) => rollup.internal.pos_predicate_wavelet_tree(),
178        }
179    }
180
181    pub fn neg_predicate_wavelet_tree(&self) -> Option<&WaveletTree> {
182        match self {
183            Base(_) => None,
184            Child(child) => Some(&child.neg_predicate_wavelet_tree),
185            Rollup(rollup) => rollup.internal.neg_predicate_wavelet_tree(),
186        }
187    }
188
189    pub fn pos_subjects(&self) -> Option<&MonotonicLogArray> {
190        match self {
191            Base(base) => base.subjects.as_ref(),
192            Child(child) => Some(&child.pos_subjects),
193            Rollup(rollup) => rollup.internal.pos_subjects(),
194        }
195    }
196
197    pub fn pos_objects(&self) -> Option<&MonotonicLogArray> {
198        match self {
199            Base(base) => base.objects.as_ref(),
200            Child(child) => Some(&child.pos_objects),
201            Rollup(rollup) => rollup.internal.pos_objects(),
202        }
203    }
204
205    pub fn neg_subjects(&self) -> Option<&MonotonicLogArray> {
206        match self {
207            Base(_) => None,
208            Child(child) => Some(&child.neg_subjects),
209            Rollup(rollup) => rollup.internal.neg_subjects(),
210        }
211    }
212
213    pub fn neg_objects(&self) -> Option<&MonotonicLogArray> {
214        match self {
215            Base(_) => None,
216            Child(child) => Some(&child.neg_objects),
217            Rollup(rollup) => rollup.internal.neg_objects(),
218        }
219    }
220
221    pub fn predicate_dict_get(&self, id: usize) -> Option<String> {
222        self.predicate_dictionary().get(id)
223    }
224
225    pub fn predicate_dict_len(&self) -> usize {
226        self.predicate_dictionary().num_entries()
227    }
228
229    pub fn predicate_dict_id(&self, predicate: &str) -> IdLookupResult {
230        self.predicate_dictionary().id(&predicate)
231    }
232
233    pub fn node_dict_id(&self, subject: &str) -> IdLookupResult {
234        self.node_dictionary().id(&subject)
235    }
236
237    pub fn node_dict_get(&self, id: usize) -> Option<String> {
238        self.node_dictionary().get(id)
239    }
240
241    pub fn node_dict_len(&self) -> usize {
242        self.node_dictionary().num_entries()
243    }
244
245    pub fn value_dict_id(&self, value: &TypedDictEntry) -> IdLookupResult {
246        self.value_dictionary().id_entry(value)
247    }
248
249    pub fn value_dict_len(&self) -> usize {
250        self.value_dictionary().num_entries()
251    }
252
253    pub fn value_dict_get(&self, id: usize) -> Option<TypedDictEntry> {
254        self.value_dictionary().entry(id)
255    }
256
257    pub fn internal_triple_addition_exists(
258        &self,
259        subject: u64,
260        predicate: u64,
261        object: u64,
262    ) -> bool {
263        layer_triple_exists(
264            self.pos_subjects(),
265            self.pos_s_p_adjacency_list(),
266            self.pos_sp_o_adjacency_list(),
267            subject,
268            predicate,
269            object,
270        )
271    }
272
273    pub fn internal_triple_removal_exists(
274        &self,
275        subject: u64,
276        predicate: u64,
277        object: u64,
278    ) -> bool {
279        match (
280            self.neg_subjects(),
281            self.neg_s_p_adjacency_list(),
282            self.neg_sp_o_adjacency_list(),
283        ) {
284            (neg_subject, Some(neg_s_p_adjacency_list), Some(neg_sp_o_adjacency_list)) => {
285                layer_triple_exists(
286                    neg_subject,
287                    neg_s_p_adjacency_list,
288                    neg_sp_o_adjacency_list,
289                    subject,
290                    predicate,
291                    object,
292                )
293            }
294            _ => false,
295        }
296    }
297
298    pub fn internal_triple_additions(&self) -> OptInternalLayerTripleSubjectIterator {
299        OptInternalLayerTripleSubjectIterator(Some(InternalLayerTripleSubjectIterator::new(
300            self.pos_subjects().cloned(),
301            self.pos_s_p_adjacency_list().clone(),
302            self.pos_sp_o_adjacency_list().clone(),
303        )))
304    }
305
306    pub fn internal_triple_removals(&self) -> OptInternalLayerTripleSubjectIterator {
307        OptInternalLayerTripleSubjectIterator(
308            match (
309                self.neg_subjects(),
310                self.neg_s_p_adjacency_list(),
311                self.neg_sp_o_adjacency_list(),
312            ) {
313                (neg_subjects, Some(neg_s_p_adjacency_list), Some(neg_sp_o_adjacency_list)) => {
314                    Some(InternalLayerTripleSubjectIterator::new(
315                        neg_subjects.cloned(),
316                        neg_s_p_adjacency_list.clone(),
317                        neg_sp_o_adjacency_list.clone(),
318                    ))
319                }
320                _ => None,
321            },
322        )
323    }
324
325    pub fn internal_triple_additions_s(
326        &self,
327        subject: u64,
328    ) -> Box<dyn Iterator<Item = IdTriple> + Send> {
329        Box::new(
330            self.internal_triple_additions()
331                .seek_subject(subject)
332                .take_while(move |t| t.subject == subject),
333        )
334    }
335
336    pub fn internal_triple_removals_s(
337        &self,
338        subject: u64,
339    ) -> Box<dyn Iterator<Item = IdTriple> + Send> {
340        Box::new(
341            self.internal_triple_removals()
342                .seek_subject(subject)
343                .take_while(move |t| t.subject == subject),
344        )
345    }
346
347    pub fn internal_triple_additions_sp(
348        &self,
349        subject: u64,
350        predicate: u64,
351    ) -> Box<dyn Iterator<Item = IdTriple> + Send> {
352        Box::new(
353            self.internal_triple_additions()
354                .seek_subject_predicate(subject, predicate)
355                .take_while(move |t| t.predicate == predicate && t.subject == subject),
356        )
357    }
358
359    pub fn internal_triple_removals_sp(
360        &self,
361        subject: u64,
362        predicate: u64,
363    ) -> Box<dyn Iterator<Item = IdTriple> + Send> {
364        Box::new(
365            self.internal_triple_removals()
366                .seek_subject_predicate(subject, predicate)
367                .take_while(move |t| t.predicate == predicate && t.subject == subject),
368        )
369    }
370
371    pub fn internal_triple_additions_p(
372        &self,
373        predicate: u64,
374    ) -> OptInternalLayerTriplePredicateIterator {
375        match self.pos_predicate_wavelet_tree().lookup(predicate) {
376            Some(lookup) => OptInternalLayerTriplePredicateIterator(Some(
377                InternalLayerTriplePredicateIterator::new(
378                    lookup,
379                    self.pos_subjects().cloned(),
380                    self.pos_s_p_adjacency_list().clone(),
381                    self.pos_sp_o_adjacency_list().clone(),
382                ),
383            )),
384            None => OptInternalLayerTriplePredicateIterator(None),
385        }
386    }
387
388    pub fn internal_triple_removals_p(
389        &self,
390        predicate: u64,
391    ) -> OptInternalLayerTriplePredicateIterator {
392        match (
393            self.neg_predicate_wavelet_tree()
394                .and_then(|t| t.lookup(predicate)),
395            self.neg_s_p_adjacency_list(),
396            self.neg_sp_o_adjacency_list(),
397        ) {
398            (Some(lookup), Some(s_p_adjacency_list), Some(sp_o_adjacency_list)) => {
399                OptInternalLayerTriplePredicateIterator(Some(
400                    InternalLayerTriplePredicateIterator::new(
401                        lookup,
402                        self.neg_subjects().cloned(),
403                        s_p_adjacency_list.clone(),
404                        sp_o_adjacency_list.clone(),
405                    ),
406                ))
407            }
408            _ => OptInternalLayerTriplePredicateIterator(None),
409        }
410    }
411
412    pub fn internal_triple_additions_o(
413        &self,
414        object: u64,
415    ) -> Box<dyn Iterator<Item = IdTriple> + Send> {
416        Box::new(
417            self.internal_triple_additions_by_object()
418                .seek_object(object)
419                .stop_at_boundary(true),
420        )
421    }
422
423    pub fn internal_triple_additions_by_object(&self) -> OptInternalLayerTripleObjectIterator {
424        OptInternalLayerTripleObjectIterator(Some(InternalLayerTripleObjectIterator::new(
425            self.pos_subjects().cloned(),
426            self.pos_objects().cloned(),
427            self.pos_o_ps_adjacency_list().clone(),
428            self.pos_s_p_adjacency_list().clone(),
429            false,
430        )))
431    }
432
433    pub fn internal_triple_removals_o(
434        &self,
435        object: u64,
436    ) -> Box<dyn Iterator<Item = IdTriple> + Send> {
437        Box::new(
438            self.internal_triple_removals_by_object()
439                .seek_object(object)
440                .stop_at_boundary(true),
441        )
442    }
443
444    pub fn internal_triple_removals_by_object(&self) -> OptInternalLayerTripleObjectIterator {
445        OptInternalLayerTripleObjectIterator(
446            match (
447                self.neg_subjects(),
448                self.neg_objects(),
449                self.neg_o_ps_adjacency_list(),
450                self.neg_s_p_adjacency_list(),
451            ) {
452                (
453                    neg_subjects,
454                    neg_objects,
455                    Some(neg_o_ps_adjacency_list),
456                    Some(neg_s_p_adjacency_list),
457                ) => Some(InternalLayerTripleObjectIterator::new(
458                    neg_subjects.cloned(),
459                    neg_objects.cloned(),
460                    neg_o_ps_adjacency_list.clone(),
461                    neg_s_p_adjacency_list.clone(),
462                    false,
463                )),
464                _ => None,
465            },
466        )
467    }
468
469    pub fn internal_triple_layer_addition_count(&self) -> usize {
470        self.pos_sp_o_adjacency_list().right_count()
471            - self
472                .pos_predicate_wavelet_tree()
473                .lookup(0)
474                .map(|l| l.len())
475                .unwrap_or(0)
476    }
477
478    pub fn internal_triple_layer_removal_count(&self) -> usize {
479        match self.neg_sp_o_adjacency_list() {
480            None => 0,
481            Some(adjacency_list) => adjacency_list.right_count()
482                - self.neg_predicate_wavelet_tree().expect("negative wavelet tree should exist when negative sp_o adjacency list exists")
483                .lookup(0).map(|l|l.len()).unwrap_or(0)
484        }
485    }
486
487    pub fn immediate_layers(&self) -> Vec<&InternalLayer> {
488        let mut layer = Some(self);
489        let mut result = Vec::new();
490
491        while let Some(l) = layer {
492            result.push(l);
493
494            layer = l.immediate_parent();
495        }
496
497        result.reverse();
498
499        result
500    }
501
502    pub fn immediate_layers_upto(&self, upto_layer_id: [u32; 5]) -> Vec<&InternalLayer> {
503        if self.name() == upto_layer_id {
504            panic!("tried to retrieve layers up to a boundary, but boundary was the top layer");
505        }
506
507        let mut layer = Some(self);
508        let mut result = Vec::new();
509
510        while let Some(l) = layer {
511            if l.name() == upto_layer_id {
512                break;
513            }
514            result.push(l);
515
516            layer = l.immediate_parent();
517        }
518
519        if layer.is_none() {
520            // we went through the whole stack and we did not find the boundary.
521            panic!("tried to find all layers up to a boundary, but boundary was not found");
522        }
523
524        result.reverse();
525
526        result
527    }
528
529    pub fn is_rollup(&self) -> bool {
530        match self {
531            Rollup(_) => true,
532            _ => false,
533        }
534    }
535}
536
537impl Layer for InternalLayer {
538    fn name(&self) -> [u32; 5] {
539        self.name()
540    }
541
542    fn parent_name(&self) -> Option<[u32; 5]> {
543        self.parent_name()
544    }
545
546    fn node_and_value_count(&self) -> usize {
547        self.parent_node_value_count()
548            + self.node_dictionary().num_entries()
549            + self.value_dictionary().num_entries()
550    }
551
552    fn predicate_count(&self) -> usize {
553        self.parent_predicate_count() + self.predicate_dictionary().num_entries()
554    }
555
556    fn subject_id<'a>(&'a self, subject: &str) -> Option<u64> {
557        let to_result = |layer: &'a InternalLayer| {
558            (
559                layer
560                    .node_dict_id(subject)
561                    .into_option()
562                    .map(|id| layer.node_value_id_map().inner_to_outer(id)),
563                layer.immediate_parent(),
564            )
565        };
566        let mut result = to_result(self);
567        while let (None, Some(layer)) = result {
568            result = to_result(layer);
569        }
570        let (id_option, parent_option) = result;
571        id_option.map(|id| id + parent_option.map_or(0, |p| p.node_and_value_count() as u64))
572    }
573
574    fn predicate_id<'a>(&'a self, predicate: &str) -> Option<u64> {
575        let to_result = |layer: &'a InternalLayer| {
576            (
577                layer
578                    .predicate_dict_id(predicate)
579                    .into_option()
580                    .map(|id| layer.predicate_id_map().inner_to_outer(id)),
581                layer.immediate_parent(),
582            )
583        };
584        let mut result = to_result(self);
585        while let (None, Some(layer)) = result {
586            result = to_result(layer);
587        }
588        let (id_option, parent_option) = result;
589        id_option.map(|id| id + parent_option.map_or(0, |p| p.predicate_count() as u64))
590    }
591
592    fn object_node_id<'a>(&'a self, object: &str) -> Option<u64> {
593        let to_result = |layer: &'a InternalLayer| {
594            (
595                layer
596                    .node_dict_id(object)
597                    .into_option()
598                    .map(|id| layer.node_value_id_map().inner_to_outer(id)),
599                layer.immediate_parent(),
600            )
601        };
602        let mut result = to_result(self);
603        while let (None, Some(layer)) = result {
604            result = to_result(layer);
605        }
606        let (id_option, parent_option) = result;
607        id_option.map(|id| id + parent_option.map_or(0, |p| p.node_and_value_count() as u64))
608    }
609
610    fn object_value_id<'a>(&'a self, object: &TypedDictEntry) -> Option<u64> {
611        let to_result = |layer: &'a InternalLayer| {
612            (
613                layer.value_dict_id(object).into_option().map(|i| {
614                    layer
615                        .node_value_id_map()
616                        .inner_to_outer(i + layer.node_dict_len() as u64)
617                }),
618                layer.immediate_parent(),
619            )
620        };
621        let mut result = to_result(self);
622        while let (None, Some(layer)) = result {
623            result = to_result(layer);
624        }
625        let (id_option, parent_option) = result;
626        id_option.map(|id| id + parent_option.map_or(0, |p| p.node_and_value_count() as u64))
627    }
628
629    fn id_subject(&self, id: u64) -> Option<String> {
630        if id == 0 {
631            return None;
632        }
633        let mut corrected_id = id;
634        let mut current_option: Option<&InternalLayer> = Some(self);
635        let mut parent_count = self.node_and_value_count() as u64;
636        while let Some(current_layer) = current_option {
637            if let Some(parent) = current_layer.immediate_parent() {
638                parent_count = parent_count
639                    - current_layer.node_dict_len() as u64
640                    - current_layer.value_dict_len() as u64;
641                if corrected_id > parent_count as u64 {
642                    // subject, if it exists, is in this layer
643                    corrected_id -= parent_count;
644                } else {
645                    current_option = Some(parent);
646                    continue;
647                }
648            }
649
650            return current_layer.node_dict_get(
651                current_layer
652                    .node_value_id_map()
653                    .outer_to_inner(corrected_id)
654                    .try_into()
655                    .unwrap(),
656            );
657        }
658
659        None
660    }
661
662    fn id_predicate(&self, id: u64) -> Option<String> {
663        if id == 0 {
664            return None;
665        }
666        let mut current_option: Option<&InternalLayer> = Some(self);
667        let mut parent_count = self.predicate_count() as u64;
668        while let Some(current_layer) = current_option {
669            let mut corrected_id = id;
670            if let Some(parent) = current_layer.immediate_parent() {
671                parent_count -= current_layer.predicate_dict_len() as u64;
672                if corrected_id > parent_count as u64 {
673                    // subject, if it exists, is in this layer
674                    corrected_id -= parent_count;
675                } else {
676                    current_option = Some(parent);
677                    continue;
678                }
679            }
680
681            return current_layer.predicate_dict_get(
682                current_layer
683                    .predicate_id_map()
684                    .outer_to_inner(corrected_id)
685                    .try_into()
686                    .unwrap(),
687            );
688        }
689
690        None
691    }
692
693    fn id_object(&self, id: u64) -> Option<ObjectType> {
694        if id == 0 {
695            return None;
696        }
697        let mut corrected_id = id;
698        let mut current_option: Option<&InternalLayer> = Some(self);
699        let mut parent_count = self.node_and_value_count() as u64;
700        while let Some(current_layer) = current_option {
701            if let Some(parent) = current_layer.immediate_parent() {
702                parent_count = parent_count
703                    - current_layer.node_dict_len() as u64
704                    - current_layer.value_dict_len() as u64;
705
706                if corrected_id > parent_count {
707                    // object, if it exists, is in this layer
708                    corrected_id -= parent_count;
709                } else {
710                    current_option = Some(parent);
711                    continue;
712                }
713            }
714
715            corrected_id = current_layer
716                .node_value_id_map()
717                .outer_to_inner(corrected_id);
718
719            if corrected_id > current_layer.node_dict_len() as u64 {
720                // object, if it exists, must be a value
721                corrected_id -= current_layer.node_dict_len() as u64;
722                return current_layer
723                    .value_dict_get(corrected_id.try_into().unwrap())
724                    .map(ObjectType::Value);
725            } else {
726                return current_layer
727                    .node_dict_get(corrected_id.try_into().unwrap())
728                    .map(ObjectType::Node);
729            }
730        }
731
732        None
733    }
734
735    fn id_object_is_node(&self, id: u64) -> Option<bool> {
736        if id == 0 {
737            return None;
738        }
739        let mut corrected_id = id;
740        let mut current_option: Option<&InternalLayer> = Some(self);
741        let mut parent_count = self.node_and_value_count() as u64;
742        while let Some(current_layer) = current_option {
743            if let Some(parent) = current_layer.immediate_parent() {
744                parent_count = parent_count
745                    - current_layer.node_dict_len() as u64
746                    - current_layer.value_dict_len() as u64;
747
748                if corrected_id > parent_count {
749                    // object, if it exists, is in this layer
750                    corrected_id -= parent_count;
751                } else {
752                    current_option = Some(parent);
753                    continue;
754                }
755            }
756
757            corrected_id = current_layer
758                .node_value_id_map()
759                .outer_to_inner(corrected_id);
760
761            if corrected_id
762                > (current_layer.node_dict_len() + current_layer.value_dict_len()) as u64
763            {
764                return None;
765            }
766            if corrected_id > current_layer.node_dict_len() as u64 {
767                // object, if it exists, must be a value
768                return Some(false);
769            }
770
771            return Some(true);
772        }
773
774        None
775    }
776
777    fn clone_boxed(&self) -> Box<dyn Layer> {
778        Box::new(self.clone())
779    }
780
781    fn triple_addition_count(&self) -> usize {
782        let mut additions = self.internal_triple_layer_addition_count();
783
784        let mut parent = self.immediate_parent();
785        while parent.is_some() {
786            additions += parent.unwrap().internal_triple_layer_addition_count();
787
788            parent = parent.unwrap().immediate_parent();
789        }
790
791        additions
792    }
793
794    fn triple_removal_count(&self) -> usize {
795        let mut removals = self.internal_triple_layer_removal_count();
796
797        let mut parent = self.immediate_parent();
798        while parent.is_some() {
799            removals += parent.unwrap().internal_triple_layer_removal_count();
800
801            parent = parent.unwrap().immediate_parent();
802        }
803
804        removals
805    }
806
807    fn all_counts(&self) -> LayerCounts {
808        let mut node_count = self.node_dict_len();
809        let mut predicate_count = self.predicate_dict_len();
810        let mut value_count = self.value_dict_len();
811        let mut parent_option = self.immediate_parent();
812        while let Some(parent) = parent_option {
813            node_count += parent.node_dict_len();
814            predicate_count += parent.predicate_dict_len();
815            value_count += parent.value_dict_len();
816            parent_option = parent.immediate_parent();
817        }
818        LayerCounts {
819            node_count,
820            predicate_count,
821            value_count,
822        }
823    }
824
825    fn triple_exists(&self, subject: u64, predicate: u64, object: u64) -> bool {
826        if subject == 0 || predicate == 0 || object == 0 {
827            return false;
828        }
829
830        if self.internal_triple_addition_exists(subject, predicate, object) {
831            true
832        } else if self.internal_triple_removal_exists(subject, predicate, object) {
833            false
834        } else {
835            let mut parent_opt = self.immediate_parent();
836            while parent_opt.is_some() {
837                let parent = parent_opt.unwrap();
838                if parent.internal_triple_addition_exists(subject, predicate, object) {
839                    return true;
840                } else if parent.internal_triple_removal_exists(subject, predicate, object) {
841                    return false;
842                }
843
844                parent_opt = parent.immediate_parent();
845            }
846
847            false
848        }
849    }
850
851    fn triples(&self) -> Box<dyn Iterator<Item = IdTriple> + Send> {
852        Box::new(InternalTripleSubjectIterator::from_layer(self))
853    }
854
855    fn triples_s(&self, subject: u64) -> Box<dyn Iterator<Item = IdTriple> + Send> {
856        Box::new(
857            InternalTripleSubjectIterator::from_layer(self)
858                .seek_subject(subject)
859                .take_while(move |t| t.subject == subject),
860        )
861    }
862
863    fn triples_sp(
864        &self,
865        subject: u64,
866        predicate: u64,
867    ) -> Box<dyn Iterator<Item = IdTriple> + Send> {
868        Box::new(
869            InternalTripleSubjectIterator::from_layer(self)
870                .seek_subject_predicate(subject, predicate)
871                .take_while(move |t| t.subject == subject && t.predicate == predicate),
872        )
873    }
874
875    fn triples_p(&self, predicate: u64) -> Box<dyn Iterator<Item = IdTriple> + Send> {
876        Box::new(InternalTriplePredicateIterator::from_layer(self, predicate))
877    }
878
879    fn triples_o(&self, object: u64) -> Box<dyn Iterator<Item = IdTriple> + Send> {
880        Box::new(
881            InternalTripleObjectIterator::from_layer(self)
882                .seek_object(object)
883                .take_while(move |t| t.object == object),
884        )
885    }
886
887    fn single_triple_sp(&self, subject: u64, predicate: u64) -> Option<IdTriple> {
888        // is subject/predicate in the positives? we're in luck
889        if let Some(pos) = sp_o_position(
890            self.pos_subjects(),
891            self.pos_s_p_adjacency_list(),
892            self.pos_sp_o_adjacency_list(),
893            subject,
894            predicate,
895        ) {
896            return Some(IdTriple {
897                subject,
898                predicate,
899                object: self.pos_sp_o_adjacency_list().num_at_pos(pos),
900            });
901        }
902
903        // alas, it's not in there.
904        let mut exclude = HashSet::new();
905        let mut l = self;
906        loop {
907            if let Some(parent) = l.immediate_parent() {
908                if let Some(neg_sp_o_adjacency_list) = l.neg_sp_o_adjacency_list() {
909                    if let Some(mut pos) = sp_o_position(
910                        l.neg_subjects(),
911                        l.neg_s_p_adjacency_list().unwrap(),
912                        neg_sp_o_adjacency_list,
913                        subject,
914                        predicate,
915                    ) {
916                        loop {
917                            exclude.insert(neg_sp_o_adjacency_list.num_at_pos(pos));
918                            if neg_sp_o_adjacency_list.bit_at_pos(pos) {
919                                break;
920                            }
921                            pos += 1;
922                        }
923                    }
924                }
925
926                let pos_sp_o_adjacency_list = parent.pos_sp_o_adjacency_list();
927                if let Some(mut pos) = sp_o_position(
928                    parent.pos_subjects(),
929                    parent.pos_s_p_adjacency_list(),
930                    pos_sp_o_adjacency_list,
931                    subject,
932                    predicate,
933                ) {
934                    // we need to iterate through the positives until we find an element that is not excluded
935                    loop {
936                        let num = pos_sp_o_adjacency_list.num_at_pos(pos);
937                        if !exclude.contains(&num) {
938                            return Some(IdTriple {
939                                subject,
940                                predicate,
941                                object: num,
942                            });
943                        }
944
945                        if pos_sp_o_adjacency_list.bit_at_pos(pos) {
946                            break;
947                        }
948                        pos += 1;
949                    }
950                }
951
952                l = parent;
953            } else {
954                return None;
955            }
956        }
957    }
958}
959
960impl From<BaseLayer> for InternalLayer {
961    fn from(layer: BaseLayer) -> InternalLayer {
962        InternalLayer::Base(layer)
963    }
964}
965
966impl From<ChildLayer> for InternalLayer {
967    fn from(layer: ChildLayer) -> InternalLayer {
968        InternalLayer::Child(layer)
969    }
970}
971
972impl From<RollupLayer> for InternalLayer {
973    fn from(layer: RollupLayer) -> InternalLayer {
974        InternalLayer::Rollup(layer)
975    }
976}
977
978fn sp_o_position(
979    subjects: Option<&MonotonicLogArray>,
980    s_p_adjacency_list: &AdjacencyList,
981    sp_o_adjacency_list: &AdjacencyList,
982    subject: u64,
983    predicate: u64,
984) -> Option<u64> {
985    if subject == 0 || predicate == 0 {
986        return None;
987    }
988
989    let s_position = match subjects {
990        None => {
991            if subject > s_p_adjacency_list.left_count() as u64 {
992                return None;
993            } else {
994                subject - 1
995            }
996        }
997        Some(subjects) => match subjects.index_of(subject) {
998            Some(pos) => pos as u64,
999            None => return None,
1000        },
1001    };
1002
1003    let mut s_p_position = s_p_adjacency_list.offset_for(s_position + 1);
1004    loop {
1005        let bit = s_p_adjacency_list.bit_at_pos(s_p_position);
1006        if s_p_adjacency_list.num_at_pos(s_p_position) == predicate {
1007            break;
1008        }
1009
1010        if bit {
1011            // moved past the end for this subject. triple isn't here.
1012            return None;
1013        }
1014
1015        s_p_position += 1;
1016    }
1017
1018    Some(sp_o_adjacency_list.offset_for(s_p_position + 1))
1019}
1020
1021pub(crate) fn layer_triple_exists(
1022    subjects: Option<&MonotonicLogArray>,
1023    s_p_adjacency_list: &AdjacencyList,
1024    sp_o_adjacency_list: &AdjacencyList,
1025    subject: u64,
1026    predicate: u64,
1027    object: u64,
1028) -> bool {
1029    if object == 0 {
1030        return false;
1031    }
1032
1033    let mut sp_o_position = match sp_o_position(
1034        subjects,
1035        s_p_adjacency_list,
1036        sp_o_adjacency_list,
1037        subject,
1038        predicate,
1039    ) {
1040        Some(p) => p,
1041        None => return false,
1042    };
1043
1044    loop {
1045        let bit = sp_o_adjacency_list.bit_at_pos(sp_o_position);
1046        if sp_o_adjacency_list.num_at_pos(sp_o_position) == object {
1047            // yay we found it
1048            return true;
1049        }
1050
1051        if bit {
1052            // moved past the end for this subject-predicate pair. triple isn't here.
1053            break;
1054        }
1055
1056        sp_o_position += 1;
1057    }
1058
1059    false
1060}
1061
1062#[cfg(test)]
1063mod tests {
1064    use tempfile::tempdir;
1065
1066    use super::*;
1067    use crate::open_directory_store;
1068    use crate::store::sync::*;
1069
1070    fn create_base_layer(store: &SyncStore) -> SyncStoreLayer {
1071        let builder = store.create_base_layer().unwrap();
1072
1073        builder
1074            .add_value_triple(ValueTriple::new_string_value("cow", "says", "moo"))
1075            .unwrap();
1076        builder
1077            .add_value_triple(ValueTriple::new_node("cow", "likes", "duck"))
1078            .unwrap();
1079        builder
1080            .add_value_triple(ValueTriple::new_string_value("duck", "says", "quack"))
1081            .unwrap();
1082
1083        builder.commit().unwrap()
1084    }
1085
1086    #[test]
1087    fn base_layer_addition_count() {
1088        let store = open_sync_memory_store();
1089
1090        let layer = create_base_layer(&store);
1091
1092        assert_eq!(3, layer.triple_layer_addition_count().unwrap());
1093    }
1094
1095    #[test]
1096    fn child_layer_addition_removal_count() {
1097        let store = open_sync_memory_store();
1098        let base_layer = create_base_layer(&store);
1099        let builder = base_layer.open_write().unwrap();
1100
1101        builder
1102            .remove_value_triple(ValueTriple::new_string_value("cow", "says", "moo"))
1103            .unwrap();
1104        builder
1105            .add_value_triple(ValueTriple::new_string_value("horse", "says", "neigh"))
1106            .unwrap();
1107
1108        let layer = builder.commit().unwrap();
1109
1110        assert_eq!(1, layer.triple_layer_addition_count().unwrap());
1111        assert_eq!(1, layer.triple_layer_removal_count().unwrap());
1112    }
1113
1114    use crate::layer::base::base_tests::*;
1115    #[tokio::test]
1116    async fn base_layer_with_gaps_addition_count() {
1117        let files = base_layer_files();
1118
1119        let nodes = vec!["aaaaa", "baa", "bbbbb", "ccccc", "mooo"];
1120        let predicates = vec!["abcde", "fghij", "klmno", "lll"];
1121        let values = vec!["chicken", "cow", "dog", "pig", "zebra"];
1122
1123        let mut builder = BaseLayerFileBuilder::from_files(&files).await.unwrap();
1124        builder.add_nodes(nodes.into_iter().map(|s| s.to_string()));
1125        builder.add_predicates(predicates.into_iter().map(|s| s.to_string()));
1126        builder.add_values(values.into_iter().map(|s| String::make_entry(&s)));
1127        let mut builder = builder.into_phase2().await.unwrap();
1128        builder.add_triple(3, 3, 3).await.unwrap();
1129        builder.finalize().await.unwrap();
1130
1131        let layer = BaseLayer::load_from_files([1, 2, 3, 4, 5], &files)
1132            .await
1133            .unwrap();
1134
1135        assert_eq!(1, layer.internal_triple_layer_addition_count());
1136    }
1137
1138    #[tokio::test]
1139    async fn object_is_node_in_base_layer() {
1140        let dir = tempdir().unwrap();
1141        let store = open_directory_store(dir.path());
1142        let builder = store.create_base_layer().await.unwrap();
1143        builder
1144            .add_value_triple(ValueTriple::new_node("foo", "links_to", "bar"))
1145            .unwrap();
1146        builder
1147            .add_value_triple(ValueTriple::new_string_value("foo", "links_to_data", "wow"))
1148            .unwrap();
1149        let layer = builder.commit().await.unwrap();
1150        assert_eq!(Some(true), layer.id_object_is_node(1));
1151        assert_eq!(Some(true), layer.id_object_is_node(2));
1152        assert_eq!(Some(false), layer.id_object_is_node(3));
1153        assert_eq!(None, layer.id_object_is_node(4));
1154    }
1155}