package net.varkhan.base.containers.map; import junit.framework.TestCase; import net.varkhan.base.containers.Index; import net.varkhan.base.containers.IndexedVisitable; import net.varkhan.base.containers.Iterator; import net.varkhan.base.containers.Visitable; import java.io.*; import java.util.HashSet; import java.util.Random; import java.util.Set; /** * <b></b>. * <p/> * * @author varkhan * @date 11/29/13 * @time 6:16 PM */ public abstract class AbstractIndexedMapTest extends TestCase { @SuppressWarnings("unchecked") public static <C extends Cloneable> C clone(C obj) { try { return (C) obj.getClass().getMethod("clone").invoke(obj); } catch(Exception e) { return null; } } protected String[] genKeyStrings(Random rand, int num, int minl, int maxl, char[] characters) { java.util.Set<String> keys=new HashSet<String>(num); while(keys.size()<num) { StringBuilder buf=new StringBuilder(); int len=minl+rand.nextInt(maxl-minl); for(int j=0;j<len;j++) buf.append(characters[rand.nextInt(characters.length)]); keys.add(buf.toString()); } return keys.toArray(new String[num]); } protected String[] generateValueStrings(Random rand, int num, double sparse, int minl, int maxl, char[] characters) { String[] a=new String[num]; for(int i=0;i<num;i++) { if(rand.nextFloat()<sparse) { a[i]=null; continue; } StringBuilder buf=new StringBuilder(); int len=minl+rand.nextInt(maxl-minl); for(int j=0;j<len;j++) buf.append(characters[rand.nextInt(characters.length)]); a[i]=buf.toString(); } return a; } protected <K,V> void featureTestAdd(Random rand, K[] keys, V[] vals, IndexedMap<K,V> imap, int verb) throws Exception { // Testing key adding for(int i=0;i<keys.length;i++) { K k=keys[i]; V v=vals[i]; long x=imap.add(k, v); if(verb>0) System.err.println("Added "+v+": "+x); if(verb>1) System.err.println(imap); assertTrue("add("+v+") = "+x, x>=0); } if(verb>0) System.out.println("add(T) OK"); } protected <K,V> void featureTestHas(Random rand, K[] keys, V[] vals, IndexedMap<K,V> imap, int verb) throws Exception { long[] idx=new long[keys.length]; imap.clear(); for(int i=0;i<keys.length;i++) idx[i]=imap.add(keys[i],vals[i]); // Testing if keys are seen for(int i=0;i<keys.length;i++) { long x=idx[i]; assertTrue("has("+x+")", imap.has(x)); if(verb>1) System.err.println("Checked "+x); if(verb>2) System.err.println(imap); } System.out.println("has(long) OK"); } protected <K,V> void featureTestIdx(Random rand, K[] keys, V[] vals, IndexedMap<K,V> imap, int verb) throws Exception { long[] idx=new long[keys.length]; imap.clear(); for(int i=0;i<keys.length;i++) idx[i]=imap.add(keys[i],vals[i]); // Testing if indexes can be retrieved for(int i=0;i<keys.length;i++) { K k=keys[i]; long x=imap.index(k); assertTrue("index("+k+") = "+idx[i]+" / "+x, x==idx[i]); if(verb>1) System.err.println("Indexed "+k+": "+x); if(verb>2) System.err.println(imap); } if(verb>0) System.out.println("index(T) OK"); } protected <K,V> void featureTestGet(Random rand, K[] keys, V[] vals, IndexedMap<K,V> imap, int verb) throws Exception { long[] idx=new long[keys.length]; imap.clear(); for(int i=0;i<keys.length;i++) idx[i]=imap.add(keys[i],vals[i]); // Testing if keys/values can be retrieved for(int i=0;i<keys.length;i++) { K k=keys[i]; V v=vals[i]; long x=idx[i]; assertTrue("getKey("+x+") = "+k, k==imap.getKey(x)); assertTrue("getValue("+x+") = "+v, v==imap.getValue(x)); if(verb>1) System.err.println("Indexed "+k+": "+x); if(verb>2) System.err.println(imap); } if(verb>0) System.out.println("get{Key,Value}(long) OK"); } protected <K,V> void featureTestDel(Random rand, K[] keys, V[] vals, IndexedMap<K,V> imap, int verb) throws Exception { long[] idx=new long[keys.length]; // Testing forward delete (no resize) for(int i=0;i<keys.length;i++) { K k=keys[i]; long x=idx[i]; // This may have been deleted before // assertTrue("has("+k+")",set.has(x)); imap.del(x); if(verb>1) System.err.println("Deleted "+k+": "+x); if(verb>2) System.err.println(imap); assertFalse("has("+k+")", imap.has(x)); // for(int j=i+1; j<keys.length; j++) { // String t = keys[i]; // if(t.equals(k)) continue; // long xx = set.index(t); // assertTrue("index("+t+") = "+idx[i]+" / "+xx,xx==idx[i]); // } // assertTrue("index("+k+") = "+idx[i]+" / "+x, x==idx[i]); } if(verb>0) System.out.println("del(long) forward OK"); // Testing backward delete (implies auto resize) for(int i=0;i<keys.length;i++) { idx[i]=imap.add(keys[i], vals[i]); } for(int i=keys.length-1;i>=0;i--) { K k=keys[i]; long x=idx[i]; // This may have been deleted before // assertTrue("has("+k+")",set.has(x)); imap.del(x); // System.err.println("Deleted "+k+": "); // System.err.println(set); assertFalse("has("+k+")", imap.has(x)); // for(int j=i+1; j<keys.length; j++) { // String t = keys[i]; // if(t.equals(k)) continue; // long xx = set.index(t); // assertTrue("index("+t+") = "+idx[i]+" / "+xx,xx==idx[i]); // } // assertTrue("index("+k+") = "+idx[i]+" / "+x, x==idx[i]); } if(verb>0) System.out.println("del(long) backward OK"); // Testing random delete (implies auto resize) Set<Integer> del=new HashSet<Integer>(); while(del.size()<keys.length) { int i=rand.nextInt(vals.length); if(del.contains(i)) continue; K k=keys[i]; V v=vals[i]; long x=idx[i]; imap.del(x); del.add(i); assertFalse("has("+k+")", imap.has(x)); // for(int j=i+1; j<a.length; j++) { // String t = a[i]; // if(t.equals(s)) continue; // long xx = set.index(t); // assertTrue("index("+t+") = "+idx[i]+" / "+xx,xx==idx[i]); // } // assertTrue("index("+k+") = "+idx[i]+" / "+x, x==idx[i]); } System.out.println("del(long) OK"); } public <K,V> void featureTestVisit(Random rand, K[] keys, V[] vals, IndexedMap<K,V> imap, int verb) throws Exception { long[] idx=new long[vals.length]; imap.clear(); for(int i=0;i<keys.length;i++) idx[i]=imap.add(keys[i],vals[i]); assertEquals("visit()", imap.size(), imap.visit(new Visitable.Visitor<IndexedMap.Entry<K,V>,IndexedMap<K,V>>() { @Override public long invoke(IndexedMap.Entry<K,V> obj, IndexedMap<K,V> map) { assertTrue(map.index(obj.getKey())>=0); assertEquals(obj.getValue(),map.getValue(map.index(obj.getKey()))); return 1; } }, imap)); assertEquals("visit()", imap.size(), imap.visit(new IndexedVisitable.IndexedVisitor<IndexedMap.Entry<K,V>,IndexedMap<K,V>>() { @Override public long invoke(long idx, IndexedMap.Entry<K,V> obj, IndexedMap<K,V> map) { assertTrue(map.has(idx)); assertEquals(idx, map.index(obj.getKey())); assertEquals(obj.getValue(),map.getValue(idx)); return 1; } }, imap)); System.out.println("visit() OK"); } @SuppressWarnings("unchecked") public <K,V> void featureTestSerialize(Random rand, K[] keys, V[] vals, IndexedMap<K,V> imap, int verb) throws Exception { long[] idx=new long[keys.length]; imap.clear(); for(int i=0;i<keys.length;i++) idx[i]=imap.add(keys[i],vals[i]); File t=null; try { t=File.createTempFile("serial-", ".ser"); ObjectOutputStream os=null; try { os=new ObjectOutputStream(new FileOutputStream(t)); os.writeObject(imap); } finally { if(os!=null) os.close(); } ObjectInputStream is=null; IndexedMap<K,V> smap=null; try { is=new ObjectInputStream(new FileInputStream(t)); smap=(IndexedMap<K,V>) is.readObject(); } finally { if(is!=null) is.close(); } // assertTrue("serialize(lst)==lst",iset.equals(sset)); for(int i=0;i<vals.length;i++) { K k=keys[i]; V v=vals[i]; long x=idx[i]; assertTrue("index("+k+") = "+x, x==smap.index(k)); assertEquals("getKey("+x+")", k, smap.getKey(x)); assertEquals("getValue("+x+")", v, smap.getValue(x)); } System.out.println("serial OK"); } finally { if(t!=null) t.delete(); } } public <K,V> void featureTestClear(Random rand, K[] keys, V[] vals, IndexedMap<K,V> imap, int verb) throws Exception { long[] idx=new long[keys.length]; imap.clear(); for(int i=0;i<keys.length;i++) idx[i]=imap.add(keys[i],vals[i]); imap.clear(); assertTrue("isEmpty", imap.isEmpty()); for(int i=0;i<vals.length;i++) { long x=idx[i]; assertFalse("has("+x+")", imap.has(x)); } System.out.println("clear() OK"); } public <K,V> void featureTestIndexes(Random rand, K[] keys, V[] vals, IndexedMap<K,V> imap, int verb) throws Exception { long[] idx=new long[keys.length]; imap.clear(); for(int i=0;i<keys.length;i++) idx[i]=imap.add(keys[i],vals[i]); Index it=imap.indexes(); assertFalse("!hasPrevious()", it.hasPrevious()); boolean prev=false; for(int i=0;i<imap.size();i++) { assertTrue(i+": hasNext()", it.hasNext()); long x=it.next(); if(verb>0) System.err.println(i+": next() = "+x); if(prev) assertTrue(i+": hasPrevious()", it.hasPrevious()); else assertFalse(i+": !hasPrevious()", it.hasPrevious()); prev=true; } assertFalse("!hasNext()", it.hasNext()); System.out.println("indexes() OK"); } public <K,V> void featureTestIterate(Random rand, K[] keys, V[] vals, IndexedMap<K,V> imap, int verb) throws Exception { long[] idx=new long[keys.length]; imap.clear(); for(int i=0;i<keys.length;i++) idx[i]=imap.add(keys[i],vals[i]); @SuppressWarnings("unchecked") Iterator<IndexedMap.Entry<K,V>> it=(Iterator<IndexedMap.Entry<K,V>>) imap.iterator(); for(int i=0;i<imap.size();i++) { assertTrue(i+": hasNext()", it.hasNext()); it.next(); } assertFalse("!hasNext()", it.hasNext()); System.out.println("iterate() OK"); } public <K,V> void featureTestEquals(Random rand, K[] keys, V[] vals, IndexedMap<K,V> imap, IndexedMap<K,V> eql, int verb) throws Exception { long[] idx=new long[keys.length]; long[] eidx=new long[keys.length]; imap.clear(); for(int i=0;i<keys.length;i++) idx[i]=imap.add(keys[i],vals[i]); assertFalse("lst.equals(eql)", imap.equals(eql)); for(int i=0;i<keys.length;i++) eidx[i]=eql.add(keys[i],vals[i]); assertTrue("lst.equals(eql)", imap.equals(eql)); assertEquals("lst.hashCode()", imap.hashCode(), eql.hashCode()); for(int i=0; i<100; i++) { int p = rand.nextInt(vals.length); if(!imap.has(p)) continue; imap.del(p); assertFalse("lst.equals(eql)", imap.equals(eql)); eql.del(p); assertTrue("lst.equals(eql)", imap.equals(eql)); assertEquals("lst.hashCode()", imap.hashCode(), eql.hashCode()); } System.out.println("equals OK"); } public <K,V,S extends IndexedMap<K,V> & Cloneable> void featureTestClone(Random rand, K[] keys, V[] vals, S imap, int verb) throws Exception { long[] idx=new long[vals.length]; imap.clear(); for(int i=0;i<keys.length;i++) idx[i]=imap.add(keys[i],vals[i]); IndexedMap<K,V> cln = clone(imap); assertEquals("size(set)==set", imap.size(),cln.size()); for(int i=0;i<keys.length;i++) { K k=keys[i]; V v=vals[i]; long x=idx[i]; assertEquals("index("+k+") = "+x, x, imap.index(k)); assertEquals("get("+x+")", v, imap.getValue(x)); } System.out.println("clone OK"); } }