1use crate::set::Set;
2use crate::{exponential_offset_ge, SetOperation, Collection};
3
4#[derive(Copy, Clone)]
24pub struct Difference<'a, T: 'a> {
25 a: &'a [T],
26 b: &'a [T],
27}
28
29impl<'a, T> Difference<'a, T> {
30 pub fn new(a: &'a Set<T>, b: &'a Set<T>) -> Self {
32 Self {
33 a: a.as_slice(),
34 b: b.as_slice(),
35 }
36 }
37}
38
39impl<'a, T: Ord> Difference<'a, T> {
40 #[inline]
41 fn extend_collection<C, U, F>(mut self, output: &mut C, extend: F)
42 where C: Collection<U>,
43 F: Fn(&mut C, &'a [T])
44 {
45 while let Some(first) = self.a.first() {
46 self.b = exponential_offset_ge(self.b, first);
47 let minimum = self.b.first();
48
49 match minimum {
50 Some(min) if min == first => self.a = exponential_offset_ge(&self.a[1..], min),
51 Some(min) => {
52 let off = self.a.iter().take_while(|&x| x < min).count();
53 extend(output, &self.a[..off]);
54
55 self.a = &self.a[off..];
56 },
57 None => {
58 extend(output, self.a);
59 break;
60 },
61 }
62 }
63 }
64}
65
66impl<'a, T: Ord + Clone> SetOperation<T> for Difference<'a, T> {
67 fn extend_collection<C>(self, output: &mut C) where C: Collection<T> {
68 self.extend_collection(output, Collection::extend_from_slice)
69 }
70}
71
72impl<'a, T: Ord> SetOperation<&'a T> for Difference<'a, T> {
73 fn extend_collection<C>(self, output: &mut C) where C: Collection<&'a T> {
74 self.extend_collection(output, Collection::extend)
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81 use crate::set::{sort_dedup_vec, SetBuf};
82
83 #[test]
84 fn two_slices() {
85 let a = &[1, 2, 3];
86 let b = &[2, 4];
87
88 let union_: SetBuf<i32> = Difference { a: a, b: b }.into_set_buf();
89 assert_eq!(&union_[..], &[1, 3]);
90 }
91
92 #[test]
93 fn two_slices_special_case() {
94 let a = &[1, 2, 3];
95 let b = &[3];
96
97 let union_: SetBuf<i32> = Difference { a: a, b: b }.into_set_buf();
98 assert_eq!(&union_[..], &[1, 2]);
99 }
100
101 quickcheck! {
102 fn qc_difference(a: Vec<i32>, b: Vec<i32>) -> bool {
103 use std::collections::BTreeSet;
104 use std::iter::FromIterator;
105
106 let mut a = a;
107 let mut b = b;
108
109 sort_dedup_vec(&mut a);
110 sort_dedup_vec(&mut b);
111
112 let x: SetBuf<i32> = Difference { a: &a, b: &b }.into_set_buf();
113
114 let a = BTreeSet::from_iter(a);
115 let b = BTreeSet::from_iter(b);
116 let y = a.difference(&b);
117 let y: Vec<_> = y.cloned().collect();
118
119 x.as_slice() == y.as_slice()
120 }
121 }
122}
123
124#[cfg(all(feature = "unstable", test))]
125mod bench {
126 extern crate test;
127 use super::*;
128 use self::test::Bencher;
129 use crate::set::SetBuf;
130
131 #[bench]
132 fn two_slices_big(bench: &mut Bencher) {
133 let a: Vec<_> = (0..100).collect();
134 let b: Vec<_> = (1..101).collect();
135
136 bench.iter(|| {
137 let difference_: SetBuf<i32> = Difference { a: &a, b: &b }.into_set_buf();
138 test::black_box(|| difference_);
139 });
140 }
141
142 #[bench]
143 fn two_slices_big2(bench: &mut Bencher) {
144 let a: Vec<_> = (0..100).collect();
145 let b: Vec<_> = (51..151).collect();
146
147 bench.iter(|| {
148 let difference_: SetBuf<i32> = Difference { a: &a, b: &b }.into_set_buf();
149 test::black_box(|| difference_);
150 });
151 }
152
153 #[bench]
154 fn two_slices_big3(bench: &mut Bencher) {
155 let a: Vec<_> = (0..100).collect();
156 let b: Vec<_> = (100..200).collect();
157
158 bench.iter(|| {
159 let difference_: SetBuf<i32> = Difference { a: &a, b: &b }.into_set_buf();
160 test::black_box(|| difference_);
161 });
162 }
163}