SketchMerger { public Sketch<?> merge(Sketch<?> left, Sketch<?> right) { if (left instanceof NormalSketch && right instanceof NormalSketch) { return mergeNormalWithNormal(asNormal(left), asNormal(right)); } else if (left instanceof NormalSketch && right instanceof SparseSketch) { return mergeNormalWithSparse(asNormal(left), asSparse(right)); } else if (left instanceof SparseSketch && right instanceof NormalSketch) { return mergeNormalWithSparse(asNormal(right), asSparse(left)); } else if (left instanceof SparseSketch && right instanceof SparseSketch) { return mergeSparseWithSparse(asSparse(left), asSparse(right)); } else { throw new IllegalArgumentException( String.format("Invalid sketch types: left=%s, right=%s", right.getClass(), left.getClass())); } }  Sketch<?> merge(Sketch<?> left, Sketch<?> right);  }
@Test public void requireThatMergingTwoSmallSparseSketchesReturnsSparseSketch() { SparseSketch s1 = SketchUtils.createSparseSketch(1); SparseSketch s2 = SketchUtils.createSparseSketch(2); Sketch<?> result = merger.merge(s1, s2); assertEquals(result.getClass(), SparseSketch.class); assertTrue("Should return the instance given by first argument.", result == s1); SketchUtils.assertSketchContains(result, 1, 2); }
@Test public void requireThatMergingTwoThresholdSizeSparseSketchesReturnsNormalSketch() { SparseSketch s1 = SketchUtils.createSparseSketch(); SparseSketch s2 = SketchUtils.createSparseSketch(); for (int i = 0; i < HyperLogLog.SPARSE_SKETCH_CONVERSION_THRESHOLD; i++) { s1.aggregate(i); s2.aggregate(i + HyperLogLog.SPARSE_SKETCH_CONVERSION_THRESHOLD); } Sketch<?> result = merger.merge(s1, s2); assertEquals(result.getClass(), NormalSketch.class); List<Integer> unionOfSketchData = new ArrayList<>(); unionOfSketchData.addAll(s1.data()); unionOfSketchData.addAll(s2.data()); Integer[] expectedValues = unionOfSketchData.toArray(new Integer[unionOfSketchData.size()]); SketchUtils.assertSketchContains(result, expectedValues); }
@Test public void requireThatMergingTwoNormalSketchesReturnsNormalSketch() { NormalSketch s1 = SketchUtils.createNormalSketch(1); NormalSketch s2 = SketchUtils.createNormalSketch(2); Sketch<?> result = merger.merge(s1, s2); assertEquals(result.getClass(), NormalSketch.class); assertTrue("Should return the instance given by first argument.", result == s1); SketchUtils.assertSketchContains(result, 1, 2); }
@Test public void requireThatMergingNormalAndSparseSketchReturnsNormalSketch() { SparseSketch s1 = SketchUtils.createSparseSketch(1); NormalSketch s2 = SketchUtils.createNormalSketch(2); Sketch<?> result = merger.merge(s1, s2); assertEquals(result.getClass(), NormalSketch.class); assertTrue("Should return the NormalSketch instance given by the arguments.", result == s2); SketchUtils.assertSketchContains(result, 1, 2); }