1use core::{fmt, hash::Hash};
2use educe::Educe;
3use hashbrown::{Equivalent, HashMap, HashSet};
4use rdf_types::Triple;
5
6use crate::GraphView;
7
8use super::GraphPatternMatching;
9
10#[derive(Educe, Clone)]
12#[educe(PartialEq(bound = "S: Eq + Hash, P: Eq + Hash, O: Eq + Hash"))]
13#[educe(Eq(bound = "S: Eq + Hash, P: Eq + Hash, O: Eq + Hash"))]
14#[educe(Default)]
15pub struct HashGraph<S = rdf_types::Term, P = S, O = S> {
16 pub(crate) table: HashMap<S, HashMap<P, HashSet<O>>>,
17 len: usize,
18}
19
20impl<S, P, O> HashGraph<S, P, O> {
21 pub fn new() -> Self {
23 Self::default()
24 }
25
26 pub fn len(&self) -> usize {
28 self.len
29 }
30
31 pub fn is_empty(&self) -> bool {
33 self.len == 0
34 }
35}
36
37impl<S: Eq + Hash, P: Eq + Hash, O: Eq + Hash> HashGraph<S, P, O> {
38 pub fn from_graph<G: crate::SizedGraph<Subject = S, Predicate = P, Object = O>>(
40 g: G,
41 ) -> HashGraph<S, P, O> {
42 let len = g.len();
43
44 let mut subject_map = HashMap::new();
45 for (subject, predicates) in g.into_subjects() {
46 let mut predicate_map = HashMap::new();
47 for (predicate, objects) in predicates {
48 predicate_map.insert(predicate, objects.collect());
49 }
50
51 subject_map.insert(subject, predicate_map);
52 }
53
54 HashGraph {
55 table: subject_map,
56 len,
57 }
58 }
59
60 pub fn insert(&mut self, triple: Triple<S, P, O>) -> bool {
61 let (subject, predicate, object) = triple.into_parts();
62
63 let added = self
64 .table
65 .entry(subject)
66 .or_default()
67 .entry(predicate)
68 .or_default()
69 .insert(object);
70
71 if added {
72 self.len += 1;
73 }
74
75 added
76 }
77
78 pub fn absorb<G: crate::SizedGraph<Subject = S, Predicate = P, Object = O>>(
79 &mut self,
80 other: G,
81 ) {
82 let subjects = other.into_subjects();
83
84 for (subject, predicates) in subjects {
85 let this_predicates = self.table.entry(subject).or_default();
86 for (predicate, objects) in predicates {
87 let this_objects = this_predicates.entry(predicate).or_default();
88 for object in objects {
89 if this_objects.insert(object) {
90 self.len += 1
91 }
92 }
93 }
94 }
95 }
96
97 pub fn remove<
98 T: ?Sized + Equivalent<S> + Hash,
99 U: ?Sized + Equivalent<P> + Hash,
100 V: ?Sized + Equivalent<O> + Hash,
101 >(
102 &mut self,
103 Triple(s, p, o): Triple<&T, &U, &V>,
104 ) {
105 if let Some(predicates) = self.table.get_mut(s) {
106 if let Some(objects) = predicates.get_mut(p) {
107 if objects.remove(o) {
108 self.len -= 1;
109 if objects.is_empty() {
110 predicates.remove(p).unwrap();
111 if predicates.is_empty() {
112 self.table.remove(s);
113 }
114 }
115 }
116 }
117 }
118 }
119
120 pub fn take<
121 T: ?Sized + Equivalent<S> + Hash,
122 U: ?Sized + Equivalent<P> + Hash,
123 V: ?Sized + Equivalent<O> + Hash,
124 >(
125 &mut self,
126 Triple(s, p, o): Triple<&T, &U, &V>,
127 ) -> Option<Triple<S, P, O>>
128 where
129 S: Clone,
130 P: Clone,
131 {
132 if let Some(predicates) = self.table.get_mut(s) {
133 if let Some(objects) = predicates.get_mut(p) {
134 if let Some(o) = objects.take(o) {
135 let (s, p) = if objects.is_empty() {
136 let p = predicates.remove_entry(p).unwrap().0;
137 let s = if predicates.is_empty() {
138 self.table.remove_entry(s).unwrap().0
139 } else {
140 self.table.get_key_value(s).unwrap().0.clone()
141 };
142
143 (s, p)
144 } else {
145 let p = predicates.get_key_value(p).unwrap().0.clone();
146 let s = self.table.get_key_value(s).unwrap().0.clone();
147 (s, p)
148 };
149
150 self.len -= 1;
151 return Some(Triple(s, p, o));
152 }
153 }
154 }
155
156 None
157 }
158
159 pub fn take_match<
160 T: ?Sized + Equivalent<S> + Hash,
161 U: ?Sized + Equivalent<P> + Hash,
162 V: ?Sized + Equivalent<O> + Hash,
163 >(
164 &mut self,
165 Triple(s, p, o): Triple<Option<&T>, Option<&U>, Option<&V>>,
166 ) -> Option<Triple<S, P, O>>
167 where
168 S: Clone,
169 P: Clone,
170 O: Clone,
171 {
172 fn take_object_match<O: Clone + Eq + Hash, V: ?Sized + Equivalent<O> + Hash>(
173 objects: &mut HashSet<O>,
174 o: Option<&V>,
175 ) -> Option<O> {
176 match o {
177 Some(o) => objects.take(o),
178 None => objects.iter().next().cloned().map(|o| {
179 objects.remove::<O>(&o);
180 o
181 }),
182 }
183 }
184
185 fn take_predicate_match<
186 P: Clone + Eq + Hash,
187 O: Clone + Eq + Hash,
188 U: ?Sized + Equivalent<P> + Hash,
189 V: ?Sized + Equivalent<O> + Hash,
190 >(
191 predicates: &mut HashMap<P, HashSet<O>>,
192 p: Option<&U>,
193 o: Option<&V>,
194 ) -> Option<(P, O)> {
195 match p {
196 Some(p) => {
197 let objects = predicates.get_mut(p)?;
198 let o = take_object_match(objects, o)?;
199
200 let p = if objects.is_empty() {
201 predicates.remove_entry(p).unwrap().0
202 } else {
203 predicates.get_key_value(p).unwrap().0.clone()
204 };
205
206 Some((p, o))
207 }
208 None => {
209 for (p, objects) in &mut *predicates {
210 if let Some(o) = take_object_match(objects, o) {
211 let p = p.clone();
212
213 if objects.is_empty() {
214 predicates.remove::<P>(&p);
215 }
216
217 return Some((p, o));
218 }
219 }
220
221 None
222 }
223 }
224 }
225
226 match s {
227 Some(s) => {
228 let predicates = self.table.get_mut(s)?;
229 let (p, o) = take_predicate_match(predicates, p, o)?;
230
231 let s = if predicates.is_empty() {
232 self.table.remove_entry(s).unwrap().0
233 } else {
234 self.table.get_key_value(s).unwrap().0.clone()
235 };
236
237 self.len -= 1;
238 Some(Triple(s, p, o))
239 }
240 None => {
241 for (s, predicates) in &mut self.table {
242 if let Some((p, o)) = take_predicate_match(predicates, p, o) {
243 let s = s.clone();
244
245 if predicates.is_empty() {
246 self.table.remove::<S>(&s);
247 }
248
249 self.len -= 1;
250 return Some(Triple(s, p, o));
251 }
252 }
253
254 None
255 }
256 }
257 }
258
259 pub fn view<'a, A>(&'a self, subject: &'a S, access: A) -> GraphView<'a, Self, A> {
260 crate::Graph::view(self, subject, access)
261 }
262}
263
264impl<S, P, O> HashGraph<S, P, O> {
265 pub fn triples(&self) -> Iter<S, P, O> {
266 Iter {
267 subjects: self.subjects(),
268 subject: None,
269 predicates: None,
270 predicate: None,
271 objects: None,
272 }
273 }
274
275 pub fn subjects(&self) -> Subjects<S, P, O> {
276 Subjects {
277 it: self.table.iter(),
278 }
279 }
280
281 pub fn predicates(&self, subject: &S) -> Predicates<P, O>
282 where
283 S: Eq + Hash,
284 {
285 match self.table.get(subject) {
286 Some(map) => Predicates {
287 it: Some(map.iter()),
288 },
289 None => Predicates { it: None },
290 }
291 }
292
293 pub fn objects(&self, subject: &S, predicate: &P) -> Objects<O>
294 where
295 S: Eq + Hash,
296 P: Eq + Hash,
297 {
298 match self.table.get(subject) {
299 Some(map) => match map.get(predicate) {
300 Some(map) => Objects {
301 it: Some(map.iter()),
302 },
303 None => Objects { it: None },
304 },
305 None => Objects { it: None },
306 }
307 }
308
309 pub fn contains(&self, Triple(subject, predicate, object): Triple<&S, &P, &O>) -> bool
310 where
311 S: Eq + Hash,
312 P: Eq + Hash,
313 O: Eq + Hash,
314 {
315 match self.table.get(subject) {
316 Some(map) => match map.get(predicate) {
317 Some(map) => map.contains(object),
318 None => false,
319 },
320 None => false,
321 }
322 }
323
324 pub fn into_triples(self) -> IntoIter<S, P, O> {
325 IntoIter {
326 subjects: self.into_subjects(),
327 subject: None,
328 predicates: None,
329 predicate: None,
330 objects: None,
331 }
332 }
333
334 pub fn into_subjects(self) -> IntoSubjects<S, P, O> {
335 IntoSubjects {
336 it: self.table.into_iter(),
337 }
338 }
339
340 pub fn into_predicates(mut self, subject: &S) -> IntoPredicates<P, O>
341 where
342 S: Eq + Hash,
343 {
344 match self.table.remove(subject) {
345 Some(map) => IntoPredicates {
346 it: Some(map.into_iter()),
347 },
348 None => IntoPredicates { it: None },
349 }
350 }
351
352 pub fn into_objects(mut self, subject: &S, predicate: &P) -> IntoObjects<O>
353 where
354 S: Eq + Hash,
355 P: Eq + Hash,
356 {
357 match self.table.remove(subject) {
358 Some(mut map) => match map.remove(predicate) {
359 Some(map) => IntoObjects {
360 it: Some(map.into_iter()),
361 },
362 None => IntoObjects { it: None },
363 },
364 None => IntoObjects { it: None },
365 }
366 }
367}
368
369impl<S: Eq + Hash, P: Eq + Hash, O: Eq + Hash> crate::Graph for HashGraph<S, P, O> {
370 type Subject = S;
371 type Predicate = P;
372 type Object = O;
373
374 type Objects<'a> = Objects<'a, O> where
375 Self: 'a,
376 O: 'a;
377 type Predicates<'a> = Predicates<'a, P, O> where
378 Self: 'a,
379 P: 'a,
380 O: 'a;
381 type Subjects<'a> = Subjects<'a, S, P, O> where
382 Self: 'a,
383 S: 'a,
384 P: 'a,
385 O: 'a;
386 type Triples<'a> = Iter<'a, S, P, O> where
387 Self: 'a,
388 S: 'a,
389 P: 'a,
390 O: 'a;
391
392 type PatternMatching<'a, 'p> = GraphPatternMatching<'a, 'p, S, P, O> where
393 Self: 'a,
394 S: 'p,
395 P: 'p,
396 O: 'p;
397
398 #[inline(always)]
399 fn len(&self) -> usize {
400 self.len()
401 }
402
403 fn triples(&self) -> Iter<S, P, O> {
404 self.triples()
405 }
406
407 fn subjects(&self) -> Subjects<S, P, O> {
408 self.subjects()
409 }
410
411 fn predicates(&self, subject: &S) -> Predicates<P, O> {
412 self.predicates(subject)
413 }
414
415 fn objects(&self, subject: &S, predicate: &P) -> Objects<O> {
416 self.objects(subject, predicate)
417 }
418
419 fn contains(&self, triple: Triple<&S, &P, &O>) -> bool {
420 self.contains(triple)
421 }
422
423 fn pattern_matching<'p>(
424 &self,
425 pattern: Triple<
426 Option<&'p Self::Subject>,
427 Option<&'p Self::Predicate>,
428 Option<&'p Self::Object>,
429 >,
430 ) -> Self::PatternMatching<'_, 'p> {
431 GraphPatternMatching::new(self, pattern)
432 }
433}
434
435impl<S: Eq + Hash, P: Eq + Hash, O: Eq + Hash> HashGraph<S, P, O> {
436 crate::macros::reflect_graph_impl!();
437}
438
439impl<'a, S, P, O> std::iter::IntoIterator for &'a HashGraph<S, P, O> {
440 type IntoIter = Iter<'a, S, P, O>;
441 type Item = Triple<&'a S, &'a P, &'a O>;
442
443 fn into_iter(self) -> Self::IntoIter {
444 self.triples()
445 }
446}
447
448impl<S: Clone + Eq + Hash, P: Clone + Eq + Hash, O: Eq + Hash> crate::SizedGraph
449 for HashGraph<S, P, O>
450{
451 type IntoObjects = IntoObjects<O>;
452 type IntoPredicates = IntoPredicates<P, O>;
453 type IntoSubjects = IntoSubjects<S, P, O>;
454 type IntoTriples = IntoIter<S, P, O>;
455
456 fn into_triples(self) -> IntoIter<S, P, O> {
457 self.into_triples()
458 }
459
460 fn into_subjects(self) -> IntoSubjects<S, P, O> {
461 self.into_subjects()
462 }
463
464 fn into_predicates(self, subject: &S) -> IntoPredicates<P, O> {
465 self.into_predicates(subject)
466 }
467
468 fn into_objects(self, subject: &S, predicate: &P) -> IntoObjects<O> {
469 self.into_objects(subject, predicate)
470 }
471}
472
473impl<S: Clone, P: Clone, O> IntoIterator for HashGraph<S, P, O> {
474 type IntoIter = IntoIter<S, P, O>;
475 type Item = Triple<S, P, O>;
476
477 fn into_iter(self) -> Self::IntoIter {
478 self.into_triples()
479 }
480}
481
482impl<S: Eq + Hash, P: Eq + Hash, O: Eq + Hash> crate::MutableGraph for HashGraph<S, P, O> {
483 fn insert(&mut self, triple: Triple<S, P, O>) -> bool {
484 self.insert(triple)
485 }
486
487 fn remove(
488 &mut self,
489 triple: Triple<
490 &<Self as crate::Graph>::Subject,
491 &<Self as crate::Graph>::Predicate,
492 &<Self as crate::Graph>::Object,
493 >,
494 ) {
495 self.remove(triple)
496 }
497
498 fn absorb<G: crate::SizedGraph<Subject = S, Predicate = P, Object = O>>(&mut self, other: G) {
499 self.absorb(other)
500 }
501}
502
503impl<
504 S: Clone + Eq + Hash,
505 P: Clone + Eq + Hash,
506 O: Clone + Eq + Hash,
507 T: ?Sized + Equivalent<S> + Hash,
508 U: ?Sized + Equivalent<P> + Hash,
509 V: ?Sized + Equivalent<O> + Hash,
510 > crate::GraphTake<T, U, V> for HashGraph<S, P, O>
511{
512 fn take(
513 &mut self,
514 triple: Triple<&T, &U, &V>,
515 ) -> Option<Triple<Self::Subject, Self::Predicate, Self::Object>> {
516 self.take(triple)
517 }
518
519 fn take_match(
520 &mut self,
521 triple: Triple<Option<&T>, Option<&U>, Option<&V>>,
522 ) -> Option<Triple<Self::Subject, Self::Predicate, Self::Object>> {
523 self.take_match(triple)
524 }
525}
526
527impl<S: fmt::Debug, P: fmt::Debug, O: fmt::Debug> fmt::Debug for HashGraph<S, P, O> {
528 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
529 write!(f, "{{")?;
530
531 for (i, rdf_types::Triple(s, p, o)) in self.triples().enumerate() {
532 if i > 0 {
533 write!(f, ",")?;
534 }
535
536 write!(f, " {s:?} {p:?} {o:?}")?;
537 }
538
539 write!(f, " }}")
540 }
541}
542
543#[derive(Educe)]
544#[educe(Clone)]
545pub struct Subjects<'a, S, P, O> {
546 it: hashbrown::hash_map::Iter<'a, S, HashMap<P, HashSet<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: hashbrown::hash_map::IntoIter<S, HashMap<P, HashSet<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<hashbrown::hash_map::Iter<'a, P, HashSet<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<hashbrown::hash_map::IntoIter<P, HashSet<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<hashbrown::hash_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<hashbrown::hash_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: Eq + Hash, P: Eq + Hash, O: Eq + Hash> std::iter::FromIterator<Triple<S, P, O>>
764 for HashGraph<S, P, O>
765{
766 fn from_iter<I: IntoIterator<Item = Triple<S, P, O>>>(iter: I) -> Self {
767 let mut ds = Self::new();
768 ds.extend(iter);
769 ds
770 }
771}
772
773impl<S: Eq + Hash, P: Eq + Hash, O: Eq + Hash> std::iter::Extend<Triple<S, P, O>>
774 for HashGraph<S, P, O>
775{
776 fn extend<I: IntoIterator<Item = Triple<S, P, O>>>(&mut self, iter: I) {
777 for quad in iter {
778 self.insert(quad);
779 }
780 }
781}