1use crate::set::Set;
2use crate::{exponential_offset_ge_by_key, SetOperation, Collection};
3
4#[derive(Copy, Clone)]
40pub struct DifferenceByKey<'a, T: 'a, U: 'a, F, G, K>
41where F: Fn(&T) -> K,
42 G: Fn(&U) -> K,
43 K: Ord,
44{
45 a: &'a [T],
46 b: &'a [U],
47 f: F,
48 g: G,
49}
50
51impl<'a, T, U, F, G, K> DifferenceByKey<'a, T, U, F, G, K>
52where F: Fn(&T) -> K,
53 G: Fn(&U) -> K,
54 K: Ord,
55{
56 pub fn new(a: &'a Set<T>, b: &'a Set<U>, f: F, g: G) -> Self {
58 Self {
59 a: a.as_slice(),
60 b: b.as_slice(),
61 f: f,
62 g: g,
63 }
64 }
65}
66
67impl<'a, T, U, F, G, K> DifferenceByKey<'a, T, U, F, G, K>
68where F: Fn(&T) -> K,
69 G: Fn(&U) -> K,
70 K: Ord,
71{
72 fn extend_collection<C, X, E>(mut self, output: &mut C, extend: E)
73 where C: Collection<X>,
74 E: Fn(&mut C, &'a [T]),
75 {
76 while let Some(first) = self.a.first().map(|x| (self.f)(x)) {
77 self.b = exponential_offset_ge_by_key(self.b, &first, &self.g);
78
79 match self.b.first().map(|x| (self.g)(x)) {
80 Some(min) => {
81 if min == first {
82 self.a = exponential_offset_ge_by_key(&self.a[1..], &min, &self.f)
83 } else {
84 let off = self.a.iter().take_while(|&x| (self.f)(x) < min).count();
85 extend(output, &self.a[..off]);
86
87 self.a = &self.a[off..]
88 }
89 },
90 None => {
91 extend(output, self.a);
92 break;
93 },
94 }
95 }
96 }
97}
98
99impl<'a, T, U, F, G, K> SetOperation<T> for DifferenceByKey<'a, T, U, F, G, K>
100where T: Clone,
101 F: Fn(&T) -> K,
102 G: Fn(&U) -> K,
103 K: Ord,
104{
105 fn extend_collection<C>(self, output: &mut C) where C: Collection<T> {
106 self.extend_collection(output, Collection::extend_from_slice)
107 }
108}
109
110impl<'a, T, U, F, G, K> SetOperation<&'a T> for DifferenceByKey<'a, T, U, F, G, K>
111where F: Fn(&T) -> K,
112 G: Fn(&U) -> K,
113 K: Ord,
114{
115 fn extend_collection<C>(self, output: &mut C) where C: Collection<&'a T> {
116 self.extend_collection(output, Collection::extend)
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123 use crate::set::{sort_dedup_vec, SetBuf};
124
125 #[derive(Debug, Clone, PartialEq, Eq)]
126 struct Foo {
127 a: i32,
128 b: i8,
129 }
130
131 #[test]
132 fn difference_empty_no_duplicates() {
133 let a = Set::new_unchecked(&[
134 Foo{ a: 1, b: 8 },
135 Foo{ a: 2, b: 9 },
136 Foo{ a: 3, b: 10 },
137 Foo{ a: 4, b: 11 },
138 Foo{ a: 5, b: 12 },
139 ]);
140 let b = Set::new(&[1, 2, 3, 4, 5]).unwrap();
141
142 let difference: SetBuf<Foo> = DifferenceByKey::new(a, b, |x| x.a, |&x| x).into_set_buf();
143
144 assert!(difference.is_empty());
145 }
146
147 #[test]
148 fn difference_empty_duplicate_relations() {
149 let a = Set::new_unchecked(&[
150 Foo{ a: 1, b: 6 },
151 Foo{ a: 1, b: 7 },
152 Foo{ a: 1, b: 8 },
153 Foo{ a: 2, b: 9 },
154 Foo{ a: 2, b: 10 },
155 ]);
156 let b = Set::new(&[1, 2, 3, 4, 5]).unwrap();
157
158 let difference: SetBuf<Foo> = DifferenceByKey::new(a, b, |x| x.a, |&x| x).into_set_buf();
159
160 assert!(difference.is_empty());
161 }
162
163 #[test]
164 fn difference_non_empty_duplicate_relations() {
165 let a = Set::new_unchecked(&[
166 Foo{ a: 1, b: 6 },
167 Foo{ a: 1, b: 7 },
168 Foo{ a: 1, b: 8 },
169 Foo{ a: 2, b: 9 },
170 Foo{ a: 2, b: 10 },
171 ]);
172 let b = Set::new(&[1, 3, 4, 5]).unwrap();
173
174 let difference: SetBuf<Foo> = DifferenceByKey::new(a, b, |x| x.a, |&x| x).into_set_buf();
175
176 assert_eq!(difference.as_slice(), &[
177 Foo{ a: 2, b: 9 },
178 Foo{ a: 2, b: 10 },
179 ][..]);
180 }
181
182 quickcheck! {
183 fn qc_difference(a: Vec<i32>, b: Vec<i64>) -> bool {
184 use std::collections::BTreeSet;
185 use std::iter::FromIterator;
186
187 let mut a = a;
188 let mut b = b;
189
190 sort_dedup_vec(&mut a);
191 sort_dedup_vec(&mut b);
192
193 let x: SetBuf<i32> = {
194 let difference = DifferenceByKey { a: &a, b: &b, f: |&x| x, g: |&x| x as i32 };
195 difference.into_set_buf()
196 };
197
198 let a = BTreeSet::from_iter(a);
199 let b = BTreeSet::from_iter(b.into_iter().map(|x| x as i32));
200 let y = a.difference(&b);
201 let y: Vec<_> = y.cloned().collect();
202
203 x.as_slice() == y.as_slice()
204 }
205 }
206}
207
208
209#[cfg(all(feature = "unstable", test))]
210mod bench {
211 extern crate test;
212 use super::*;
213 use self::test::Bencher;
214 use crate::set::SetBuf;
215
216 #[derive(Debug, Clone)]
217 pub struct Foo {
218 a: i32,
219 b: u8
220 }
221
222 impl Foo {
223 fn new(a: i32) -> Foo {
224 Foo { a, b: 0 }
225 }
226 }
227
228 #[bench]
229 fn two_slices_big(bench: &mut Bencher) {
230 let a: Vec<_> = (0..100).map(Foo::new).collect();
231 let b: Vec<_> = (1..101).collect();
232 let f = |x: &Foo| x.a;
233 let g = |x: &i32| *x;
234
235 bench.iter(|| {
236 let op = DifferenceByKey { a: &a, b: &b, f, g };
237 let res: SetBuf<Foo> = op.into_set_buf();
238 test::black_box(|| res);
239 });
240 }
241
242 #[bench]
243 fn two_slices_big2(bench: &mut Bencher) {
244 let a: Vec<_> = (0..100).map(Foo::new).collect();
245 let b: Vec<_> = (51..151).collect();
246 let f = |x: &Foo| x.a;
247 let g = |x: &i32| *x;
248
249 bench.iter(|| {
250 let op = DifferenceByKey { a: &a, b: &b, f, g };
251 let res: SetBuf<Foo> = op.into_set_buf();
252 test::black_box(|| res);
253 });
254 }
255
256 #[bench]
257 fn two_slices_big3(bench: &mut Bencher) {
258 let a: Vec<_> = (0..100).map(Foo::new).collect();
259 let b: Vec<_> = (100..200).collect();
260 let f = |x: &Foo| x.a;
261 let g = |x: &i32| *x;
262
263 bench.iter(|| {
264 let op = DifferenceByKey { a: &a, b: &b, f, g };
265 let res: SetBuf<Foo> = op.into_set_buf();
266 test::black_box(|| res);
267 });
268 }
269}