CountThenEstimate implements IRichCardinality, Externalizable { private void tip() { estimator = builder.build(); for (Object o : counter) { estimator.offer(o); } counter = null; builder = null; tipped = true; } CountThenEstimate();  CountThenEstimate(int tippingPoint, IBuilder<IRichCardinality> builder);  CountThenEstimate(byte[] bytes); @Override long cardinality(); @Override boolean offerHashed(long hashedLong); @Override boolean offerHashed(int hashedInt); @Override boolean offer(Object o); @Override int sizeof(); boolean tipped(); @Override byte[] getBytes(); @SuppressWarnings("unchecked") @Override void readExternal(ObjectInput in); @Override void writeExternal(ObjectOutput out); @Override IRichCardinality merge(IRichCardinality... estimators); static CountThenEstimate mergeEstimators(CountThenEstimate... estimators);  }
@Test public void testTip() throws IOException, ClassNotFoundException { CountThenEstimate cte = new CountThenEstimate(10000, new LinearCounting.Builder(1024)); CountThenEstimate clone = new CountThenEstimate(cte.getBytes()); assertCountThenEstimateEquals(cte, clone); for (int i = 0; i < 128; i++) { cte.offer(Integer.toString(i)); } clone = new CountThenEstimate(cte.getBytes()); assertEquals(128, cte.cardinality()); assertCountThenEstimateEquals(cte, clone); for (int i = 128; i < 256; i++) { cte.offer(Integer.toString(i)); } clone = new CountThenEstimate(cte.getBytes()); assertFalse(cte.tipped()); assertEquals(256, cte.cardinality()); assertTrue(clone.tipped()); double error = Math.abs(cte.cardinality() - 256) / 256D; assertEquals(0.1, error, 0.1); }