1use crate::ids::Id;
3
4pub const NUM_BITS: usize = 256;
5const BITS_PER_BYTES: usize = 8;
6
7pub fn equal_subset(start: usize, stop: usize, id1: &Id, id2: &Id) -> bool {
11 if stop == 0 {
12 return true;
13 }
14
15 let stop = stop - 1; if start > stop {
17 return true;
18 }
19 if stop >= NUM_BITS {
20 return false;
21 }
22
23 let start_index = start / BITS_PER_BYTES;
24 let stop_index = stop / BITS_PER_BYTES;
25
26 if start_index + 1 < stop_index
27 && id1.0[(start_index + 1)..stop_index] != id2.0[(start_index + 1)..stop_index]
28 {
29 return false;
30 }
31
32 let start_bit = start % BITS_PER_BYTES; let stop_bit = stop % BITS_PER_BYTES; let start_mask: i32 = -1 << start_bit; let stop_mask: i32 = (1 << (stop_bit + 1)) - 1; if start_index == stop_index {
39 let mask = start_mask & stop_mask;
41
42 let b1 = mask & id1.0[start_index] as i32;
43 let b2 = mask & id2.0[start_index] as i32;
44
45 return b1 == b2;
46 }
47
48 let start1 = start_mask & id1.0[start_index] as i32;
49 let start2 = start_mask & id2.0[start_index] as i32;
50
51 let stop1 = stop_mask & id1.0[stop_index] as i32;
52 let stop2 = stop_mask & id2.0[stop_index] as i32;
53
54 start1 == start2 && stop1 == stop2
55}
56
57#[test]
59fn test_equal_subset() {
60 let id1 = Id::from_slice(&[0xf0, 0x0f]);
62 let id2 = Id::from_slice(&[0xf0, 0x1f]);
63
64 assert!(equal_subset(0, 12, &id1, &id2));
78 assert!(!equal_subset(0, 13, &id1, &id2));
79
80 let id1 = Id::from_slice(&[0x1f, 0xf8]);
82 let id2 = Id::from_slice(&[0x10, 0x08]);
83
84 assert!(equal_subset(4, 12, &id1, &id2));
98 assert!(!equal_subset(4, 13, &id1, &id2));
99}
100
101#[test]
104fn test_equal_subset_same_byte() {
105 let id1 = Id::from_slice(&[0x18]);
106 let id2 = Id::from_slice(&[0xfc]);
107
108 assert!(equal_subset(3, 5, &id1, &id2));
122 assert!(!equal_subset(2, 5, &id1, &id2));
123 assert!(!equal_subset(3, 6, &id1, &id2));
124}
125
126#[test]
129fn test_equal_subset_bad_middle() {
130 let id1 = Id::from_slice(&[0x18, 0xe8, 0x55]);
131 let id2 = Id::from_slice(&[0x18, 0x8e, 0x55]);
132
133 assert!(!equal_subset(0, 8 * 3, &id1, &id2));
147}
148
149#[test]
152fn test_equal_subset_out_of_bounds() {
153 let id1 = Id::from_slice(&[0x18, 0xe8, 0x55]);
154 let id2 = Id::from_slice(&[0x18, 0x8e, 0x55]);
155 assert!(!equal_subset(0, 500, &id1, &id2));
156}
157
158pub fn first_difference_subset(start: usize, stop: usize, id1: &Id, id2: &Id) -> (usize, bool) {
162 if stop == 0 {
163 return (0, false);
164 }
165
166 let stop = stop - 1; if start > stop {
168 return (0, false);
169 }
170 if stop >= NUM_BITS {
171 return (0, false);
172 }
173
174 let start_index = start / BITS_PER_BYTES;
175 let stop_index = stop / BITS_PER_BYTES;
176
177 let start_bit = start % BITS_PER_BYTES; let stop_bit = stop % BITS_PER_BYTES; let start_mask: i32 = -1 << start_bit; let stop_mask: i32 = (1 << (stop_bit + 1)) - 1; if start_index == stop_index {
184 let mask = start_mask & stop_mask;
186
187 let b1 = mask & id1.0[start_index] as i32;
188 let b2 = mask & id2.0[start_index] as i32;
189 if b1 == b2 {
190 return (0, false);
191 }
192
193 let bd = b1 ^ b2;
194 return (
195 bd.trailing_zeros() as usize + start_index * BITS_PER_BYTES,
196 true,
197 );
198 }
199
200 let start1 = start_mask & id1.0[start_index] as i32;
201 let start2 = start_mask & id2.0[start_index] as i32;
202 if start1 != start2 {
203 let bd = start1 ^ start2;
204 return (
205 bd.trailing_zeros() as usize + start_index * BITS_PER_BYTES,
206 true,
207 );
208 }
209
210 for idx in (start_index + 1)..stop_index {
212 let b1 = id1.0[idx];
213 let b2 = id2.0[idx];
214 if b1 != b2 {
215 let bd = b1 ^ b2;
216 return (bd.trailing_zeros() as usize + idx * BITS_PER_BYTES, true);
217 }
218 }
219
220 let stop1 = stop_mask & id1.0[stop_index] as i32;
221 let stop2 = stop_mask & id2.0[stop_index] as i32;
222 if stop1 != stop2 {
223 let bd = stop1 ^ stop2;
224 return (
225 bd.trailing_zeros() as usize + stop_index * BITS_PER_BYTES,
226 true,
227 );
228 }
229
230 (0, false) }
232
233#[test]
235fn test_first_difference_subset() {
236 let id1 = Id::from_slice(&[0xf0, 0x0f]);
238 let id2 = Id::from_slice(&[0xf0, 0x1f]);
239
240 assert_eq!(first_difference_subset(0, 12, &id1, &id2), (0, false));
254 assert_eq!(first_difference_subset(0, 13, &id1, &id2), (12, true));
255
256 let id1 = Id::from_slice(&[0x10]);
258 let id2 = Id::from_slice(&[0x00]);
259
260 assert_eq!(first_difference_subset(0, 4, &id1, &id2), (0, false));
274 assert_eq!(first_difference_subset(0, 5, &id1, &id2), (4, true));
275}
276
277#[test]
280fn test_first_difference_equal_byte_5() {
281 let id1 = Id::from_slice(&[0x20]);
282 let id2 = Id::from_slice(&[0x00]);
283
284 assert_eq!(first_difference_subset(0, 5, &id1, &id2), (0, false));
298 assert_eq!(first_difference_subset(0, 6, &id1, &id2), (5, true));
299}
300
301#[test]
304fn test_first_difference_subset_middle() {
305 let id1 = Id::from_slice(&[0xf0, 0x0f, 0x11]);
306 let id2 = Id::from_slice(&[0xf0, 0x1f, 0xff]);
307
308 assert_eq!(first_difference_subset(0, 24, &id1, &id2), (12, true));
322 assert_eq!(first_difference_subset(0, 12, &id1, &id2), (0, false));
323}
324
325#[test]
328fn test_first_difference_vacuous() {
329 let id1 = Id::from_slice(&[0xf0, 0x0f, 0x11]);
330 let id2 = Id::from_slice(&[0xf0, 0x1f, 0xff]);
331
332 assert_eq!(first_difference_subset(0, 0, &id1, &id2), (0, false));
346}
347
348#[derive(
349 std::clone::Clone,
350 std::cmp::Eq,
351 std::cmp::Ord,
352 std::cmp::PartialEq,
353 std::cmp::PartialOrd,
354 std::fmt::Debug,
355 std::hash::Hash,
356)]
357pub enum Bit {
358 Zero,
359 One,
360}
361
362impl std::convert::From<usize> for Bit {
363 fn from(v: usize) -> Self {
364 assert!(v <= 1);
365 match v {
366 0 => Bit::Zero,
367 1 => Bit::One,
368 _ => panic!("unexpected bit value {}", v),
369 }
370 }
371}
372
373impl Bit {
374 pub fn as_usize(&self) -> usize {
376 match self {
377 Bit::Zero => 0,
378 Bit::One => 1,
379 }
380 }
381}
382
383#[derive(Debug, Clone, Copy, Eq, PartialEq)]
387pub struct Set64(u64);
388
389impl Set64 {
390 pub fn new() -> Self {
391 Self(0_u64)
392 }
393
394 pub fn add(&mut self, i: u64) {
396 self.0 |= 1 << i;
397 }
398
399 pub fn union(&mut self, s: Set64) {
401 self.0 |= s.0;
402 }
403
404 pub fn intersection(&mut self, s: Set64) {
406 self.0 &= s.0;
407 }
408
409 pub fn difference(&mut self, s: Set64) {
411 self.0 &= !(s.0);
413 }
414
415 pub fn remove(&mut self, i: u64) {
417 self.0 &= !(1 << i);
419 }
420
421 pub fn clear(&mut self) {
423 self.0 = 0;
424 }
425
426 pub fn contains(&self, i: u64) -> bool {
428 (self.0 & (1 << i)) != 0
429 }
430
431 pub fn len(&self) -> u32 {
433 u64::count_ones(self.0)
435 }
436
437 pub fn is_empty(&self) -> bool {
439 self.len() == 0
440 }
441}
442
443impl Default for Set64 {
444 fn default() -> Self {
445 Self::new()
446 }
447}
448
449impl std::fmt::Display for Set64 {
453 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
454 write!(f, "{:#16x}", self.0)
455 }
456}
457
458#[test]
460fn test_bit_set() {
461 let mut bs1 = Set64::new();
462 assert!(bs1.is_empty());
463
464 bs1.add(5);
465 assert!(bs1.len() == 1);
466 assert!(bs1.contains(5));
467
468 bs1.add(10);
469 assert!(bs1.len() == 2);
470 assert!(bs1.contains(5));
471 assert!(bs1.contains(10));
472
473 bs1.add(10);
474 assert!(bs1.len() == 2);
475 assert!(bs1.contains(5));
476 assert!(bs1.contains(10));
477
478 let mut bs2 = Set64::new();
479 assert!(bs2.is_empty());
480
481 bs2.add(0);
482 assert!(bs2.len() == 1);
483 assert!(bs2.contains(0));
484
485 bs2.union(bs1);
486 assert!(bs1.len() == 2);
487 assert!(bs1.contains(5));
488 assert!(bs1.contains(10));
489 assert!(bs2.len() == 3);
490 assert!(bs2.contains(0));
491 assert!(bs2.contains(5));
492 assert!(bs2.contains(10));
493
494 bs1.clear();
495 assert!(bs1.is_empty());
496 assert!(bs2.len() == 3);
497 assert!(bs2.contains(0));
498 assert!(bs2.contains(5));
499 assert!(bs2.contains(10));
500
501 bs1.add(63);
502 assert!(bs1.len() == 1);
503 assert!(bs1.contains(63));
504
505 bs1.add(1);
506 assert!(bs1.len() == 2);
507 assert!(bs1.contains(1));
508 assert!(bs1.contains(63));
509
510 bs1.remove(63);
511 assert!(bs1.len() == 1);
512 assert!(bs1.contains(1));
513
514 let mut bs3 = Set64::new();
515 bs3.add(0);
516 bs3.add(2);
517 bs3.add(5);
518
519 let mut bs4 = Set64::new();
520 bs4.add(2);
521 bs4.add(5);
522
523 bs3.intersection(bs4);
524
525 assert!(bs3.len() == 2);
526 assert!(bs3.contains(2));
527 assert!(bs3.contains(5));
528 assert!(bs4.len() == 2);
529 assert!(bs4.contains(2));
530 assert!(bs4.contains(5));
531
532 let mut bs5 = Set64::new();
533 bs5.add(7);
534 bs5.add(11);
535 bs5.add(9);
536
537 let mut bs6 = Set64::new();
538 bs6.add(9);
539 bs6.add(11);
540
541 bs5.difference(bs6);
542
543 assert!(bs5.len() == 1);
544 assert!(bs5.contains(7));
545 assert!(bs6.len() == 2);
546 assert!(bs6.contains(9));
547 assert!(bs6.contains(11));
548}