graphos_core/execution/
selection.rs1#[derive(Debug, Clone)]
7pub struct SelectionVector {
8 indices: Vec<u16>,
10}
11
12impl SelectionVector {
13 pub const MAX_CAPACITY: usize = u16::MAX as usize;
15
16 #[must_use]
18 pub fn new_all(count: usize) -> Self {
19 assert!(count <= Self::MAX_CAPACITY);
20 Self {
21 indices: (0..count as u16).collect(),
22 }
23 }
24
25 #[must_use]
27 pub fn new_empty() -> Self {
28 Self {
29 indices: Vec::new(),
30 }
31 }
32
33 #[must_use]
35 pub fn with_capacity(capacity: usize) -> Self {
36 Self {
37 indices: Vec::with_capacity(capacity.min(Self::MAX_CAPACITY)),
38 }
39 }
40
41 #[must_use]
45 pub fn from_predicate<F>(count: usize, predicate: F) -> Self
46 where
47 F: Fn(usize) -> bool,
48 {
49 let indices: Vec<u16> = (0..count)
50 .filter(|&i| predicate(i))
51 .map(|i| i as u16)
52 .collect();
53 Self { indices }
54 }
55
56 #[must_use]
58 pub fn len(&self) -> usize {
59 self.indices.len()
60 }
61
62 #[must_use]
64 pub fn is_empty(&self) -> bool {
65 self.indices.is_empty()
66 }
67
68 #[must_use]
70 pub fn get(&self, position: usize) -> Option<usize> {
71 self.indices.get(position).map(|&i| i as usize)
72 }
73
74 pub fn push(&mut self, index: usize) {
76 assert!(index <= Self::MAX_CAPACITY);
77 self.indices.push(index as u16);
78 }
79
80 #[must_use]
82 pub fn as_slice(&self) -> &[u16] {
83 &self.indices
84 }
85
86 pub fn clear(&mut self) {
88 self.indices.clear();
89 }
90
91 #[must_use]
95 pub fn filter<F>(&self, predicate: F) -> Self
96 where
97 F: Fn(usize) -> bool,
98 {
99 let indices: Vec<u16> = self
100 .indices
101 .iter()
102 .copied()
103 .filter(|&i| predicate(i as usize))
104 .collect();
105 Self { indices }
106 }
107
108 #[must_use]
110 pub fn intersect(&self, other: &Self) -> Self {
111 let mut result = Vec::new();
113 let mut i = 0;
114 let mut j = 0;
115
116 while i < self.indices.len() && j < other.indices.len() {
117 match self.indices[i].cmp(&other.indices[j]) {
118 std::cmp::Ordering::Less => i += 1,
119 std::cmp::Ordering::Greater => j += 1,
120 std::cmp::Ordering::Equal => {
121 result.push(self.indices[i]);
122 i += 1;
123 j += 1;
124 }
125 }
126 }
127
128 Self { indices: result }
129 }
130
131 #[must_use]
133 pub fn union(&self, other: &Self) -> Self {
134 let mut result = Vec::new();
135 let mut i = 0;
136 let mut j = 0;
137
138 while i < self.indices.len() && j < other.indices.len() {
139 match self.indices[i].cmp(&other.indices[j]) {
140 std::cmp::Ordering::Less => {
141 result.push(self.indices[i]);
142 i += 1;
143 }
144 std::cmp::Ordering::Greater => {
145 result.push(other.indices[j]);
146 j += 1;
147 }
148 std::cmp::Ordering::Equal => {
149 result.push(self.indices[i]);
150 i += 1;
151 j += 1;
152 }
153 }
154 }
155
156 result.extend_from_slice(&self.indices[i..]);
157 result.extend_from_slice(&other.indices[j..]);
158
159 Self { indices: result }
160 }
161
162 pub fn iter(&self) -> impl Iterator<Item = usize> + '_ {
164 self.indices.iter().map(|&i| i as usize)
165 }
166
167 #[must_use]
169 pub fn contains(&self, index: usize) -> bool {
170 if index > u16::MAX as usize {
171 return false;
172 }
173 self.indices.binary_search(&(index as u16)).is_ok()
175 }
176}
177
178impl Default for SelectionVector {
179 fn default() -> Self {
180 Self::new_empty()
181 }
182}
183
184impl IntoIterator for SelectionVector {
185 type Item = usize;
186 type IntoIter = std::iter::Map<std::vec::IntoIter<u16>, fn(u16) -> usize>;
187
188 fn into_iter(self) -> Self::IntoIter {
189 self.indices.into_iter().map(|i| i as usize)
190 }
191}
192
193#[cfg(test)]
194mod tests {
195 use super::*;
196
197 #[test]
198 fn test_selection_all() {
199 let sel = SelectionVector::new_all(10);
200 assert_eq!(sel.len(), 10);
201
202 for i in 0..10 {
203 assert_eq!(sel.get(i), Some(i));
204 }
205 }
206
207 #[test]
208 fn test_selection_from_predicate() {
209 let sel = SelectionVector::from_predicate(10, |i| i % 2 == 0);
210
211 assert_eq!(sel.len(), 5);
212 assert_eq!(sel.get(0), Some(0));
213 assert_eq!(sel.get(1), Some(2));
214 assert_eq!(sel.get(2), Some(4));
215 }
216
217 #[test]
218 fn test_selection_filter() {
219 let sel = SelectionVector::new_all(10);
220 let filtered = sel.filter(|i| i >= 5);
221
222 assert_eq!(filtered.len(), 5);
223 assert_eq!(filtered.get(0), Some(5));
224 }
225
226 #[test]
227 fn test_selection_intersect() {
228 let sel1 = SelectionVector::from_predicate(10, |i| i % 2 == 0); let sel2 = SelectionVector::from_predicate(10, |i| i % 3 == 0); let intersection = sel1.intersect(&sel2);
232 assert_eq!(intersection.len(), 2);
235 assert_eq!(intersection.get(0), Some(0));
236 assert_eq!(intersection.get(1), Some(6));
237 }
238
239 #[test]
240 fn test_selection_union() {
241 let sel1 = SelectionVector::from_predicate(10, |i| i == 1 || i == 3); let sel2 = SelectionVector::from_predicate(10, |i| i == 2 || i == 3); let union = sel1.union(&sel2);
245 assert_eq!(union.len(), 3);
248 assert_eq!(union.get(0), Some(1));
249 assert_eq!(union.get(1), Some(2));
250 assert_eq!(union.get(2), Some(3));
251 }
252
253 #[test]
254 fn test_selection_iterator() {
255 let sel = SelectionVector::from_predicate(5, |i| i < 3);
256 let collected: Vec<_> = sel.iter().collect();
257
258 assert_eq!(collected, vec![0, 1, 2]);
259 }
260}