matchmaker/
selection.rs

1use crate::Selection;
2use rustc_hash::FxBuildHasher;
3use std::sync::Mutex;
4use std::{borrow::Borrow, collections::HashMap, hash::Hash, sync::Arc};
5
6// Trait on the output type to avoid orphan rule limitations
7
8#[derive(Debug)]
9pub struct SelectionSet<T, S> {
10    selections: SelectionSetImpl<u32, S>,
11    pub identifier: fn(&T) -> (u32, S),
12}
13
14impl<T, S: Selection> SelectionSet<T, S> {
15    pub fn new(identifier: fn(&T) -> (u32, S)) -> Self {
16        Self {
17            selections: SelectionSetImpl::new(),
18            identifier,
19        }
20    }
21    
22    pub fn sel(&mut self, item: &T) -> bool {
23        let (k, v) = (self.identifier)(item);
24        self.selections.insert(k, v)
25    }
26    
27    pub fn desel(&mut self, item: &T) -> bool {
28        let (k, _v) = (self.identifier)(item);
29        self.selections.remove(&k)
30    }
31    
32    pub fn contains(&self, item: &T) -> bool {
33        let (k, _v) = (self.identifier)(item);
34        self.selections.contains(&k)
35    }
36    
37    pub fn toggle(&mut self, item: &T) {
38        let (k, v) = (self.identifier)(item);
39        if self.selections.contains(&k) {
40            self.selections.remove(&k);
41        } else {
42            self.selections.insert(k, v);
43        }
44    }
45    
46    pub fn clear(&mut self) {
47        self.selections.clear();
48    }
49    
50    pub fn len(&self) -> usize {
51        self.selections.len()
52    }
53    
54    pub fn is_empty(&self) -> bool {
55        self.selections.is_empty()
56    }
57    
58    // ------
59    
60    pub fn output(&mut self) -> impl Iterator<Item = S> {
61        let mut set = self.selections.set.lock().unwrap();
62        
63        let mut pairs: Vec<_> = set.drain().map(|(k, v)| (k.clone(), v)).collect();
64        pairs.sort_by_key(|(k, _)| k.clone());
65        pairs.into_iter().map(|(_k, v)| v)
66        
67        // std::mem::take(&mut *set).into_iter().map(|(_k,| x.1)
68    }
69    
70    pub fn map_to_vec<I>(&self, items: I) -> Vec<S>
71    where
72    I: IntoIterator,
73    I::Item: std::borrow::Borrow<T> + Send,
74    {
75        // let items_vec: Vec<I::Item> = items.into_iter().collect();
76        
77        items
78        .into_iter()
79        // .into_par_iter()
80        .map(|item| (self.identifier)(item.borrow()).1)
81        .collect()
82    }
83    
84    pub fn cycle_all_bg<I>(&self, items: I)
85    where
86    I: IntoIterator,
87    I::Item: std::borrow::Borrow<T> + Send,
88    {
89        let results: Vec<_> = items
90        .into_iter()
91        // .into_par_iter()
92        .map(|item| (self.identifier)(item.borrow()))
93        .collect();
94        
95        let selections = self.selections.clone();
96        
97        tokio::task::spawn_blocking(move || {
98            let mut all = true;
99            let mut set_guard = selections.set.lock().unwrap();
100            
101            let mut seen = 0;
102            for (i, (k, _v)) in results.iter().enumerate() {
103                if !set_guard.contains_key(k) {
104                    all = false;
105                    seen = i;
106                    break;
107                }
108            }
109            
110            if all {
111                for (k, _v) in results {
112                    set_guard.remove(&k); // swap instead of shift for speed
113                }
114            } else {
115                for (k, v) in results.into_iter().skip(seen) {
116                    set_guard.insert(k, v);
117                }
118            }
119        });
120    }
121}
122
123// ---------- Selection Set ---------------
124#[derive(Debug, Clone)]
125struct SelectionSetImpl<K: Eq + Hash, S> {
126    pub set: Arc<Mutex<HashMap<K, S, FxBuildHasher>>>,
127}
128
129impl<K: Eq + Hash, S> SelectionSetImpl<K, S>
130where
131S: Selection,
132{
133    pub fn new() -> Self {
134        Self {
135            set: Arc::new(Mutex::new(HashMap::with_hasher(FxBuildHasher::default()))),
136        }
137    }
138    
139    pub fn insert(&self, key: K, value: S) -> bool {
140        let mut set = self.set.lock().unwrap();
141        set.insert(key, value).is_none()
142    }
143    
144    pub fn remove(&self, key: &K) -> bool {
145        let mut set = self.set.lock().unwrap();
146        set.remove(key).is_some()
147    }
148    
149    pub fn contains(&self, key: &K) -> bool {
150        let set = self.set.lock().unwrap();
151        set.contains_key(key)
152    }
153    
154    pub fn clear(&self) {
155        let mut set = self.set.lock().unwrap();
156        set.clear();
157    }
158    
159    pub fn clone(&self) -> Self {
160        Self {
161            set: Arc::clone(&self.set),
162        }
163    }
164    
165    pub fn len(&self) -> usize {
166        let set = self.set.lock().unwrap();
167        set.len()
168    }
169    
170    pub fn is_empty(&self) -> bool {
171        let set = self.set.lock().unwrap();
172        set.is_empty()
173    }
174}