dfir_rs/compiled/pull/half_join_state/
multiset.rs1use std::collections::VecDeque;
2use std::collections::hash_map::Entry;
3
4use super::HalfJoinState;
5use crate::util::clear::Clear;
6
7type HashMap<K, V> = rustc_hash::FxHashMap<K, V>;
8
9use smallvec::{SmallVec, smallvec};
10#[derive(Debug)]
11pub struct HalfMultisetJoinState<Key, ValBuild, ValProbe> {
12 table: HashMap<Key, SmallVec<[ValBuild; 1]>>,
19 current_matches: VecDeque<(Key, ValProbe, ValBuild)>,
21 len: usize,
22}
23impl<Key, ValBuild, ValProbe> Default for HalfMultisetJoinState<Key, ValBuild, ValProbe> {
24 fn default() -> Self {
25 Self {
26 table: HashMap::default(),
27 current_matches: VecDeque::default(),
28 len: 0,
29 }
30 }
31}
32impl<Key, ValBuild, ValProbe> Clear for HalfMultisetJoinState<Key, ValBuild, ValProbe> {
33 fn clear(&mut self) {
34 self.table.clear();
35 self.current_matches.clear();
36 self.len = 0;
37 }
38}
39impl<Key, ValBuild, ValProbe> HalfJoinState<Key, ValBuild, ValProbe>
40 for HalfMultisetJoinState<Key, ValBuild, ValProbe>
41where
42 Key: Clone + Eq + std::hash::Hash,
43 ValBuild: Clone,
44 ValProbe: Clone,
45{
46 fn build(&mut self, k: Key, v: &ValBuild) -> bool {
47 let entry = self.table.entry(k);
48
49 match entry {
50 Entry::Occupied(mut e) => {
51 let vec = e.get_mut();
52
53 vec.push(v.clone());
54 self.len += 1;
55 }
56 Entry::Vacant(e) => {
57 e.insert(smallvec![v.clone()]);
58 self.len += 1;
59 }
60 };
61
62 true
63 }
64
65 fn probe(&mut self, k: &Key, v: &ValProbe) -> Option<(Key, ValProbe, ValBuild)> {
66 let mut iter = self
70 .table
71 .get(k)?
72 .iter()
73 .map(|valbuild| (k.clone(), v.clone(), valbuild.clone()));
74
75 let first = iter.next();
76
77 self.current_matches.extend(iter);
78
79 first
80 }
81
82 fn full_probe(&self, k: &Key) -> std::slice::Iter<'_, ValBuild> {
83 let Some(sv) = self.table.get(k) else {
84 return [].iter();
85 };
86
87 sv.iter()
88 }
89
90 fn pop_match(&mut self) -> Option<(Key, ValProbe, ValBuild)> {
91 self.current_matches.pop_front()
92 }
93
94 fn len(&self) -> usize {
95 self.len
96 }
97 fn iter(&self) -> std::collections::hash_map::Iter<'_, Key, SmallVec<[ValBuild; 1]>> {
98 self.table.iter()
99 }
100}