grdf/impl/btree_dataset/
graph.rs

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/// Graph implementation based on `BTreeMap` and `BTreeSet`.
15#[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	/// Create a new empty `BTreeGraph`.
34	pub fn new() -> Self {
35		Self::default()
36	}
37
38	/// Returns the number of triples in the graph.
39	pub fn len(&self) -> usize {
40		self.len
41	}
42
43	/// Checks if the graph is empty.
44	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	/// Create a new `BTreeGraph` from another graph by consuming its triples.
67	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}