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 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 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 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 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 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 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 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 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 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 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 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 return true;
1049 }
1050
1051 if bit {
1052 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}