/*
Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved.
Contact:
SYSTAP, LLC DBA Blazegraph
2501 Calvert ST NW #106
Washington, DC 20008
licenses@blazegraph.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Created on Apr 15, 2009
*/
package com.bigdata.service.ndx.pipeline;
import java.util.concurrent.atomic.AtomicInteger;
import junit.framework.TestCase2;
import com.bigdata.btree.keys.KVO;
/**
* Test suite for {@link DefaultDuplicateRemover}.
*
* @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a>
* @version $Id$
*/
public class TestDefaultDuplicateRemover extends TestCase2 {
/**
*
*/
public TestDefaultDuplicateRemover() {
}
/**
* @param arg0
*/
public TestDefaultDuplicateRemover(String arg0) {
super(arg0);
}
/**
* Test of filter which removes identical writes (same key, same value).
*/
public void test_filter_keyAndVal() {
final IDuplicateRemover<Object> fixture = new DefaultDuplicateRemover<Object>(
false/* filterRefs */);
final KVO<Object> t0 = new KVO<Object>(new byte[] {}, new byte[] {}, null);
final KVO<Object> t1 = new KVO<Object>(new byte[] {1}, new byte[] {1}, null);
// t2 is dup of t1.
final KVO<Object> t2 = new KVO<Object>(new byte[] {1}, new byte[] {1}, null);
// t3 has the same key, but is not a dup
final KVO<Object> t3 = new KVO<Object>(new byte[] {1}, new byte[] {2}, null);
final KVO<Object> t4 = new KVO<Object>(new byte[] {1,2}, new byte[] {}, null);
/*
* Note: The array is given in ordered order to avoid sort() choosing
* the ordering for us.
*/
final KVO<Object>[] a = new KVO[] { t0, t1, t2, t3, t4 };
// filter to remove duplicates.
final KVO<Object>[] b = fixture.filter(a);
// should have removed ONE duplicate.
assertEquals("length", a.length - 1, b.length);
assertTrue(t0 == b[0]);
assertTrue(t1 == b[1]);
assertTrue(t3 == b[2]);
assertTrue(t4 == b[3]);
}
/**
* Test of filter which removes writes having the same reference (the
* reference test is used to avoid the key and value comparison).
*/
public void test_filter_ref() {
final IDuplicateRemover<Object> fixture = new DefaultDuplicateRemover<Object>(
true/* filterRefs */);
final Object o0 = new Object();
final Object o1 = new Object();
final Object o2 = new Object();
final Object o3 = new Object();
final KVO<Object> t0 = new KVO<Object>(new byte[] {}, new byte[] {}, o0);
final KVO<Object> t1 = new KVO<Object>(new byte[] {1}, new byte[] {1}, o1);
// t2 is dup of t1.
final KVO<Object> t2 = new KVO<Object>(new byte[] {1}, new byte[] {1}, o1);
// t3 has the same key, but is not a dup
final KVO<Object> t3 = new KVO<Object>(new byte[] {1}, new byte[] {2}, o2);
final KVO<Object> t4 = new KVO<Object>(new byte[] {1,2}, new byte[] {}, o3);
/*
* Note: The array is given in ordered order to avoid sort() choosing
* the ordering for us.
*/
final KVO<Object>[] a = new KVO[] { t0, t1, t2, t3, t4 };
// filter to remove duplicates.
final KVO<Object>[] b = fixture.filter(a);
// should have removed ONE duplicate.
assertEquals("length", a.length - 1, b.length);
assertTrue(t0 == b[0]);
assertTrue(t1 == b[1]);
assertTrue(t3 == b[2]);
assertTrue(t4 == b[3]);
}
/**
* Helper class uses an atomic counter to record the #of visited instances
* when {@link #done()} is invoked.
*
* @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan
* Thompson</a>
* @version $Id$
* @param <O>
*/
private static class KVODupTest<O> extends KVOList<O> {
private final AtomicInteger counter;
/**
* @param key
* @param val
* @param obj
*/
public KVODupTest(byte[] key, byte[] val, O obj, AtomicInteger counter) {
super(key, val, obj);
this.counter = counter;
}
@Override
public void done() {
super.done();
counter.incrementAndGet();
}
}
/**
* Unit test verifies that the duplicates are maintained on a
* {@link KVOList}, including the case where a series or more than one
* duplicate is identified to verify that the linked list is constructed
* correctly.
*/
public void test_duplicateList() {
final IDuplicateRemover<Object> fixture = new DefaultDuplicateRemover<Object>(
true/* filterRefs */);
final Object o0 = new Object();
final Object o1 = new Object();
final Object o2 = new Object();
final Object o3 = new Object();
final AtomicInteger counter = new AtomicInteger();
final KVOList<Object> t0 = new KVODupTest<Object>(new byte[] {},
new byte[] {}, o0, counter);
final KVOList<Object> t1 = new KVODupTest<Object>(new byte[] { 1 },
new byte[] { 1 }, o1, counter);
// t2 is dup of t1.
final KVOList<Object> t2 = new KVODupTest<Object>(new byte[] { 1 },
new byte[] { 1 }, o1, counter);
// t3 is also a dup of t1.
final KVOList<Object> t3 = new KVODupTest<Object>(new byte[] { 1 },
new byte[] { 1 }, o1, counter);
// t4 has the same key but is not a dup.
final KVOList<Object> t4 = new KVODupTest<Object>(new byte[] { 1 },
new byte[] { 1, 0, 2 }, o2, counter);
// t5 has a different key.
final KVOList<Object> t5 = new KVODupTest<Object>(new byte[] { 1, 2 },
new byte[] {}, o3, counter);
/*
* Note: The array is given in ordered order to avoid sort() choosing
* the ordering for us.
*/
final KVO<Object>[] a = new KVO[] { t0, t1, t2, t3, t4, t5 };
// filter to remove duplicates.
final KVO<Object>[] b = fixture.filter(a);
// should have removed TWO duplicates.
assertEquals("length", a.length - 2, b.length);
assertTrue(t0 == b[0]);
assertTrue(t1 == b[1]);
assertTrue(t4 == b[2]);
assertTrue(t5 == b[3]);
assertEquals("duplicateCount", 0, t0.getDuplicateCount());
assertEquals("duplicateCount", 2, t1.getDuplicateCount());
assertEquals("duplicateCount", 0, t2.getDuplicateCount());
assertEquals("duplicateCount", 0, t3.getDuplicateCount());
assertEquals("duplicateCount", 0, t4.getDuplicateCount());
assertEquals("duplicateCount", 0, t5.getDuplicateCount());
// verify that done() traverses the list of duplicates.
assertEquals("counter",0,counter.get());
t1.done();
assertEquals("counter",3,counter.get());
}
}