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