dfir_rs/compiled/pull/
anti_join.rs
1use itertools::Either;
2use rustc_hash::FxHashSet;
3
4pub struct AntiJoin<'a, Key, V, Ipos>
5where
6 Key: Eq + std::hash::Hash + Clone,
7 V: Eq + std::hash::Hash + Clone,
8 Ipos: Iterator<Item = (Key, V)>,
9{
10 input_pos: Ipos,
11 neg_state: &'a mut FxHashSet<Key>,
12 pos_state: &'a mut FxHashSet<(Key, V)>,
13}
14
15impl<Key, V, Ipos> Iterator for AntiJoin<'_, Key, V, Ipos>
16where
17 Key: Eq + std::hash::Hash + Clone,
18 V: Eq + std::hash::Hash + Clone,
19 Ipos: Iterator<Item = (Key, V)>,
20{
21 type Item = (Key, V);
22
23 fn next(&mut self) -> Option<Self::Item> {
24 for item in self.input_pos.by_ref() {
25 if !self.neg_state.contains(&item.0) && !self.pos_state.contains(&item) {
26 self.pos_state.insert(item.clone());
27 return Some(item);
28 }
29 }
30
31 None
32 }
33}
34
35pub fn anti_join_into_iter<'a, Key, V, Ipos>(
36 input_pos: Ipos,
37 state_neg: &'a mut FxHashSet<Key>,
38 state_pos: &'a mut FxHashSet<(Key, V)>,
39 new_tick: bool,
40) -> impl 'a + Iterator<Item = (Key, V)>
41where
42 Key: Eq + std::hash::Hash + Clone,
43 V: Eq + std::hash::Hash + Clone,
44 Ipos: 'a + Iterator<Item = (Key, V)>,
45{
46 if new_tick {
47 Either::Left(
48 state_pos
49 .iter()
50 .filter(|kv| !state_neg.contains(&kv.0))
51 .cloned()
52 .collect::<Vec<_>>()
53 .into_iter()
54 .chain(input_pos.filter_map(|kv| {
55 if !state_neg.contains(&kv.0) {
56 state_pos.insert(kv.clone());
57 Some(kv)
58 } else {
59 None
60 }
61 })),
62 )
63 } else {
64 Either::Right(AntiJoin {
65 input_pos,
66 neg_state: state_neg,
67 pos_state: state_pos,
68 })
69 }
70}