From: Bryan T. <tho...@us...> - 2007-11-30 21:54:02
|
Update of /cvsroot/cweb/generic-native-test/src/java/org/CognitiveWeb/generic/core/ndx In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv29214/src/java/org/CognitiveWeb/generic/core/ndx Modified Files: TestStringTypeIndex.java AbstractIndexTest.java TestCharacterTypeIndex.java Log Message: Work on the bigdata-GOM integration. Index: AbstractIndexTest.java =================================================================== RCS file: /cvsroot/cweb/generic-native-test/src/java/org/CognitiveWeb/generic/core/ndx/AbstractIndexTest.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** AbstractIndexTest.java 15 Jun 2006 15:47:01 -0000 1.5 --- AbstractIndexTest.java 30 Nov 2007 21:53:57 -0000 1.6 *************** *** 92,98 **** * value. */ - abstract public class AbstractIndexTest extends GOMProxyTestCase { /** * --- 92,99 ---- * value. */ abstract public class AbstractIndexTest extends GOMProxyTestCase { + protected final Random r = new Random(); + /** * *************** *** 944,947 **** --- 945,1154 ---- /** + * Generator for random keys with an optional class constraint on the + * property values. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ + public class KeyGenerator implements IKeyGenerator { + + private final int maxDistinct; + + private final Class cls; + + private final boolean allowNull = false; + + private final Object[] keys; + + /** + * @param maxDistinct + * This parameter governs the maximum #of distinct keys that + * will be produced by the generator. When zero (0), all keys + * will be distinct - this should be used with an index that + * does not allow duplicate keys. When positive, that many + * distinct keys will be pre-generated and keys will be + * selected randomly (with replacement) from that population - + * this should be used with an index that allows duplicate + * keys. + * @param cls + * The type constraint -or- <code>null</code> iff there is + * no type constraint. + */ + public KeyGenerator( int maxDistinct, Class cls ) { + + this.maxDistinct = maxDistinct; + + this.cls = cls; + + if(maxDistinct==0) { + + // all keys are distinct so we do not pre-generate any keys. + + keys = null; + + } else { + + // pre-generate maxDistinct keys. + + keys = new Object[maxDistinct]; + + for (int i = 0; i < maxDistinct; i++) { + + keys[i] = _randomType.nextObject(r, cls, allowNull); + + } + + } + + } + + public Object nextKey() { + + if(keys==null) { + + // random property value of the specified type. + + // return getRandomString(10) + "-" + (counter++); + + return _randomType.nextObject(r, cls, allowNull); + + } else { + + // choosen at random from a fixed population. + + return keys[r.nextInt(maxDistinct)]; + + } + + } + + } + + /** + * Test helper for the ability to drop/add a link set index and the ability + * of the link set index to continue to track the link set as the later is + * cleared and repopulated. + * + * @todo parameterize to test link sets that allow and that do not allow + * duplicate keys (duplicate keys are allowed by the index used in + * this test since that is the default behavior). + */ + protected void doDropAddTest(int ntrials) { + + final ObjectManager om = getNativeObjectManager(); + + final PropertyClass ac = (PropertyClass) om.getPropertyClass( getUniquePropertyName("assoc")); + + final PropertyClass pc = (PropertyClass) om.getPropertyClass( getUniquePropertyName("value")); + + final Class cls = getType(); + + final IKeyGenerator keyGen = new KeyGenerator(ntrials/* maxDistinct */, cls); + + pc.setType( cls ); + + Generic g = new Generic( om ); + + LinkSet linkSet = (LinkSet) g.getLinkSet( ac ); + + LinkSetIndex ndx = (LinkSetIndex) linkSet.getIndex( pc ); + + /* + * Populate the link set. + */ + final int capacity = ntrials; + + Generic ary[] = new Generic[capacity]; + + for( int i=0; i<capacity; i++ ) { + + Generic t = new Generic( om ); + + t.set(ac,g); + + t.set(pc, keyGen.nextKey() ); + + ary[ i ] = t; + + } + + /* + * Verify the index against the link set. + */ + verify(linkSet, ndx); + + /* + * Clear the link set and verify the index against the link set. This + * breaks the links licensing membership in the link set but does not + * cause the link set members to be removed from the database. + */ + linkSet.clear(); + verify(linkSet, ndx); + + /* + * Add all of the objects back into the link set and verify the index + * against the link set. This verifies that the link set index is + * transparently re-created when the link set becomes non-empty. + */ + for( int i=0; i<capacity; i++ ) { + ary[ i ].set(ac, g); + } + verify(linkSet, ndx); + + /* + * Rebuild the index. + */ + ndx.rebuildIndex(); + + /* + * Verify the rebuilt index against the link set. + */ + verify(linkSet, ndx); + + /* + * Verify that we can rebuild the index again (this operation should be + * repeatable if and when desired). + */ + ndx.rebuildIndex(); + + /* + * Verify the rebuilt index against the link set. + */ + verify(linkSet, ndx); + + /* + * Modify a property value and verify that the index is tracking + * updates. + */ + if( true ) { + Generic t = ary[r.nextInt(ary.length)]; + t.set(pc,keyGen.nextKey()); + verify(linkSet, ndx); + } + + /* + * Unlink a link set member and verify that the index is tracking + * updates. + */ + final Generic unlinked; + if( true ) { + Generic t = ary[r.nextInt(ary.length)]; + t.set(ac,null); + verify(linkSet, ndx); + unlinked = t; + } + + /* + * Re-link a link set member and verify that the index is tracking + * updates. + */ + if( true ) { + unlinked.set(ac,g); + verify(linkSet, ndx); + } + + } + + /** * <p> * Test helper for index stress tests. The stress test creates and deletes *************** *** 982,993 **** * an exception or failed assertion. * * @todo The ability to efficiently drop an index requires (a) that it is * isolated within its own segment(s); and (b) that we factor out the * per-object index state into state on a prototype object so that we * do not have to touch each object in the index when we drop the ! * index. (Re-)building an index of course requires a link set scan. ! * There are opportunities for somewhat greater efficiencies if we ! * sort the link set by property value first when using a btree ! * implementation that handles right most additions efficiently. * * @todo Periodically we can change the indexClass metadata before --- 1189,1204 ---- * an exception or failed assertion. * + * @todo parameterize to test link sets that allow and that do not allow + * duplicate keys (duplicate keys are allowed by the index used in + * this test since that is the default behavior). the key generator + * used must be selected based on whether or not duplicate keys will + * be allowed. + * * @todo The ability to efficiently drop an index requires (a) that it is * isolated within its own segment(s); and (b) that we factor out the * per-object index state into state on a prototype object so that we * do not have to touch each object in the index when we drop the ! * index. (Re-)building an index of course requires a link set scan, ! * which should be chunked and use ordered writes for efficiency. * * @todo Periodically we can change the indexClass metadata before *************** *** 1001,1030 **** * abort (rollback to the last time the native transaction counter * reached zero during a commit). - * - * @todo For GOM for Objectivity the stress test should periodically - * rollover the container or database. This can be achieved either by - * limiting the container or database size for the entire test suite - * or by explicitly running the index stress test with smaller - * container and database limits. Once the notion of a GOM database - * within a GDBMS is established, we can explicitly invoke segment - * rollover. A segment is a contiguous linear address space. Segments - * are typically on the order of 200-400M. The Objectivity container - * concept more of less corresponds to a segment. The Objectivity - * database is both a collection of segments and has some namespace - * mechanisms. */ ! ! public void doStressTest( int maxCreated, int maxOps, Op gen, IKeyGenerator keyGen, boolean logOps ) { ! if (maxCreated < 0 || maxOps < 0) { throw new IllegalArgumentException("no stopping condition"); } if (gen == null) { throw new IllegalArgumentException(); } - Random r = new Random(); - ObjectManager om = getNativeObjectManager(); --- 1212,1230 ---- * abort (rollback to the last time the native transaction counter * reached zero during a commit). */ ! public void doStressTest( int maxCreated, int maxOps, Op gen, boolean logOps ) { ! if (maxCreated < 0 && maxOps < 0) { ! throw new IllegalArgumentException("no stopping condition"); + } if (gen == null) { + throw new IllegalArgumentException(); + } ObjectManager om = getNativeObjectManager(); *************** *** 1045,1049 **** * typed. */ ! valueClass.setType( getType() ); /* --- 1245,1254 ---- * typed. */ ! ! final Class cls = getType(); ! ! final IKeyGenerator keyGen = new KeyGenerator(maxCreated/* maxDistinct */, cls); ! ! valueClass.setType( cls ); /* *************** *** 1056,1060 **** LinkSetIndex ndx = (LinkSetIndex) linkSet.getIndex(valueClass); ! Vector oids = new Vector(); // of created objects. boolean done = false; int[] opsum = new int[Op.lastOp + 1]; // #of times we do each --- 1261,1265 ---- LinkSetIndex ndx = (LinkSetIndex) linkSet.getIndex(valueClass); ! final Vector<Long> oids = new Vector<Long>(); // of created objects. boolean done = false; int[] opsum = new int[Op.lastOp + 1]; // #of times we do each *************** *** 1312,1322 **** final Comparator internalKeyComparator = ndx.getBTree().getComparator(); ! /* ! * The comparator for the coerced form of the keys. This is ! * different iff duplicate keys are supported. ! */ ! final Comparator coercedKeyComparator = (duplicateKeys ? ((CompositeKeyComparator) internalKeyComparator) ! .getDelegate() ! : internalKeyComparator); /* --- 1517,1527 ---- final Comparator internalKeyComparator = ndx.getBTree().getComparator(); ! // /* ! // * The comparator for the coerced form of the keys. This is ! // * different iff duplicate keys are supported. ! // */ ! // final Comparator coercedKeyComparator = (duplicateKeys ? ((CompositeKeyComparator) internalKeyComparator) ! // .getDelegate() ! // : internalKeyComparator); /* *************** *** 1392,1396 **** if (duplicateKeys) { ! assertTrue(internalKey instanceof ICompositeKey); assertEquals("oid", g.getOID(), --- 1597,1602 ---- if (duplicateKeys) { ! // Note: may also be an unsigned byte[]. ! if(internalKey instanceof ICompositeKey) { assertEquals("oid", g.getOID(), *************** *** 1407,1410 **** --- 1613,1618 ---- ((ICompositeKey) internalKey) .getCoercedKey()); + + } } else { *************** *** 1494,1498 **** if( duplicateKeys ) { ! assertTrue( internalKey instanceof ICompositeKey ); assertEquals("oid", g.getOID(), --- 1702,1707 ---- if( duplicateKeys ) { ! // Note: may also be an unsigned byte[]. ! if( internalKey instanceof ICompositeKey ) { assertEquals("oid", g.getOID(), *************** *** 1510,1513 **** --- 1719,1723 ---- coercedVal.equals(((ICompositeKey) internalKey) .getCoercedKey())); + } } else { *************** *** 1528,1534 **** */ ! if( nscanned > 0 ) { assertTrue(internalKeyComparator.compare(lastInternalKey, internalKey) <= 0); } --- 1738,1746 ---- */ ! if( nscanned > 0 && internalKeyComparator!=null) { ! assertTrue(internalKeyComparator.compare(lastInternalKey, internalKey) <= 0); + } *************** *** 1559,1566 **** --- 1771,1806 ---- public Object coerce(Object externalKey) { + return externalKey; + } } + /** + * A short-lived stress test. + */ + public void test_dropAdd() { + + int ntrials = 10; /* 100 */; + + doDropAddTest( ntrials ); + + } + + /** + * A short-lived stress test. Longer lived stress tests can be run by + * increasing the first two arguments by an order of magnitude or more. + */ + public void test_stress() { + + doStressTest(// + 10000,// maxCreated + 100000,// maxOps + getOpGenerator(),// + true//logOps + ); + + } + } Index: TestCharacterTypeIndex.java =================================================================== RCS file: /cvsroot/cweb/generic-native-test/src/java/org/CognitiveWeb/generic/core/ndx/TestCharacterTypeIndex.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** TestCharacterTypeIndex.java 10 Jun 2006 18:15:53 -0000 1.2 --- TestCharacterTypeIndex.java 30 Nov 2007 21:53:57 -0000 1.3 *************** *** 60,74 **** Class getType() { return Character.class; } Object[] getValues() { ! return new Character[]{new Character('a'), ! new Character('m'), ! new Character('z')}; } ! Object successor(Object key) throws NoSuccessorException { return new Character(SuccessorUtil.successor(((Character) key).charValue())); } } --- 60,83 ---- Class getType() { + return Character.class; + } Object[] getValues() { ! ! return new Character[]{ ! new Character('a'), ! new Character('m'), ! new Character('z') ! }; ! } ! Object successor(Object key) throws NoSuccessorException { + return new Character(SuccessorUtil.successor(((Character) key).charValue())); + } + } Index: TestStringTypeIndex.java =================================================================== RCS file: /cvsroot/cweb/generic-native-test/src/java/org/CognitiveWeb/generic/core/ndx/TestStringTypeIndex.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** TestStringTypeIndex.java 15 Jun 2006 15:47:01 -0000 1.6 --- TestStringTypeIndex.java 30 Nov 2007 21:53:57 -0000 1.7 *************** *** 48,58 **** package org.CognitiveWeb.generic.core.ndx; - import java.util.Random; - - import org.CognitiveWeb.generic.core.Generic; - import org.CognitiveWeb.generic.core.LinkSet; import org.CognitiveWeb.generic.core.LinkSetIndex; - import org.CognitiveWeb.generic.core.PropertyClass; - import org.CognitiveWeb.generic.core.om.ObjectManager; /** --- 48,52 ---- *************** *** 66,293 **** Class getType() { return String.class; - } - - Object[] getValues() { - return new String[] { "a", "b", "c" }; - } - - Object successor(Object key) throws NoSuccessorException { - return SuccessorUtil.successor((String) key); - } - - /** - * A key generator appropriate for the type constraint (if any) on the - * index. - * - * @return The key generator. - * - * @todo Refactor into {@link AbstractIndexTest}. This will require - * breaking the tests of indices that do and do not allow duplicate - * keys into distinct test classes so that we can run the appropriate - * key generator in each case. It will also require appropriate key - * generators for each test class. Once that is done, refactor the - * {@link #test_stress()} and {@link #test_dropAdd()} test methods - * into the {@link AbstractIndexTest} class so that they are also - * run for each kind of typed and untyped index. - */ - public IKeyGenerator getKeyGenerator() { - - return new StringKeyGenerator(true); } ! /** ! * Key generator takes the type constraint from the index. ! * ! * @author <a href="mailto:tho...@us...">Bryan Thompson</a> ! * @version $Id$ ! */ ! ! public class StringKeyGenerator implements IKeyGenerator { ! ! /** ! * FIXME In order to generate duplicate keys there must be a reasonable ! * period to the keys. In order to guarentee distinct keys we must use a ! * one up identifier to make ties impossible. ! */ ! public StringKeyGenerator( boolean duplicateKeys ) { ! } ! ! public Object nextKey() {return getRandomString(10);} ! ! /** ! * Returns a random string of Unicode characters. The "-" character is ! * NOT included in the returned string and may be used to delimit the ! * random characters from a unique one up identifier to obtain a ! * guarenteed unique value. ! * ! * @param len ! * The maximum length of the string. Each generated literal ! * will have a mean length of <code>len/2</code> and the ! * lengths will be distributed using a normal distribution ! * (bell curve). ! */ ! ! public String getRandomString( int len ) ! { ! ! // final String data = "0123456789!@#$%^&*()`~-_=+[{]}\\|;:'\",<.>/?QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm"; ! final String data = "0123456789QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm"; ! ! int[] order = getRandomOrder( data.length() ); ! ! int n = getNormalInt( len ); ! StringBuffer sb = new StringBuffer( n ); ! ! int index = 0; - for( int i=0; i<n; i++ ) { - - sb.append( data.charAt( order[ index++ ] ) ); - - if( index == order.length ) { - - index = 0; - - } - - } - - return sb.toString(); - - } - } ! /** ! * Various tests of the ability to drop/add a link set index and the ability ! * of the link set index to continue to track the link set as the later is ! * cleared and repopulated. ! */ ! public void test_dropAdd() { ! ! Random r = new Random(); ! ! ObjectManager om = getNativeObjectManager(); ! ! PropertyClass ac = (PropertyClass) om.getPropertyClass( getUniquePropertyName("assoc")); ! ! PropertyClass pc = (PropertyClass) om.getPropertyClass( getUniquePropertyName("value")); ! ! pc.setType( getType() ); ! ! IKeyGenerator keyGen = getKeyGenerator(); ! ! Generic g = new Generic( om ); ! ! LinkSet linkSet = (LinkSet) g.getLinkSet( ac ); ! ! LinkSetIndex ndx = (LinkSetIndex) linkSet.getIndex( pc ); ! ! /* ! * Populate the link set. ! */ ! final int capacity = 3; /* 100 */ ! ! Generic ary[] = new Generic[capacity]; ! ! for( int i=0; i<capacity; i++ ) { ! ! Generic t = new Generic( om ); ! ! t.set(ac,g); ! ! t.set(pc, keyGen.nextKey() ); ! ! ary[ i ] = t; ! ! } ! ! /* ! * Verify the index against the link set. ! */ ! verify(linkSet, ndx); ! ! /* ! * Clear the link set and verify the index against the link set. This ! * breaks the links licensing membership in the link set but does not ! * cause the link set members to be removed from the database. ! */ ! linkSet.clear(); ! verify(linkSet, ndx); ! ! /* ! * Add all of the objects back into the link set and verify the index ! * against the link set. This verifies that the link set index is ! * transparently re-created when the link set becomes non-empty. ! */ ! for( int i=0; i<capacity; i++ ) { ! ary[ i ].set(ac, g); ! } ! verify(linkSet, ndx); ! ! /* ! * Rebuild the index. ! */ ! ndx.rebuildIndex(); ! ! /* ! * Verify the rebuilt index against the link set. ! */ ! verify(linkSet, ndx); ! /* ! * Verify that we can rebuild the index again (this operation should be ! * repeatable if and when desired). ! */ ! ndx.rebuildIndex(); ! /* ! * Verify the rebuilt index against the link set. ! */ ! verify(linkSet, ndx); ! ! /* ! * Modify a property value and verify that the index is tracking ! * updates. ! */ ! if( true ) { ! Generic t = ary[r.nextInt(ary.length)]; ! t.set(pc,keyGen.nextKey()); ! verify(linkSet, ndx); ! } ! ! /* ! * Unlink a link set member and verify that the index is tracking ! * updates. ! */ ! final Generic unlinked; ! if( true ) { ! Generic t = ary[r.nextInt(ary.length)]; ! t.set(ac,null); ! verify(linkSet, ndx); ! unlinked = t; ! } ! ! /* ! * Re-link a link set member and verify that the index is tracking ! * updates. ! */ ! if( true ) { ! unlinked.set(ac,g); ! verify(linkSet, ndx); ! } ! ! } ! ! /** ! * A short-lived stress test. Longer lived stress tests can be run by ! * increasing the first two arguments by an order of magnitude or more. ! */ ! public void test_stress() { ! doStressTest( 10000, 100000, getOpGenerator(), getKeyGenerator(), false ); ! } } --- 60,79 ---- Class getType() { + return String.class; } ! Object[] getValues() { ! return new String[] { "a", "b", "c" }; } ! Object successor(Object key) throws NoSuccessorException { ! return SuccessorUtil.successor((String) key); ! } } |