1use crate::core::round_up_power_of2;
15
16pub fn shape_pair_key(k1: i32, k2: i32) -> u64 {
21 if k1 < k2 {
22 (k1 as u64) << 32 | (k2 as u64)
23 } else {
24 (k2 as u64) << 32 | (k1 as u64)
25 }
26}
27
28#[derive(Debug, Clone, Default)]
30pub struct HashSet {
31 pub(crate) items: Vec<u64>,
33 pub(crate) count: u32,
34}
35
36fn key_hash(key: u64) -> u64 {
39 let mut h = key;
40 h ^= h >> 33;
41 h = h.wrapping_mul(0xff51afd7ed558ccd);
42 h ^= h >> 33;
43 h = h.wrapping_mul(0xc4ceb9fe1a85ec53);
44 h ^= h >> 33;
45 h
46}
47
48impl HashSet {
49 pub fn new(capacity: i32) -> HashSet {
52 let capacity = if capacity > 16 {
54 round_up_power_of2(capacity)
55 } else {
56 16
57 };
58
59 HashSet {
60 items: vec![0; capacity as usize],
61 count: 0,
62 }
63 }
64
65 pub fn destroy(&mut self) {
67 self.items = Vec::new();
68 self.count = 0;
69 }
70
71 pub fn clear(&mut self) {
73 self.count = 0;
74 self.items.iter_mut().for_each(|slot| *slot = 0);
75 }
76
77 pub fn count(&self) -> i32 {
79 self.count as i32
80 }
81
82 pub fn capacity(&self) -> i32 {
84 self.items.len() as i32
85 }
86
87 pub fn bytes(&self) -> i32 {
89 self.items.len() as i32 * core::mem::size_of::<u64>() as i32
90 }
91
92 fn cap(&self) -> u32 {
93 self.items.len() as u32
94 }
95
96 fn find_slot(&self, key: u64, hash: u64) -> usize {
98 let capacity = self.cap();
99 let mut index = (hash as u32) & (capacity - 1);
100 while self.items[index as usize] != 0 && self.items[index as usize] != key {
101 index = (index + 1) & (capacity - 1);
102 }
103 index as usize
104 }
105
106 fn add_key_have_capacity(&mut self, key: u64, hash: u64) {
107 let index = self.find_slot(key, hash);
108 debug_assert!(self.items[index] == 0);
109 self.items[index] = key;
110 self.count += 1;
111 }
112
113 fn grow_table(&mut self) {
114 let old_items = core::mem::take(&mut self.items);
115
116 self.count = 0;
117 self.items = vec![0; 2 * old_items.len()];
119
120 for &key in &old_items {
122 if key == 0 {
123 continue;
125 }
126
127 let hash = key_hash(key);
128 self.add_key_have_capacity(key, hash);
129 }
130 }
131
132 pub fn contains_key(&self, key: u64) -> bool {
134 debug_assert!(key != 0);
136 let hash = key_hash(key);
137 let index = self.find_slot(key, hash);
138 self.items[index] == key
139 }
140
141 pub fn add_key(&mut self, key: u64) -> bool {
143 debug_assert!(key != 0);
145
146 let hash = key_hash(key);
147 debug_assert!(hash != 0);
148
149 let index = self.find_slot(key, hash);
150 if self.items[index] != 0 {
151 debug_assert!(self.items[index] == key);
153 return true;
154 }
155
156 if 2 * self.count >= self.cap() {
157 self.grow_table();
158 }
159
160 self.add_key_have_capacity(key, hash);
161 false
162 }
163
164 pub fn remove_key(&mut self, key: u64) -> bool {
167 let hash = key_hash(key);
168 let mut i = self.find_slot(key, hash);
169 if self.items[i] == 0 {
170 return false;
172 }
173
174 self.items[i] = 0;
176
177 debug_assert!(self.count > 0);
178 self.count -= 1;
179
180 let mask = self.items.len() - 1;
182 let mut j = i;
183 loop {
184 j = (j + 1) & mask;
185 if self.items[j] == 0 {
186 break;
187 }
188
189 let hash_j = key_hash(self.items[j]);
191 let k = (hash_j as usize) & mask;
192
193 if i <= j {
197 if i < k && k <= j {
198 continue;
199 }
200 } else if i < k || k <= j {
201 continue;
202 }
203
204 self.items[i] = self.items[j];
206
207 self.items[j] = 0;
209
210 i = j;
211 }
212
213 true
214 }
215}