/* * Copyright (C) 2011 Clearspring Technologies, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.streaminer.stream.cardinality; import static org.junit.Assert.*; import java.util.Arrays; import org.junit.Ignore; import org.junit.Test; public class TestAdaptiveCounting { @Test public void testRho() { assertEquals(17, LogLog.rho(0, 16)); assertEquals(16, LogLog.rho(1, 16)); assertEquals(15, LogLog.rho(2, 16)); assertEquals(1, LogLog.rho(0x00008000, 16)); assertEquals(23, LogLog.rho(0, 10)); assertEquals(22, LogLog.rho(1, 10)); assertEquals(21, LogLog.rho(2, 10)); assertEquals(1, LogLog.rho(0x00200000, 10)); } @Test public void testRhoL() { assertEquals(49, AdaptiveCounting.rho(0L, 16)); assertEquals(48, AdaptiveCounting.rho(1L, 16)); assertEquals(47, AdaptiveCounting.rho(2L, 16)); assertEquals(1, AdaptiveCounting.rho(0x80008000L, 32)); assertEquals(55, AdaptiveCounting.rho(0L, 10)); assertEquals(54, AdaptiveCounting.rho(1L, 10)); assertEquals(53, AdaptiveCounting.rho(2L, 10)); assertEquals(1, AdaptiveCounting.rho(0x0020000000000000L, 10)); assertEquals(3, AdaptiveCounting.rho(0xDEA07EEFFEEDCAFEL, 15)); } @Test public void testJ() { long x = 0xDEADBEEFFEEDCAFEL; int k = 12; int j = (int) (x >>> (Long.SIZE - k)); assertEquals(0xDEA, j); } @Test public void testMerge() throws CardinalityMergeException { int numToMerge = 10; int cardinality = 10000; AdaptiveCounting[] lcs = new AdaptiveCounting[numToMerge]; AdaptiveCounting baseline = new AdaptiveCounting(16); for (int i = 0; i < numToMerge; i++) { lcs[i] = new AdaptiveCounting(16); for (int j = 0; j < cardinality; j++) { double val = Math.random(); lcs[i].offer(val); baseline.offer(val); } } int expectedCardinality = numToMerge * cardinality; long mergedEstimate = AdaptiveCounting.mergeEstimators(lcs).cardinality(); double error = Math.abs(mergedEstimate - expectedCardinality) / (double) expectedCardinality; assertEquals(0.01, error, 0.01); AdaptiveCounting lc = lcs[0]; lcs = Arrays.asList(lcs).subList(1, lcs.length).toArray(new AdaptiveCounting[0]); mergedEstimate = lc.merge(lcs).cardinality(); error = Math.abs(mergedEstimate - expectedCardinality) / (double) expectedCardinality; assertEquals(0.01, error, 0.01); assertEquals(baseline.cardinality(), mergedEstimate); } @Ignore @Test public void testLongCardinality() { IRichCardinality ac = new AdaptiveCounting(16); for (long i = 0; i < 5000000000L; i++) { ac.offer(Long.valueOf(i)); if (i % 10000000 == 0) { System.out.println("actual: " + i + ", estimated: " + ac.cardinality()); } } System.out.println(ac.cardinality()); assertEquals(5000000000L, ac.cardinality(), 100000000); } @Test public void testSerialization() { AdaptiveCounting ac = new AdaptiveCounting(10); testSerialization(ac); } private void testSerialization(AdaptiveCounting ac) { AdaptiveCounting clone = new AdaptiveCounting(ac.getBytes()); assertAdaptiveCountingEquals(ac, clone); assertEquals(0, ac.cardinality()); for (int i = 0; i < 100; i++) { ac.offer(i); } clone = new AdaptiveCounting(ac.getBytes()); assertAdaptiveCountingEquals(ac, clone); for (int i = 0; i < 1000000; i++) { ac.offer(i); } clone = new AdaptiveCounting(ac.getBytes()); assertAdaptiveCountingEquals(ac, clone); } private void assertAdaptiveCountingEquals(AdaptiveCounting expected, AdaptiveCounting actual) { assertArrayEquals(expected.M, actual.M); assertEquals(expected.k, actual.k); assertEquals(expected.m, actual.m); assertEquals(expected.Ca, actual.Ca, 0.00000001); assertEquals(expected.Rsum, actual.Rsum); assertEquals(expected.b_e, actual.b_e); assertEquals(expected.B_s, actual.B_s, 0.00000001); assertEquals(expected.sizeof(), actual.sizeof()); assertEquals(expected.cardinality(), actual.cardinality()); } }