1use core::{fmt, hash::Hash};
2use std::{
3 borrow::Borrow,
4 collections::{BTreeMap, BTreeSet},
5};
6
7use educe::Educe;
8use rdf_types::Triple;
9
10use crate::GraphView;
11
12use super::GraphPatternMatching;
13
14#[derive(Educe, Clone)]
16#[educe(PartialEq(bound = "S: Ord, P: Ord, O: Ord"))]
17#[educe(Eq(bound = "S: Ord, P: Ord, O: Ord"))]
18#[educe(Ord(bound = "S: Ord, P: Ord, O: Ord"))]
19#[educe(Hash(bound = "S: Ord + Hash, P: Ord + Hash, O: Ord + Hash"))]
20#[educe(Default)]
21pub struct BTreeGraph<S = rdf_types::Term, P = S, O = S> {
22 pub(crate) table: BTreeMap<S, BTreeMap<P, BTreeSet<O>>>,
23 len: usize,
24}
25
26impl<S: Ord, P: Ord, O: Ord> PartialOrd for BTreeGraph<S, P, O> {
27 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
28 Some(self.cmp(other))
29 }
30}
31
32impl<S, P, O> BTreeGraph<S, P, O> {
33 pub fn new() -> Self {
35 Self::default()
36 }
37
38 pub fn len(&self) -> usize {
40 self.len
41 }
42
43 pub fn is_empty(&self) -> bool {
45 self.len == 0
46 }
47}
48
49impl<S: fmt::Debug, P: fmt::Debug, O: fmt::Debug> fmt::Debug for BTreeGraph<S, P, O> {
50 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51 write!(f, "{{")?;
52
53 for (i, rdf_types::Triple(s, p, o)) in self.triples().enumerate() {
54 if i > 0 {
55 write!(f, ",")?;
56 }
57
58 write!(f, " {s:?} {p:?} {o:?}")?;
59 }
60
61 write!(f, " }}")
62 }
63}
64
65impl<S: Ord, P: Ord, O: Ord> BTreeGraph<S, P, O> {
66 pub fn from_graph<G: crate::SizedGraph<Subject = S, Predicate = P, Object = O>>(
68 g: G,
69 ) -> BTreeGraph<S, P, O> {
70 let len = g.len();
71
72 let mut subject_map = BTreeMap::new();
73 for (subject, predicates) in g.into_subjects() {
74 let mut predicate_map = BTreeMap::new();
75 for (predicate, objects) in predicates {
76 predicate_map.insert(predicate, objects.collect());
77 }
78
79 subject_map.insert(subject, predicate_map);
80 }
81
82 BTreeGraph {
83 table: subject_map,
84 len,
85 }
86 }
87
88 pub fn insert(&mut self, triple: Triple<S, P, O>) -> bool {
89 let (subject, predicate, object) = triple.into_parts();
90
91 let added = self
92 .table
93 .entry(subject)
94 .or_default()
95 .entry(predicate)
96 .or_default()
97 .insert(object);
98
99 if added {
100 self.len += 1;
101 }
102
103 added
104 }
105
106 pub fn absorb<G: crate::SizedGraph<Subject = S, Predicate = P, Object = O>>(
107 &mut self,
108 other: G,
109 ) {
110 let subjects = other.into_subjects();
111
112 for (subject, predicates) in subjects {
113 let this_predicates = self.table.entry(subject).or_default();
114 for (predicate, objects) in predicates {
115 let this_objects = this_predicates.entry(predicate).or_default();
116 for object in objects {
117 if this_objects.insert(object) {
118 self.len += 1
119 }
120 }
121 }
122 }
123 }
124
125 pub fn remove<T: ?Sized + Ord, U: ?Sized + Ord, V: ?Sized + Ord>(
126 &mut self,
127 Triple(s, p, o): Triple<&T, &U, &V>,
128 ) where
129 S: Borrow<T>,
130 P: Borrow<U>,
131 O: Borrow<V>,
132 {
133 if let Some(predicates) = self.table.get_mut(s) {
134 if let Some(objects) = predicates.get_mut(p) {
135 if objects.remove(o) {
136 self.len -= 1;
137 if objects.is_empty() {
138 predicates.remove(p).unwrap();
139 if predicates.is_empty() {
140 self.table.remove(s);
141 }
142 }
143 }
144 }
145 }
146 }
147
148 pub fn take<T: ?Sized + Ord, U: ?Sized + Ord, V: ?Sized + Ord>(
149 &mut self,
150 Triple(s, p, o): Triple<&T, &U, &V>,
151 ) -> Option<Triple<S, P, O>>
152 where
153 S: Clone + Borrow<T>,
154 P: Clone + Borrow<U>,
155 O: Borrow<V>,
156 {
157 if let Some(predicates) = self.table.get_mut(s) {
158 if let Some(objects) = predicates.get_mut(p) {
159 if let Some(o) = objects.take(o) {
160 let (s, p) = if objects.is_empty() {
161 let p = predicates.remove_entry(p).unwrap().0;
162 let s = if predicates.is_empty() {
163 self.table.remove_entry(s).unwrap().0
164 } else {
165 self.table.get_key_value(s).unwrap().0.clone()
166 };
167
168 (s, p)
169 } else {
170 let p = predicates.get_key_value(p).unwrap().0.clone();
171 let s = self.table.get_key_value(s).unwrap().0.clone();
172 (s, p)
173 };
174
175 self.len -= 1;
176 return Some(Triple(s, p, o));
177 }
178 }
179 }
180
181 None
182 }
183
184 pub fn take_match<T: ?Sized + Ord, U: ?Sized + Ord, V: ?Sized + Ord>(
185 &mut self,
186 Triple(s, p, o): Triple<Option<&T>, Option<&U>, Option<&V>>,
187 ) -> Option<Triple<S, P, O>>
188 where
189 S: Clone + Borrow<T>,
190 P: Clone + Borrow<U>,
191 O: Borrow<V>,
192 {
193 fn take_object_match<O: Borrow<V> + Ord, V: ?Sized + Ord>(
194 objects: &mut BTreeSet<O>,
195 o: Option<&V>,
196 ) -> Option<O> {
197 match o {
198 Some(o) => objects.take(o),
199 None => objects.pop_first(),
200 }
201 }
202
203 fn take_predicate_match<
204 P: Borrow<U> + Clone + Ord,
205 O: Borrow<V> + Ord,
206 U: ?Sized + Ord,
207 V: ?Sized + Ord,
208 >(
209 predicates: &mut BTreeMap<P, BTreeSet<O>>,
210 p: Option<&U>,
211 o: Option<&V>,
212 ) -> Option<(P, O)> {
213 match p {
214 Some(p) => {
215 let objects = predicates.get_mut(p)?;
216 let o = take_object_match(objects, o)?;
217
218 let p = if objects.is_empty() {
219 predicates.remove_entry(p).unwrap().0
220 } else {
221 predicates.get_key_value(p).unwrap().0.clone()
222 };
223
224 Some((p, o))
225 }
226 None => {
227 for (p, objects) in &mut *predicates {
228 if let Some(o) = take_object_match(objects, o) {
229 let p = p.clone();
230
231 if objects.is_empty() {
232 predicates.remove::<P>(&p);
233 }
234
235 return Some((p, o));
236 }
237 }
238
239 None
240 }
241 }
242 }
243
244 match s {
245 Some(s) => {
246 let predicates = self.table.get_mut(s)?;
247 let (p, o) = take_predicate_match(predicates, p, o)?;
248
249 let s = if predicates.is_empty() {
250 self.table.remove_entry(s).unwrap().0
251 } else {
252 self.table.get_key_value(s).unwrap().0.clone()
253 };
254
255 self.len -= 1;
256 Some(Triple(s, p, o))
257 }
258 None => {
259 for (s, predicates) in &mut self.table {
260 if let Some((p, o)) = take_predicate_match(predicates, p, o) {
261 let s = s.clone();
262
263 if predicates.is_empty() {
264 self.table.remove::<S>(&s);
265 }
266
267 self.len -= 1;
268 return Some(Triple(s, p, o));
269 }
270 }
271
272 None
273 }
274 }
275 }
276
277 pub fn view<'a, A>(&'a self, subject: &'a S, access: A) -> GraphView<'a, Self, A> {
278 crate::Graph::view(self, subject, access)
279 }
280}
281
282impl<S, P, O> BTreeGraph<S, P, O> {
283 pub fn triples(&self) -> Iter<S, P, O> {
284 Iter {
285 subjects: self.subjects(),
286 subject: None,
287 predicates: None,
288 predicate: None,
289 objects: None,
290 }
291 }
292
293 pub fn subjects(&self) -> Subjects<S, P, O> {
294 Subjects {
295 it: self.table.iter(),
296 }
297 }
298
299 pub fn predicates(&self, subject: &S) -> Predicates<P, O>
300 where
301 S: Ord,
302 {
303 match self.table.get(subject) {
304 Some(map) => Predicates {
305 it: Some(map.iter()),
306 },
307 None => Predicates { it: None },
308 }
309 }
310
311 pub fn objects(&self, subject: &S, predicate: &P) -> Objects<O>
312 where
313 S: Ord,
314 P: Ord,
315 {
316 match self.table.get(subject) {
317 Some(map) => match map.get(predicate) {
318 Some(map) => Objects {
319 it: Some(map.iter()),
320 },
321 None => Objects { it: None },
322 },
323 None => Objects { it: None },
324 }
325 }
326
327 pub fn contains(&self, Triple(subject, predicate, object): Triple<&S, &P, &O>) -> bool
328 where
329 S: Ord,
330 P: Ord,
331 O: Ord,
332 {
333 match self.table.get(subject) {
334 Some(map) => match map.get(predicate) {
335 Some(map) => map.contains(object),
336 None => false,
337 },
338 None => false,
339 }
340 }
341
342 pub fn into_triples(self) -> IntoIter<S, P, O> {
343 IntoIter {
344 subjects: self.into_subjects(),
345 subject: None,
346 predicates: None,
347 predicate: None,
348 objects: None,
349 }
350 }
351
352 pub fn into_subjects(self) -> IntoSubjects<S, P, O> {
353 IntoSubjects {
354 it: self.table.into_iter(),
355 }
356 }
357
358 pub fn into_predicates(mut self, subject: &S) -> IntoPredicates<P, O>
359 where
360 S: Ord,
361 {
362 match self.table.remove(subject) {
363 Some(map) => IntoPredicates {
364 it: Some(map.into_iter()),
365 },
366 None => IntoPredicates { it: None },
367 }
368 }
369
370 pub fn into_objects(mut self, subject: &S, predicate: &P) -> IntoObjects<O>
371 where
372 S: Ord,
373 P: Ord,
374 {
375 match self.table.remove(subject) {
376 Some(mut map) => match map.remove(predicate) {
377 Some(map) => IntoObjects {
378 it: Some(map.into_iter()),
379 },
380 None => IntoObjects { it: None },
381 },
382 None => IntoObjects { it: None },
383 }
384 }
385}
386
387impl<S: Ord, P: Ord, O: Ord> crate::Graph for BTreeGraph<S, P, O> {
388 type Subject = S;
389 type Predicate = P;
390 type Object = O;
391
392 type Objects<'a> = Objects<'a, O> where
393 Self: 'a,
394 O: 'a;
395 type Predicates<'a> = Predicates<'a, P, O> where
396 Self: 'a,
397 P: 'a,
398 O: 'a;
399 type Subjects<'a> = Subjects<'a, S, P, O> where
400 Self: 'a,
401 S: 'a,
402 P: 'a,
403 O: 'a;
404 type Triples<'a> = Iter<'a, S, P, O> where
405 Self: 'a,
406 S: 'a,
407 P: 'a,
408 O: 'a;
409
410 type PatternMatching<'a, 'p> = GraphPatternMatching<'a, 'p, S, P, O> where
411 Self: 'a,
412 S: 'a + 'p,
413 P: 'a + 'p,
414 O: 'a + 'p;
415
416 #[inline(always)]
417 fn len(&self) -> usize {
418 self.len()
419 }
420
421 fn triples(&self) -> Iter<S, P, O> {
422 self.triples()
423 }
424
425 fn subjects(&self) -> Subjects<S, P, O> {
426 self.subjects()
427 }
428
429 fn predicates(&self, subject: &S) -> Predicates<P, O> {
430 self.predicates(subject)
431 }
432
433 fn objects(&self, subject: &S, predicate: &P) -> Objects<O> {
434 self.objects(subject, predicate)
435 }
436
437 fn contains(&self, triple: Triple<&S, &P, &O>) -> bool {
438 self.contains(triple)
439 }
440
441 fn pattern_matching<'p>(
442 &self,
443 pattern: Triple<
444 Option<&'p Self::Subject>,
445 Option<&'p Self::Predicate>,
446 Option<&'p Self::Object>,
447 >,
448 ) -> Self::PatternMatching<'_, 'p> {
449 GraphPatternMatching::new(self, pattern)
450 }
451}
452
453impl<S: Ord, P: Ord, O: Ord> BTreeGraph<S, P, O> {
454 crate::macros::reflect_graph_impl!();
455}
456
457impl<'a, S, P, O> std::iter::IntoIterator for &'a BTreeGraph<S, P, O> {
458 type IntoIter = Iter<'a, S, P, O>;
459 type Item = Triple<&'a S, &'a P, &'a O>;
460
461 fn into_iter(self) -> Self::IntoIter {
462 self.triples()
463 }
464}
465
466impl<S: Clone + Ord, P: Clone + Ord, O: Ord> crate::SizedGraph for BTreeGraph<S, P, O> {
467 type IntoObjects = IntoObjects<O>;
468 type IntoPredicates = IntoPredicates<P, O>;
469 type IntoSubjects = IntoSubjects<S, P, O>;
470 type IntoTriples = IntoIter<S, P, O>;
471
472 fn into_triples(self) -> IntoIter<S, P, O> {
473 self.into_triples()
474 }
475
476 fn into_subjects(self) -> IntoSubjects<S, P, O> {
477 self.into_subjects()
478 }
479
480 fn into_predicates(self, subject: &S) -> IntoPredicates<P, O> {
481 self.into_predicates(subject)
482 }
483
484 fn into_objects(self, subject: &S, predicate: &P) -> IntoObjects<O> {
485 self.into_objects(subject, predicate)
486 }
487}
488
489impl<S: Clone, P: Clone, O> IntoIterator for BTreeGraph<S, P, O> {
490 type IntoIter = IntoIter<S, P, O>;
491 type Item = Triple<S, P, O>;
492
493 fn into_iter(self) -> Self::IntoIter {
494 self.into_triples()
495 }
496}
497
498impl<S: Ord, P: Ord, O: Ord> crate::MutableGraph for BTreeGraph<S, P, O> {
499 fn insert(&mut self, triple: Triple<S, P, O>) -> bool {
500 self.insert(triple)
501 }
502
503 fn remove(
504 &mut self,
505 triple: Triple<
506 &<Self as crate::Graph>::Subject,
507 &<Self as crate::Graph>::Predicate,
508 &<Self as crate::Graph>::Object,
509 >,
510 ) {
511 self.remove(triple)
512 }
513
514 fn absorb<G: crate::SizedGraph<Subject = S, Predicate = P, Object = O>>(&mut self, other: G) {
515 self.absorb(other)
516 }
517}
518
519impl<
520 S: Clone + Borrow<T> + Ord,
521 P: Clone + Borrow<U> + Ord,
522 O: Borrow<V> + Ord,
523 T: ?Sized + Ord,
524 U: ?Sized + Ord,
525 V: ?Sized + Ord,
526 > crate::GraphTake<T, U, V> for BTreeGraph<S, P, O>
527{
528 fn take(
529 &mut self,
530 triple: Triple<&T, &U, &V>,
531 ) -> Option<Triple<Self::Subject, Self::Predicate, Self::Object>> {
532 self.take(triple)
533 }
534
535 fn take_match(
536 &mut self,
537 triple: Triple<Option<&T>, Option<&U>, Option<&V>>,
538 ) -> Option<Triple<Self::Subject, Self::Predicate, Self::Object>> {
539 self.take_match(triple)
540 }
541}
542
543#[derive(Educe)]
544#[educe(Clone)]
545pub struct Subjects<'a, S, P, O> {
546 it: std::collections::btree_map::Iter<'a, S, BTreeMap<P, BTreeSet<O>>>,
547}
548
549impl<'a, S, P, O> Iterator for Subjects<'a, S, P, O> {
550 type Item = (&'a S, Predicates<'a, P, O>);
551
552 fn next(&mut self) -> Option<Self::Item> {
553 self.it.next().map(|(subject, map)| {
554 (
555 subject,
556 Predicates {
557 it: Some(map.iter()),
558 },
559 )
560 })
561 }
562}
563
564pub struct IntoSubjects<S, P, O> {
565 it: std::collections::btree_map::IntoIter<S, BTreeMap<P, BTreeSet<O>>>,
566}
567
568impl<S, P, O> Iterator for IntoSubjects<S, P, O> {
569 type Item = (S, IntoPredicates<P, O>);
570
571 fn next(&mut self) -> Option<Self::Item> {
572 self.it.next().map(|(subject, map)| {
573 (
574 subject,
575 IntoPredicates {
576 it: Some(map.into_iter()),
577 },
578 )
579 })
580 }
581}
582
583#[derive(Educe)]
584#[educe(Clone)]
585pub struct Predicates<'a, P, O> {
586 it: Option<std::collections::btree_map::Iter<'a, P, BTreeSet<O>>>,
587}
588
589impl<'a, P, O> Iterator for Predicates<'a, P, O> {
590 type Item = (&'a P, Objects<'a, O>);
591
592 fn next(&mut self) -> Option<Self::Item> {
593 match &mut self.it {
594 Some(it) => it.next().map(|(predicate, set)| {
595 (
596 predicate,
597 Objects {
598 it: Some(set.iter()),
599 },
600 )
601 }),
602 None => None,
603 }
604 }
605}
606
607pub struct IntoPredicates<P, O> {
608 it: Option<std::collections::btree_map::IntoIter<P, BTreeSet<O>>>,
609}
610
611impl<P, O> Iterator for IntoPredicates<P, O> {
612 type Item = (P, IntoObjects<O>);
613
614 fn next(&mut self) -> Option<Self::Item> {
615 match &mut self.it {
616 Some(it) => it.next().map(|(predicate, set)| {
617 (
618 predicate,
619 IntoObjects {
620 it: Some(set.into_iter()),
621 },
622 )
623 }),
624 None => None,
625 }
626 }
627}
628
629#[derive(Educe)]
630#[educe(Clone)]
631pub struct Objects<'a, O> {
632 it: Option<std::collections::btree_set::Iter<'a, O>>,
633}
634
635impl<'a, O> Iterator for Objects<'a, O> {
636 type Item = &'a O;
637
638 fn next(&mut self) -> Option<Self::Item> {
639 match &mut self.it {
640 Some(it) => it.next(),
641 None => None,
642 }
643 }
644}
645
646pub struct IntoObjects<O> {
647 it: Option<std::collections::btree_set::IntoIter<O>>,
648}
649
650impl<O> Iterator for IntoObjects<O> {
651 type Item = O;
652
653 fn next(&mut self) -> Option<Self::Item> {
654 match &mut self.it {
655 Some(it) => it.next(),
656 None => None,
657 }
658 }
659}
660
661#[derive(Educe)]
662#[educe(Clone)]
663pub struct Iter<'a, S, P, O> {
664 subjects: Subjects<'a, S, P, O>,
665 subject: Option<&'a S>,
666 predicates: Option<Predicates<'a, P, O>>,
667 predicate: Option<&'a P>,
668 objects: Option<Objects<'a, O>>,
669}
670
671impl<'a, S, P, O> Iterator for Iter<'a, S, P, O> {
672 type Item = Triple<&'a S, &'a P, &'a O>;
673
674 fn next(&mut self) -> Option<Self::Item> {
675 loop {
676 match &mut self.objects {
677 Some(objects) => match objects.next() {
678 Some(object) => {
679 return Some(Triple(
680 self.subject.unwrap(),
681 self.predicate.unwrap(),
682 object,
683 ))
684 }
685 None => {
686 self.objects = None;
687 }
688 },
689 None => match &mut self.predicates {
690 Some(predicates) => match predicates.next() {
691 Some((predicate, objects)) => {
692 self.predicate = Some(predicate);
693 self.objects = Some(objects)
694 }
695 None => {
696 self.predicates = None;
697 self.predicate = None;
698 }
699 },
700 None => match self.subjects.next() {
701 Some((subject, predicates)) => {
702 self.subject = Some(subject);
703 self.predicates = Some(predicates)
704 }
705 None => return None,
706 },
707 },
708 }
709 }
710 }
711}
712
713pub struct IntoIter<S, P, O> {
714 subjects: IntoSubjects<S, P, O>,
715 subject: Option<S>,
716 predicates: Option<IntoPredicates<P, O>>,
717 predicate: Option<P>,
718 objects: Option<IntoObjects<O>>,
719}
720
721impl<S: Clone, P: Clone, O> Iterator for IntoIter<S, P, O> {
722 type Item = Triple<S, P, O>;
723
724 fn next(&mut self) -> Option<Self::Item> {
725 loop {
726 match &mut self.objects {
727 Some(objects) => match objects.next() {
728 Some(object) => {
729 return Some(Triple(
730 self.subject.clone().unwrap(),
731 self.predicate.clone().unwrap(),
732 object,
733 ))
734 }
735 None => {
736 self.objects = None;
737 }
738 },
739 None => match &mut self.predicates {
740 Some(predicates) => match predicates.next() {
741 Some((predicate, objects)) => {
742 self.predicate = Some(predicate);
743 self.objects = Some(objects)
744 }
745 None => {
746 self.predicates = None;
747 self.predicate = None;
748 }
749 },
750 None => match self.subjects.next() {
751 Some((subject, predicates)) => {
752 self.subject = Some(subject);
753 self.predicates = Some(predicates)
754 }
755 None => return None,
756 },
757 },
758 }
759 }
760 }
761}
762
763impl<S: Ord, P: Ord, O: Ord> std::iter::FromIterator<Triple<S, P, O>> for BTreeGraph<S, P, O> {
764 fn from_iter<I: IntoIterator<Item = Triple<S, P, O>>>(iter: I) -> Self {
765 let mut ds = Self::new();
766 ds.extend(iter);
767 ds
768 }
769}
770
771impl<S: Ord, P: Ord, O: Ord> std::iter::Extend<Triple<S, P, O>> for BTreeGraph<S, P, O> {
772 fn extend<I: IntoIterator<Item = Triple<S, P, O>>>(&mut self, iter: I) {
773 for triple in iter {
774 self.insert(triple);
775 }
776 }
777}