1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.collections4.bloomfilter;
18
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNotEquals;
21 import static org.junit.Assert.assertNotSame;
22 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
23 import static org.junit.jupiter.api.Assertions.assertFalse;
24 import static org.junit.jupiter.api.Assertions.assertSame;
25 import static org.junit.jupiter.api.Assertions.assertThrows;
26 import static org.junit.jupiter.api.Assertions.assertTrue;
27
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.LinkedList;
31 import java.util.List;
32 import java.util.NoSuchElementException;
33 import java.util.function.Consumer;
34 import java.util.function.Predicate;
35
36 import org.junit.jupiter.api.Test;
37 import org.junit.jupiter.params.ParameterizedTest;
38 import org.junit.jupiter.params.provider.ValueSource;
39
40 public class LayerManagerTest {
41
42 private Shape shape = Shape.fromKM(17, 72);
43
44 @ParameterizedTest
45 @ValueSource(ints = {4, 10, 2, 1})
46 public void testAdvanceOnCount(int breakAt) {
47 Predicate<LayerManager> underTest = LayerManager.ExtendCheck.advanceOnCount(breakAt);
48 LayerManager layerManager = testingBuilder().build();
49 for (int i = 0; i < breakAt - 1; i++) {
50 assertFalse(underTest.test(layerManager), "at " + i);
51 layerManager.getTarget().merge(TestingHashers.FROM1);
52 }
53 assertTrue(underTest.test(layerManager));
54 }
55
56 @Test
57 public void testAdvanceOnCountInvalidArguments() {
58 assertThrows(IllegalArgumentException.class, () -> LayerManager.ExtendCheck.advanceOnCount(0));
59 assertThrows(IllegalArgumentException.class, () -> LayerManager.ExtendCheck.advanceOnCount(-1));
60 }
61
62 @Test
63 public void testAdvanceOnPopulated() {
64 Predicate<LayerManager> underTest = LayerManager.ExtendCheck.advanceOnPopulated();
65 LayerManager layerManager = testingBuilder().build();
66 assertFalse(underTest.test(layerManager));
67 layerManager.getTarget().merge(TestingHashers.FROM1);
68 assertTrue(underTest.test(layerManager));
69 }
70
71 @Test
72 public void testAdvanceOnSaturation() {
73 Double maxN = shape.estimateMaxN();
74 int hashStart = 0;
75 Predicate<LayerManager> underTest = LayerManager.ExtendCheck.advanceOnSaturation(maxN);
76 LayerManager layerManager = testingBuilder().build();
77 while (layerManager.getTarget().getShape().estimateN(layerManager.getTarget().cardinality()) < maxN) {
78 assertFalse(underTest.test(layerManager));
79 layerManager.getTarget().merge(new IncrementingHasher(hashStart, shape.getNumberOfHashFunctions()));
80 hashStart+=shape.getNumberOfHashFunctions();
81 }
82 assertTrue(underTest.test(layerManager));
83 assertThrows(IllegalArgumentException.class, () -> LayerManager.ExtendCheck.advanceOnSaturation(0));
84 assertThrows(IllegalArgumentException.class, () -> LayerManager.ExtendCheck.advanceOnSaturation(-1));
85 }
86
87 @Test
88 public void testBuilder() {
89 LayerManager.Builder underTest = LayerManager.builder();
90 NullPointerException npe = assertThrows(NullPointerException.class, () -> underTest.build());
91 assertTrue(npe.getMessage().contains("Supplier must not be null"));
92 underTest.setSupplier(() -> null).setCleanup(null);
93 npe = assertThrows(NullPointerException.class, () -> underTest.build());
94 assertTrue(npe.getMessage().contains("Cleanup must not be null"));
95 underTest.setCleanup(x -> {
96 }).setExtendCheck(null);
97 npe = assertThrows(NullPointerException.class, () -> underTest.build());
98 assertTrue(npe.getMessage().contains("ExtendCheck must not be null"));
99
100 npe = assertThrows(NullPointerException.class, () -> LayerManager.builder().setSupplier(() -> null).build());
101 assertTrue(npe.getMessage().contains("filterSupplier returned null."));
102
103 }
104
105 @Test
106 public void testClear() {
107 LayerManager underTest = LayerManager.builder().setSupplier(() -> new SimpleBloomFilter(shape)).build();
108 underTest.getTarget().merge(TestingHashers.randomHasher());
109 underTest.next();
110 underTest.getTarget().merge(TestingHashers.randomHasher());
111 underTest.next();
112 underTest.getTarget().merge(TestingHashers.randomHasher());
113 assertEquals(3, underTest.getDepth());
114 underTest.clear();
115 assertEquals(1, underTest.getDepth());
116 assertEquals(0, underTest.getTarget().cardinality());
117 }
118
119 @Test
120 public void testCopy() {
121 LayerManager underTest = LayerManager.builder().setSupplier(() -> new SimpleBloomFilter(shape)).build();
122 underTest.getTarget().merge(TestingHashers.randomHasher());
123 underTest.next();
124 underTest.getTarget().merge(TestingHashers.randomHasher());
125 underTest.next();
126 underTest.getTarget().merge(TestingHashers.randomHasher());
127 assertEquals(3, underTest.getDepth());
128
129 LayerManager copy = underTest.copy();
130 assertNotSame(underTest, copy);
131
132 assertNotEquals(underTest, copy);
133
134 assertEquals(underTest.getDepth(), copy.getDepth());
135 assertTrue(
136 underTest.forEachBloomFilterPair(copy, (x, y) -> Arrays.equals(x.asBitMapArray(), y.asBitMapArray())));
137 }
138
139 @Test
140 public void testForEachBloomFilter() {
141 LayerManager underTest = LayerManager.builder().setSupplier(() -> new SimpleBloomFilter(shape))
142 .setExtendCheck(LayerManager.ExtendCheck.advanceOnPopulated()).build();
143
144 List<BloomFilter> lst = new ArrayList<>();
145 for (int i = 0; i < 10; i++) {
146 BloomFilter bf = new SimpleBloomFilter(shape);
147 bf.merge(TestingHashers.randomHasher());
148 lst.add(bf);
149 underTest.getTarget().merge(bf);
150 }
151 List<BloomFilter> lst2 = new ArrayList<>();
152 underTest.forEachBloomFilter(lst2::add);
153 assertEquals(10, lst.size());
154 assertEquals(10, lst2.size());
155 for (int i = 0; i < lst.size(); i++) {
156 assertArrayEquals(lst.get(i).asBitMapArray(), lst2.get(i).asBitMapArray());
157 }
158 }
159
160 @Test
161 public void testGet() {
162 SimpleBloomFilter f = new SimpleBloomFilter(shape);
163 LayerManager underTest = LayerManager.builder().setSupplier(() -> f).build();
164 assertEquals(1, underTest.getDepth());
165 assertSame(f, underTest.get(0));
166 assertThrows(NoSuchElementException.class, () -> underTest.get(-1));
167 assertThrows(NoSuchElementException.class, () -> underTest.get(1));
168 }
169
170 private LayerManager.Builder testingBuilder() {
171 return LayerManager.builder().setSupplier(() -> new SimpleBloomFilter(shape));
172 }
173
174 @Test
175 public void testNeverAdvance() {
176 Predicate<LayerManager> underTest = LayerManager.ExtendCheck.neverAdvance();
177 LayerManager layerManager = testingBuilder().build();
178 assertFalse(underTest.test(layerManager));
179 for (int i = 0; i < 10; i++) {
180 layerManager.getTarget().merge(TestingHashers.randomHasher());
181 assertFalse(underTest.test(layerManager));
182 }
183 }
184
185 @Test
186 public void testNextAndGetDepth() {
187 LayerManager underTest = LayerManager.builder().setSupplier(() -> new SimpleBloomFilter(shape)).build();
188 assertEquals(1, underTest.getDepth());
189 underTest.getTarget().merge(TestingHashers.randomHasher());
190 assertEquals(1, underTest.getDepth());
191 underTest.next();
192 assertEquals(2, underTest.getDepth());
193 }
194
195 @Test
196 public void testNoCleanup() {
197 Consumer<LinkedList<BloomFilter>> underTest = LayerManager.Cleanup.noCleanup();
198 LinkedList<BloomFilter> list = new LinkedList<>();
199 for (int i = 0; i < 20; i++) {
200 assertEquals(i, list.size());
201 list.add(new SimpleBloomFilter(shape));
202 underTest.accept(list);
203 }
204 }
205
206 @ParameterizedTest
207 @ValueSource(ints = {5, 100, 2, 1})
208 public void testOnMaxSize(int maxSize) {
209 Consumer<LinkedList<BloomFilter>> underTest = LayerManager.Cleanup.onMaxSize(maxSize);
210 LinkedList<BloomFilter> list = new LinkedList<>();
211 for (int i = 0; i < maxSize; i++) {
212 assertEquals(i, list.size());
213 list.add(new SimpleBloomFilter(shape));
214 underTest.accept(list);
215 }
216 assertEquals(maxSize, list.size());
217
218 for (int i = 0; i < maxSize; i++) {
219 list.add(new SimpleBloomFilter(shape));
220 underTest.accept(list);
221 assertEquals(maxSize, list.size());
222 }
223 }
224
225 @Test
226 public void testOnMaxSizeIllegalValues() {
227 assertThrows(IllegalArgumentException.class, () -> LayerManager.Cleanup.onMaxSize(0));
228 assertThrows(IllegalArgumentException.class, () -> LayerManager.Cleanup.onMaxSize(-1));
229 }
230
231 @Test
232 public void testRemoveEmptyTarget() {
233 Consumer<LinkedList<BloomFilter>> underTest = LayerManager.Cleanup.removeEmptyTarget();
234 LinkedList<BloomFilter> list = new LinkedList<>();
235
236
237 BloomFilter bf = new SimpleBloomFilter(shape);
238 list.add(bf);
239 assertEquals(bf, list.get(0));
240 underTest.accept(list);
241 assertTrue(list.isEmpty());
242
243
244 bf.merge(IndexProducer.fromIndexArray(1));
245 list.add(bf);
246 assertEquals(bf, list.get(0));
247 underTest.accept(list);
248 assertEquals(bf, list.get(0));
249
250
251 list.clear();
252 list.add(new SimpleBloomFilter(shape));
253 list.add(bf);
254 assertEquals(2, list.size());
255 underTest.accept(list);
256 assertEquals(2, list.size());
257
258
259
260 list.clear();
261 list.add(bf);
262 list.add(new SimpleBloomFilter(shape));
263 list.add(new SimpleBloomFilter(shape));
264 assertEquals(3, list.size());
265 underTest.accept(list);
266 assertEquals(2, list.size());
267 assertEquals(bf, list.get(0));
268
269 }
270
271 @Test
272 public void testTarget() {
273 boolean[] extendCheckCalled = { false };
274 boolean[] cleanupCalled = { false };
275 int[] supplierCount = { 0 };
276 LayerManager underTest = LayerManager.builder().setSupplier(() -> {
277 supplierCount[0]++;
278 return new SimpleBloomFilter(shape);
279 }).setExtendCheck(lm -> {
280 extendCheckCalled[0] = true;
281 return true;
282 }).setCleanup(ll -> {
283 cleanupCalled[0] = true;
284 }).build();
285 assertFalse(extendCheckCalled[0]);
286 assertFalse(cleanupCalled[0]);
287 assertEquals(1, supplierCount[0]);
288 underTest.getTarget();
289 assertTrue(extendCheckCalled[0]);
290 assertTrue(cleanupCalled[0]);
291 assertEquals(2, supplierCount[0]);
292 }
293
294 }