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}