1use crate::constants::{CHILD_MASK, SHAPE_MASK, SHAPE_POWER};
15use crate::core::round_up_power_of2;
16
17#[derive(Debug, Clone, Copy, Default)]
22#[repr(C)]
23pub struct SetItem {
24 pub key: u64,
25 pub hash: u32,
26}
27
28pub fn shape_pair_key(s1: i32, s2: i32, c: i32) -> u64 {
34 if s1 < s2 {
35 ((SHAPE_MASK & s1 as u64) << (64 - SHAPE_POWER))
36 | ((SHAPE_MASK & s2 as u64) << (64 - 2 * SHAPE_POWER))
37 | (CHILD_MASK & c as u64)
38 } else {
39 ((SHAPE_MASK & s2 as u64) << (64 - SHAPE_POWER))
40 | ((SHAPE_MASK & s1 as u64) << (64 - 2 * SHAPE_POWER))
41 | (CHILD_MASK & c as u64)
42 }
43}
44
45#[derive(Debug, Clone, Default)]
47pub struct HashSet {
48 pub(crate) items: Vec<SetItem>,
50 pub(crate) count: u32,
51}
52
53fn key_hash(key: u64) -> u32 {
58 let mut h = key;
59 h ^= h >> 33;
60 h = h.wrapping_mul(0xff51afd7ed558ccd);
61 h ^= h >> 33;
62 h = h.wrapping_mul(0xc4ceb9fe1a85ec53);
63 h ^= h >> 33;
64 h as u32
65}
66
67impl HashSet {
68 pub fn new(capacity: i32) -> HashSet {
71 let capacity = if capacity > 16 {
73 round_up_power_of2(capacity)
74 } else {
75 16
76 };
77
78 HashSet {
79 items: vec![SetItem::default(); capacity as usize],
80 count: 0,
81 }
82 }
83
84 pub fn destroy(&mut self) {
86 self.items = Vec::new();
87 self.count = 0;
88 }
89
90 pub fn clear(&mut self) {
92 self.count = 0;
93 self.items
94 .iter_mut()
95 .for_each(|slot| *slot = SetItem::default());
96 }
97
98 pub fn count(&self) -> i32 {
100 self.count as i32
101 }
102
103 pub fn capacity(&self) -> i32 {
105 self.items.len() as i32
106 }
107
108 pub fn bytes(&self) -> i32 {
110 self.items.len() as i32 * core::mem::size_of::<SetItem>() as i32
111 }
112
113 fn cap(&self) -> u32 {
114 self.items.len() as u32
115 }
116
117 fn find_slot(&self, key: u64, hash: u32) -> usize {
119 let capacity = self.cap();
120 let mut index = hash & (capacity - 1);
121 while self.items[index as usize].hash != 0 && self.items[index as usize].key != key {
122 index = (index + 1) & (capacity - 1);
123 }
124 index as usize
125 }
126
127 fn add_key_have_capacity(&mut self, key: u64, hash: u32) {
128 let index = self.find_slot(key, hash);
129 debug_assert!(self.items[index].hash == 0);
130 self.items[index].key = key;
131 self.items[index].hash = hash;
132 self.count += 1;
133 }
134
135 fn grow_table(&mut self) {
136 let old_items = core::mem::take(&mut self.items);
137
138 self.count = 0;
139 self.items = vec![SetItem::default(); 2 * old_items.len()];
141
142 for item in &old_items {
144 if item.hash == 0 {
145 continue;
147 }
148
149 self.add_key_have_capacity(item.key, item.hash);
150 }
151 }
152
153 pub fn contains_key(&self, key: u64) -> bool {
155 debug_assert!(key != 0);
157 let hash = key_hash(key);
158 let index = self.find_slot(key, hash);
159 self.items[index].key == key
160 }
161
162 pub fn add_key(&mut self, key: u64) -> bool {
164 debug_assert!(key != 0);
166
167 let hash = key_hash(key);
168 debug_assert!(hash != 0);
169
170 let index = self.find_slot(key, hash);
171 if self.items[index].hash != 0 {
172 debug_assert!(self.items[index].hash == hash && self.items[index].key == key);
174 return true;
175 }
176
177 if 2 * self.count >= self.cap() {
178 self.grow_table();
179 }
180
181 self.add_key_have_capacity(key, hash);
182 false
183 }
184
185 pub fn remove_key(&mut self, key: u64) -> bool {
188 let hash = key_hash(key);
189 let mut i = self.find_slot(key, hash);
190 if self.items[i].hash == 0 {
191 return false;
193 }
194
195 self.items[i].key = 0;
197 self.items[i].hash = 0;
198
199 debug_assert!(self.count > 0);
200 self.count -= 1;
201
202 let capacity = self.cap() as usize;
204 let mut j = i;
205 loop {
206 j = (j + 1) & (capacity - 1);
207 if self.items[j].hash == 0 {
208 break;
209 }
210
211 let k = (self.items[j].hash as usize) & (capacity - 1);
213
214 if i <= j {
218 if i < k && k <= j {
219 continue;
220 }
221 } else if i < k || k <= j {
222 continue;
223 }
224
225 self.items[i] = self.items[j];
227
228 self.items[j].key = 0;
230 self.items[j].hash = 0;
231
232 i = j;
233 }
234
235 true
236 }
237}