|
From: Bryan T. <tho...@us...> - 2007-04-10 18:33:39
|
Update of /cvsroot/cweb/bigdata/src/test/com/bigdata/objndx In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv24584/src/test/com/bigdata/objndx Modified Files: TestAll.java TestIndexSegmentBuilderWithSmallTree.java AbstractBTreeTestCase.java Added Files: TestDataOutputBuffer.java TestLongPacker.java TestShortPacker.java Log Message: Fixed a bug in UUID assignment to index segments. Added some logic for fast data output for btree nodes and leaves. Index: TestIndexSegmentBuilderWithSmallTree.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/test/com/bigdata/objndx/TestIndexSegmentBuilderWithSmallTree.java,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** TestIndexSegmentBuilderWithSmallTree.java 8 Mar 2007 18:14:05 -0000 1.10 --- TestIndexSegmentBuilderWithSmallTree.java 10 Apr 2007 18:33:31 -0000 1.11 *************** *** 417,421 **** public void test_problem3_buildOrder3() throws IOException { ! BTree btree = getProblem3(); btree.dump(Level.DEBUG,System.err); --- 417,421 ---- public void test_problem3_buildOrder3() throws IOException { ! final BTree btree = getProblem3(); btree.dump(Level.DEBUG,System.err); Index: AbstractBTreeTestCase.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/test/com/bigdata/objndx/AbstractBTreeTestCase.java,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** AbstractBTreeTestCase.java 27 Mar 2007 14:34:21 -0000 1.32 --- AbstractBTreeTestCase.java 10 Apr 2007 18:33:31 -0000 1.33 *************** *** 1555,1562 **** assert actual != null; ! assertEquals("indexUUID",expected.getIndexUUID(), actual.getIndexUUID()); // The #of entries must agree. ! assertEquals("entryCount",expected.getEntryCount(), actual.getEntryCount()); // verify the entry iterator. --- 1555,1565 ---- assert actual != null; ! // Must be the same "index". ! assertEquals("indexUUID", expected.getIndexUUID(), actual ! .getIndexUUID()); // The #of entries must agree. ! assertEquals("entryCount", expected.getEntryCount(), actual ! .getEntryCount()); // verify the entry iterator. --- NEW FILE: TestLongPacker.java --- /** The Notice below must appear in each file of the Source Code of any copy you distribute of the Licensed Product. Contributors to any Modifications may add their own copyright notices to identify their own contributions. License: The contents of this file are subject to the CognitiveWeb Open Source License Version 1.1 (the License). You may not copy or use this file, in either source code or executable form, except in compliance with the License. You may obtain a copy of the License from http://www.CognitiveWeb.org/legal/license/ Software distributed under the License is distributed on an AS IS basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Copyrights: Portions created by or assigned to CognitiveWeb are Copyright (c) 2003-2003 CognitiveWeb. All Rights Reserved. Contact information for CognitiveWeb is available at http://www.CognitiveWeb.org Portions Copyright (c) 2002-2003 Bryan Thompson. Acknowledgements: Special thanks to the developers of the Jabber Open Source License 1.0 (JOSL), from which this License was derived. This License contains terms that differ from JOSL. Special thanks to the CognitiveWeb Open Source Contributors for their suggestions and support of the Cognitive Web. Modifications: */ /* * Created on Oct 28, 2005 */ package com.bigdata.objndx; import java.io.IOException; import java.util.Random; import junit.framework.TestCase; /** * Test suite for packing and unpacking unsigned long integers. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ */ public class TestLongPacker extends TestCase { /** * */ public TestLongPacker() { super(); } /** * @param name */ public TestLongPacker(String name) { super(name); } /** * Unpacks a long. * * @param expected The expected long value. * * @param packed The packed byte[]. * * @throws IOException * If there was not enough data. * * @throws junit.framework.AssertionFailedError * If there is too much data. */ public void doUnpackTest( long expected, byte[] packed ) throws IOException { DataInputBuffer dib = new DataInputBuffer(packed); long actual = dib.unpackLong(); assertEquals( "value", expected, actual ); // assertTrue( "Expecting EOF", dib.read() == -1 ); try { dib.readByte(); fail("Expecting: "+IOException.class); } catch(IOException ex) { System.err.println("Ignoring expected exception: "+ex); } } /** * Given the first byte of a packed long value, return the #of bytes into which * that value was packed (including this one). * * @param firstByte The first byte. * * @return The #of bytes. This is in the range [1:8] inclusive. */ public int getNBytes( int firstByte ) { int nbytes; if( ( firstByte & 0x80 ) != 0 ) { // high bit is set. nbytes = 8; } else { nbytes = firstByte >> 4; // clear the high bit and right shift one nibble. } return nbytes; } public void testNBytes() { // high bit is set - always 8 bytes. assertEquals( "nbytes", 8, getNBytes( 0x80 ) ); assertEquals( "nbytes", 8, getNBytes( 0x81 ) ); assertEquals( "nbytes", 8, getNBytes( 0x8e ) ); assertEquals( "nbytes", 8, getNBytes( 0x8f ) ); // high bit is NOT set. nbytes is the upper nibble. assertEquals( "nbytes", 1, getNBytes( 0x10 ) ); assertEquals( "nbytes", 2, getNBytes( 0x20 ) ); assertEquals( "nbytes", 3, getNBytes( 0x30 ) ); assertEquals( "nbytes", 4, getNBytes( 0x40 ) ); assertEquals( "nbytes", 5, getNBytes( 0x50 ) ); assertEquals( "nbytes", 6, getNBytes( 0x60 ) ); assertEquals( "nbytes", 7, getNBytes( 0x70 ) ); // high bit is NOT set. nbytes is the upper nibble. assertEquals( "nbytes", 1, getNBytes( 0x11 ) ); assertEquals( "nbytes", 2, getNBytes( 0x21 ) ); assertEquals( "nbytes", 3, getNBytes( 0x31 ) ); assertEquals( "nbytes", 4, getNBytes( 0x41 ) ); assertEquals( "nbytes", 5, getNBytes( 0x51 ) ); assertEquals( "nbytes", 6, getNBytes( 0x61 ) ); assertEquals( "nbytes", 7, getNBytes( 0x71 ) ); // high bit is NOT set. nbytes is the upper nibble. assertEquals( "nbytes", 1, getNBytes( 0x1f ) ); assertEquals( "nbytes", 2, getNBytes( 0x2f ) ); assertEquals( "nbytes", 3, getNBytes( 0x3f ) ); assertEquals( "nbytes", 4, getNBytes( 0x4f ) ); assertEquals( "nbytes", 5, getNBytes( 0x5f ) ); assertEquals( "nbytes", 6, getNBytes( 0x6f ) ); assertEquals( "nbytes", 7, getNBytes( 0x7f ) ); } public void testUnpack() throws IOException { // upper nibble is 1, so nbytes == 1 and the lower nibble is the value. doUnpackTest( 0x0, new byte[]{(byte)0x10} ); doUnpackTest( 0x1, new byte[]{(byte)0x11} ); doUnpackTest( 0x7, new byte[]{(byte)0x17} ); doUnpackTest( 0xf, new byte[]{(byte)0x1f} ); // upper nibble is 2, so nbytes == 2. doUnpackTest( 0xf00, new byte[]{(byte)0x2f, (byte)0x00} ); doUnpackTest( 0xfa7, new byte[]{(byte)0x2f, (byte)0xa7} ); doUnpackTest( 0xfa0, new byte[]{(byte)0x2f, (byte)0xa0} ); doUnpackTest( 0xf07, new byte[]{(byte)0x2f, (byte)0x07} ); // upper nibble is 3, so nbytes == 3. doUnpackTest( 0xcaa4d, new byte[]{(byte)0x3c, (byte)0xaa, (byte)0x4d} ); // high bit only, lower nibble plus next seven bytes are the value. doUnpackTest( 0xaeede00a539271fL, new byte[]{(byte)0x8a, (byte)0xee, (byte)0xde, (byte)0x00, (byte)0xa5, (byte)0x39, (byte)0x27, (byte)0x1f } ); } public void doPackTest( long v, byte[] expected ) throws IOException { DataOutputBuffer dob = new DataOutputBuffer(); final int nbytes = dob.packLong( v ); final byte[] actual = dob.toByteArray(); assertEquals( "nbytes", expected.length, nbytes ); assertEquals( "nbytes", getNBytes(expected[0]), nbytes ); assertEquals( "bytes", expected, actual ); } public void test_getNibbleLength() { // Note: zero (0) is interpreted as being one nibble for our purposes. assertEquals( "nibbles", 1, DataOutputBuffer.getNibbleLength( 0x0 ) ); assertEquals( "nibbles", 1, DataOutputBuffer.getNibbleLength( 0x1 ) ); assertEquals( "nibbles", 1, DataOutputBuffer.getNibbleLength( 0x2 ) ); assertEquals( "nibbles", 1, DataOutputBuffer.getNibbleLength( 0x7 ) ); assertEquals( "nibbles", 1, DataOutputBuffer.getNibbleLength( 0x8 ) ); assertEquals( "nibbles", 1, DataOutputBuffer.getNibbleLength( 0xe ) ); assertEquals( "nibbles", 1, DataOutputBuffer.getNibbleLength( 0xf ) ); assertEquals( "nibbles", 2, DataOutputBuffer.getNibbleLength( 0x10 ) ); assertEquals( "nibbles", 2, DataOutputBuffer.getNibbleLength( 0x11 ) ); assertEquals( "nibbles", 2, DataOutputBuffer.getNibbleLength( 0x12 ) ); assertEquals( "nibbles", 2, DataOutputBuffer.getNibbleLength( 0x17 ) ); assertEquals( "nibbles", 2, DataOutputBuffer.getNibbleLength( 0x18 ) ); assertEquals( "nibbles", 2, DataOutputBuffer.getNibbleLength( 0x1e ) ); assertEquals( "nibbles", 2, DataOutputBuffer.getNibbleLength( 0x1f ) ); assertEquals( "nibbles", 2, DataOutputBuffer.getNibbleLength( 0x7f ) ); assertEquals( "nibbles", 2, DataOutputBuffer.getNibbleLength( 0x8f ) ); assertEquals( "nibbles", 2, DataOutputBuffer.getNibbleLength( 0xff ) ); assertEquals( "nibbles", 3, DataOutputBuffer.getNibbleLength( 0x100 ) ); assertEquals( "nibbles", 3, DataOutputBuffer.getNibbleLength( 0x101 ) ); assertEquals( "nibbles", 3, DataOutputBuffer.getNibbleLength( 0x121 ) ); assertEquals( "nibbles", 3, DataOutputBuffer.getNibbleLength( 0x1ee ) ); assertEquals( "nibbles", 3, DataOutputBuffer.getNibbleLength( 0x1ff ) ); assertEquals( "nibbles", 3, DataOutputBuffer.getNibbleLength( 0xfff ) ); assertEquals( "nibbles", 4, DataOutputBuffer.getNibbleLength( 0x1ff0 ) ); assertEquals( "nibbles", 4, DataOutputBuffer.getNibbleLength( 0x7ff0 ) ); assertEquals( "nibbles", 4, DataOutputBuffer.getNibbleLength( 0xfff0 ) ); assertEquals( "nibbles", 4, DataOutputBuffer.getNibbleLength( 0xfff1 ) ); assertEquals( "nibbles", 5, DataOutputBuffer.getNibbleLength( 0x12345 ) ); assertEquals( "nibbles", 5, DataOutputBuffer.getNibbleLength( 0x54321 ) ); assertEquals( "nibbles", 6, DataOutputBuffer.getNibbleLength( 0x123456 ) ); assertEquals( "nibbles", 6, DataOutputBuffer.getNibbleLength( 0x654321 ) ); assertEquals( "nibbles", 7, DataOutputBuffer.getNibbleLength( 0x1234567 ) ); assertEquals( "nibbles", 7, DataOutputBuffer.getNibbleLength( 0x7654321 ) ); /* * Note: At 8 nibbles we have 32 bits. When the high bit is one, this * MUST be expressed as a long (trailing 'L', NOT cast to a long) or it * will be interpreted as a negative integer and sign extended to a * negative long. */ assertEquals( "nibbles", 8, DataOutputBuffer.getNibbleLength( 0x12345678L ) ); assertEquals( "nibbles", 8, DataOutputBuffer.getNibbleLength( 0x87654321L ) ); assertEquals( "nibbles", 9, DataOutputBuffer.getNibbleLength( 0x123456789L ) ); assertEquals( "nibbles", 9, DataOutputBuffer.getNibbleLength( 0x987654321L ) ); assertEquals( "nibbles", 10, DataOutputBuffer.getNibbleLength( 0x123456789aL ) ); assertEquals( "nibbles", 10, DataOutputBuffer.getNibbleLength( 0xa987654321L ) ); assertEquals( "nibbles", 11, DataOutputBuffer.getNibbleLength( 0x123456789abL ) ); assertEquals( "nibbles", 11, DataOutputBuffer.getNibbleLength( 0xba987654321L ) ); assertEquals( "nibbles", 12, DataOutputBuffer.getNibbleLength( 0x123456789abcL ) ); assertEquals( "nibbles", 12, DataOutputBuffer.getNibbleLength( 0xcba987654321L ) ); assertEquals( "nibbles", 13, DataOutputBuffer.getNibbleLength( 0x123456789abcdL ) ); assertEquals( "nibbles", 13, DataOutputBuffer.getNibbleLength( 0xdcba987654321L ) ); assertEquals( "nibbles", 14, DataOutputBuffer.getNibbleLength( 0x123456789abcdeL ) ); assertEquals( "nibbles", 14, DataOutputBuffer.getNibbleLength( 0xedcba987654321L ) ); assertEquals( "nibbles", 15, DataOutputBuffer.getNibbleLength( 0x123456789abcdefL ) ); assertEquals( "nibbles", 15, DataOutputBuffer.getNibbleLength( 0xfedcba987654321L ) ); assertEquals( "nibbles", 16, DataOutputBuffer.getNibbleLength( 0x1234567890abcdefL ) ); assertEquals( "nibbles", 16, DataOutputBuffer.getNibbleLength( 0xfedcba0987654321L ) ); } public void testPack() throws IOException { // [0:15] should be packed into one byte. doPackTest( 0x0, new byte[]{(byte)0x10} ); doPackTest( 0x1, new byte[]{(byte)0x11} ); doPackTest( 0x2, new byte[]{(byte)0x12} ); doPackTest( 0xe, new byte[]{(byte)0x1e} ); doPackTest( 0xf, new byte[]{(byte)0x1f} ); /* * 0x10 through 0xfff overflow the lower nibble, so the value is packed * into two bytes. the first byte has the header and the next three * nibbles are the value. This case is good for up to 2^12, since there * are three full nibbles to encode the value. */ doPackTest( 0x10, new byte[]{(byte)0x20, (byte)0x10 }); doPackTest( 0x11, new byte[]{(byte)0x20, (byte)0x11 }); doPackTest( 0x1f, new byte[]{(byte)0x20, (byte)0x1f }); doPackTest( 0x20, new byte[]{(byte)0x20, (byte)0x20 }); doPackTest( 0xff, new byte[]{(byte)0x20, (byte)0xff }); doPackTest( 0x100, new byte[]{(byte)0x21, (byte)0x00 }); doPackTest( 0x101, new byte[]{(byte)0x21, (byte)0x01 }); doPackTest( 0x121, new byte[]{(byte)0x21, (byte)0x21 }); doPackTest( 0x1ee, new byte[]{(byte)0x21, (byte)0xee }); doPackTest( 0x1ff, new byte[]{(byte)0x21, (byte)0xff }); doPackTest( 0xfff, new byte[]{(byte)0x2f, (byte)0xff }); /* * 0x1000 through 0xfffff fit into one more byte. */ doPackTest( 0x1000, new byte[]{(byte)0x30, (byte)0x10, (byte)0x00 }); doPackTest( 0x1234, new byte[]{(byte)0x30, (byte)0x12, (byte)0x34 }); doPackTest( 0x1fff, new byte[]{(byte)0x30, (byte)0x1f, (byte)0xff }); doPackTest( 0x54321, new byte[]{(byte)0x35, (byte)0x43, (byte)0x21 }); doPackTest( 0xfffff, new byte[]{(byte)0x3f, (byte)0xff, (byte)0xff }); } public static final long SIGN_MASK = 1L<<63; public void testHighBit() { assertTrue( "sign bit", ( -1L & SIGN_MASK ) != 0 ); assertFalse( "sign bit", ( 0L & SIGN_MASK ) != 0 ); } private interface LongGenerator { public long nextLong(); } /** * All long values in sequence starting from the given start value * and using the given increment. * @author thompsonbry */ private static class Sequence implements LongGenerator { long _start, _inc, _next; public Sequence( long start, long inc ) { _start = start; _inc = inc; _next = start; } public long nextLong() { long v = _next; _next += _inc; return v; // double d = rnd.nextGaussian(); //// if( d < 0 ) d = -d; // final long expected = (long) ( d * Long.MAX_VALUE ); } } /** * Random long values (32 bits of random long), including negatives, * with a uniform distribution. * * @author thompsonbry */ private static class RandomLong implements LongGenerator { Random _rnd; public RandomLong( Random rnd ) { _rnd = rnd; } public long nextLong() { return _rnd.nextLong(); } } /** * Run a large #of pack/unpack operations on a sequence of long values to * demonstrate correctness in that sequence. The sequence is the long * values from -1 to 1M by one (dense coverage). * * @throws IOException */ public void testStressSequence() throws IOException { // dense coverage of the first 1M values. doStressTest( 1000000, new Sequence( -1, 1 ) ); } /** * Run a large #of random pack/unpack operations to sample the space while * showing correctness on those samples. The amount of compression due to * packing for this test is <em>very</em> small since all bits are equally * likely to be non-zero, so the #of bytes required on average to pack a * long value is 8. * * @throws IOException */ public void testStressRandom() throws IOException { // test on 1M random long values. doStressTest( 1000000, new RandomLong( new Random() ) ); } /** * Run a stress test. Writes some information of possible interest onto * System.err. * * @param ntrials #of trials. * * @param g Generator for the long values. * * @throws IOException */ public void doStressTest( int ntrials, LongGenerator g ) throws IOException { long nwritten = 0L; long packlen = 0L; long minv = Long.MAX_VALUE, maxv = Long.MIN_VALUE; for( int i=0; i<ntrials; i++ ) { long expected = g.nextLong(); if( expected < 0L ) { DataOutputBuffer dos = new DataOutputBuffer(); try { dos.packLong( expected ); fail( "Expecting rejection of negative value: val="+expected ); } catch( IllegalArgumentException ex ) { // System.err.println( "Ingoring expected exception: "+ex ); } } else { if( expected > maxv ) maxv = expected; if( expected < minv ) minv = expected; DataOutputBuffer dos = new DataOutputBuffer(); final int actualByteLength1 = dos.packLong( expected ); byte[] packed = dos.toByteArray(); final int actualByteLength2 = getNBytes( packed[ 0 ] ); DataInputBuffer dis = new DataInputBuffer( packed ); final long actual = dis.unpackLong(); assertEquals( "trial="+i, expected, actual ); assertEquals( "trial="+i+", v="+expected+", nbytes", actualByteLength1, actualByteLength2 ); packlen += packed.length; // total #of packed bytes. nwritten++; // count #of non-negative random values. } } System.err.println( "\nWrote "+nwritten+" non-negative long values." ); System.err.println( "minv="+minv+", maxv="+maxv ); System.err.println( "#packed bytes ="+packlen ); System.err.println( "#bytes if not packed="+(nwritten * 8)); long nsaved = ( nwritten * 8 ) - packlen; System.err.println ("#bytes saved ="+nsaved); System.err.println( "%saved by packing ="+nsaved/(nwritten*8f)*100+"%"); } public static void assertEquals( String msg, byte[] expected, byte[] actual ) { assertEquals( msg+": length", expected.length, actual.length ); for( int i=0; i<expected.length; i++ ) { assertEquals( msg+": byte[i="+i+"]", expected[i], actual[i] ); } } } --- NEW FILE: TestDataOutputBuffer.java --- /** The Notice below must appear in each file of the Source Code of any copy you distribute of the Licensed Product. Contributors to any Modifications may add their own copyright notices to identify their own contributions. License: The contents of this file are subject to the CognitiveWeb Open Source License Version 1.1 (the License). You may not copy or use this file, in either source code or executable form, except in compliance with the License. You may obtain a copy of the License from http://www.CognitiveWeb.org/legal/license/ Software distributed under the License is distributed on an AS IS basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Copyrights: Portions created by or assigned to CognitiveWeb are Copyright (c) 2003-2003 CognitiveWeb. All Rights Reserved. Contact information for CognitiveWeb is available at http://www.CognitiveWeb.org Portions Copyright (c) 2002-2003 Bryan Thompson. Acknowledgements: Special thanks to the developers of the Jabber Open Source License 1.0 (JOSL), from which this License was derived. This License contains terms that differ from JOSL. Special thanks to the CognitiveWeb Open Source Contributors for their suggestions and support of the Cognitive Web. Modifications: */ /* * Created on Apr 9, 2007 */ package com.bigdata.objndx; import java.io.IOException; import java.util.Random; import junit.framework.TestCase; import junit.framework.TestCase2; /** * Test suite for {@link DataOutputBuffer}. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ */ public class TestDataOutputBuffer extends TestCase2 { /** * */ public TestDataOutputBuffer() { } /** * @param arg0 */ public TestDataOutputBuffer(String arg0) { super(arg0); } /** * ctor tests, including correct rejection. */ public void test_ctor() { { DataOutputBuffer buf = new DataOutputBuffer(); assertNotNull(buf.buf); assertEquals(DataOutputBuffer.DEFAULT_INITIAL_CAPACITY, buf.buf.length); assertEquals(0, buf.len); } { DataOutputBuffer buf = new DataOutputBuffer(0); assertNotNull(buf.buf); assertEquals(0, buf.buf.length); assertEquals(0, buf.len); } { DataOutputBuffer buf = new DataOutputBuffer(20); assertNotNull(buf.buf); assertEquals(20, buf.buf.length); assertEquals(0, buf.len); } { final byte[] expected = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; DataOutputBuffer buf = new DataOutputBuffer(4, expected); assertNotNull(buf.buf); assertEquals(4, buf.len); assertEquals(10, buf.buf.length); assertTrue(expected == buf.buf); } } /* * correct rejection tests. */ { try { new DataOutputBuffer(-1); fail("Expecting: " + IllegalArgumentException.class); } catch (IllegalArgumentException ex) { System.err.println("Ignoring expected exception: " + ex); } } { try { new DataOutputBuffer(20, new byte[10]); fail("Expecting: " + IllegalArgumentException.class); } catch (IllegalArgumentException ex) { System.err.println("Ignoring expected exception: " + ex); } } public void test_DataOutputBuffer_ensureCapacity() { DataOutputBuffer DataOutputBuffer = new DataOutputBuffer(0); assertEquals(0, DataOutputBuffer.len); assertNotNull(DataOutputBuffer.buf); assertEquals(0, DataOutputBuffer.buf.length); final byte[] originalBuffer = DataOutputBuffer.buf; // correct rejection. try { DataOutputBuffer.ensureCapacity(-1); fail("Expecting: " + IllegalArgumentException.class); } catch (IllegalArgumentException ex) { System.err.println("Ignoring expected exception: " + ex); } assertTrue(originalBuffer == DataOutputBuffer.buf); // same buffer. // no change. DataOutputBuffer.ensureCapacity(0); assertEquals(0, DataOutputBuffer.len); assertNotNull(DataOutputBuffer.buf); assertEquals(0, DataOutputBuffer.buf.length); assertTrue(originalBuffer == DataOutputBuffer.buf); // same buffer. } public void test_DataOutputBuffer_ensureCapacity02() { DataOutputBuffer DataOutputBuffer = new DataOutputBuffer(0); assertEquals(0, DataOutputBuffer.len); assertNotNull(DataOutputBuffer.buf); assertEquals(0, DataOutputBuffer.buf.length); final byte[] originalBuffer = DataOutputBuffer.buf; // extends buffer. DataOutputBuffer.ensureCapacity(100); assertEquals(0, DataOutputBuffer.len); assertNotNull(DataOutputBuffer.buf); assertEquals(100, DataOutputBuffer.buf.length); assertTrue(originalBuffer != DataOutputBuffer.buf); // same buffer. } /** * verify that existing data is preserved if the capacity is extended. */ public void test_DataOutputBuffer_ensureCapacity03() { Random r = new Random(); byte[] expected = new byte[20]; r.nextBytes(expected); DataOutputBuffer DataOutputBuffer = new DataOutputBuffer(20, expected); assertEquals(20, DataOutputBuffer.len); assertNotNull(DataOutputBuffer.buf); assertTrue(expected == DataOutputBuffer.buf); DataOutputBuffer.ensureCapacity(30); assertEquals(20, DataOutputBuffer.len); assertTrue(DataOutputBuffer.buf.length >= 30); assertEquals(0, BytesUtil.compareBytesWithLenAndOffset(0, expected.length, expected, 0, expected.length, DataOutputBuffer.buf)); for (int i = 21; i < 30; i++) { assertEquals(0, DataOutputBuffer.buf[i]); } } public void test_DataOutputBuffer_ensureFree() { DataOutputBuffer DataOutputBuffer = new DataOutputBuffer(0); assertEquals(0, DataOutputBuffer.len); assertNotNull(DataOutputBuffer.buf); assertEquals(0, DataOutputBuffer.buf.length); DataOutputBuffer.ensureFree(2); assertEquals(0, DataOutputBuffer.len); assertNotNull(DataOutputBuffer.buf); assertTrue(DataOutputBuffer.buf.length >= 2); } /** * Tests ability to append to the buffer, including with overflow of the * buffer capacity. */ public void test_DataOutputBuffer_append_bytes() throws IOException { // setup buffer with some data and two(2) free bytes. DataOutputBuffer DataOutputBuffer = new DataOutputBuffer(5, new byte[] { 1, 2, 3, 4, 5, 0, 0 }); /* * fill to capacity by copying two bytes from the middle of another * array. since this does not overflow we know the exact capacity of the * internal buffer (it is not reallocated). */ byte[] tmp = new byte[] { 4, 5, 6, 7, 8, 9 }; DataOutputBuffer.write(tmp, 2, 2); assertEquals(7, DataOutputBuffer.len); assertEquals(new byte[] { 1, 2, 3, 4, 5, 6, 7 }, DataOutputBuffer.buf); assertEquals(0, BytesUtil.compareBytes( new byte[] { 1, 2, 3, 4, 5, 6, 7 }, DataOutputBuffer.buf)); // overflow capacity (new capacity is not known in advance). tmp = new byte[] { 8, 9, 10 }; byte[] expected = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; DataOutputBuffer.write(tmp); assertEquals(10, DataOutputBuffer.len); assertEquals(0, BytesUtil.compareBytesWithLenAndOffset(0, expected.length, expected, 0, DataOutputBuffer.len, DataOutputBuffer.buf)); // possible overflow (old and new capacity are unknown). tmp = new byte[] { 11, 12 }; expected = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; DataOutputBuffer.write(tmp); assertEquals(12, DataOutputBuffer.len); assertEquals(0, BytesUtil.compareBytesWithLenAndOffset(0, expected.length, expected, 0, DataOutputBuffer.len, DataOutputBuffer.buf)); } /** * Test ability to extract and return a key. */ public void test_DataOutputBuffer_getKey() { DataOutputBuffer DataOutputBuffer = new DataOutputBuffer(5, new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); byte[] key = DataOutputBuffer.toByteArray(); assertEquals(5, key.length); assertEquals(new byte[] { 1, 2, 3, 4, 5 }, key); } /** * Verify returns zero length byte[] when the key has zero bytes. */ public void test_DataOutputBuffer_getKey_len0() { DataOutputBuffer DataOutputBuffer = new DataOutputBuffer(); byte[] key = DataOutputBuffer.toByteArray(); assertEquals(0, key.length); } /** * Test ability to reset the key buffer (simply zeros the #of valid bytes in * the buffer without touching the buffer itself). */ public void test_DataOutputBuffer_reset() { byte[] expected = new byte[10]; DataOutputBuffer DataOutputBuffer = new DataOutputBuffer(5, expected); assertEquals(5, DataOutputBuffer.len); assertTrue(expected == DataOutputBuffer.buf); assertTrue(DataOutputBuffer == DataOutputBuffer.reset()); assertEquals(0, DataOutputBuffer.len); assertTrue(expected == DataOutputBuffer.buf); } public void test_roundTrip() { fail("write tests"); } public void test_fencePosts() { fail("write tests"); } } --- NEW FILE: TestShortPacker.java --- /** The Notice below must appear in each file of the Source Code of any copy you distribute of the Licensed Product. Contributors to any Modifications may add their own copyright notices to identify their own contributions. License: The contents of this file are subject to the CognitiveWeb Open Source License Version 1.1 (the License). You may not copy or use this file, in either source code or executable form, except in compliance with the License. You may obtain a copy of the License from http://www.CognitiveWeb.org/legal/license/ Software distributed under the License is distributed on an AS IS basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Copyrights: Portions created by or assigned to CognitiveWeb are Copyright (c) 2003-2003 CognitiveWeb. All Rights Reserved. Contact information for CognitiveWeb is available at http://www.CognitiveWeb.org Portions Copyright (c) 2002-2003 Bryan Thompson. Acknowledgements: Special thanks to the developers of the Jabber Open Source License 1.0 (JOSL), from which this License was derived. This License contains terms that differ from JOSL. Special thanks to the CognitiveWeb Open Source Contributors for their suggestions and support of the Cognitive Web. Modifications: */ /* * Created on Oct 28, 2005 */ package com.bigdata.objndx; import java.io.IOException; import java.util.Random; import junit.framework.TestCase; /** * Test suite for packing and unpacking unsigned short integers. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ */ public class TestShortPacker extends TestCase { /** * */ public TestShortPacker() { super(); } /** * @param name */ public TestShortPacker(String name) { super(name); } /** * Unpacks a short value. * * @param expected The expected long value. * * @param packed The packed byte[]. * * @throws IOException * If there was not enough data. * * @throws junit.framework.AssertionFailedError * If there is too much data. */ public void doUnpackTest( short expected, byte[] packed ) throws IOException { DataInputBuffer dib = new DataInputBuffer(packed); short actual = dib.unpackShort(); assertEquals( "value", expected, actual ); // assertTrue( "Expecting EOF", dib.read() == -1 ); try { dib.readByte(); fail("Expecting: "+IOException.class); } catch(IOException ex) { System.err.println("Ignoring expected exception: "+ex); } } /* * A short in [0:127] is packed into one byte. Larger values are packed into * two bytes. The high bit of the first byte is set if the value was packed * into two bytes. If the bit is set, clear the high bit, read the next * byte, and interpret the two bytes as a short value. Otherwise interpret * the byte as a short value. */ public void testUnpack() throws IOException { doUnpackTest( (short) 0x0, new byte[]{(byte)0x0} ); doUnpackTest( (short) 0x1, new byte[]{(byte)0x1} ); doUnpackTest( (short) 0x7, new byte[]{(byte)0x7} ); doUnpackTest( (short) 0xf, new byte[]{(byte)0xf} ); doUnpackTest( (short) 0x70, new byte[]{(byte)0x70} ); doUnpackTest( (short) 0x7f, new byte[]{(byte)0x7f} ); doUnpackTest( (short) 0x80, new byte[]{(byte)0x80, (byte)0x80} ); doUnpackTest( (short) 0x8e, new byte[]{(byte)0x80, (byte)0x8e} ); } public void doPackTest( short v, byte[] expected ) throws IOException { DataOutputBuffer dob = new DataOutputBuffer(); final int nbytes = dob.packShort( v ); final byte[] actual = dob.toByteArray(); assertEquals( "nbytes", expected.length, nbytes ); assertEquals( "bytes", expected, actual ); } public void testPack() throws IOException { // [0:127] should be packed into one byte. doPackTest( (short) 0x00, new byte[]{(byte)0x0} ); doPackTest( (short) 0x01, new byte[]{(byte)0x1} ); doPackTest( (short) 0x02, new byte[]{(byte)0x2} ); doPackTest( (short) 0x0e, new byte[]{(byte)0xe} ); doPackTest( (short) 0x0f, new byte[]{(byte)0xf} ); doPackTest( (short) 0x10, new byte[]{(byte)0x10 }); doPackTest( (short) 0x11, new byte[]{(byte)0x11 }); doPackTest( (short) 0x1f, new byte[]{(byte)0x1f }); doPackTest( (short) 0x20, new byte[]{(byte)0x20 }); doPackTest( (short) 0x70, new byte[]{(byte)0x70 }); doPackTest( (short) 0x7f, new byte[]{(byte)0x7f }); // high nibble of the short value is zero. doPackTest( (short) 0x80, new byte[]{(byte)0x80, (byte)0x80 }); doPackTest( (short) 0xff, new byte[]{(byte)0x80, (byte)0xff }); doPackTest( (short) 0x100, new byte[]{(byte)0x81, (byte)0x00 }); doPackTest( (short) 0x101, new byte[]{(byte)0x81, (byte)0x01 }); doPackTest( (short) 0x121, new byte[]{(byte)0x81, (byte)0x21 }); doPackTest( (short) 0x1ee, new byte[]{(byte)0x81, (byte)0xee }); doPackTest( (short) 0x1ff, new byte[]{(byte)0x81, (byte)0xff }); doPackTest( (short) 0xfff, new byte[]{(byte)0x8f, (byte)0xff }); } public void test_rejectNegatives() throws IOException { try { doPackTest( (short) 0x8fff, new byte[]{}); fail( "Expecting: "+IllegalArgumentException.class ); } catch( IllegalArgumentException ex ) { System.err.println( "Ignoring expected exception: "+ex ); } try { doPackTest( (short) 0xffff, new byte[]{}); fail( "Expecting: "+IllegalArgumentException.class ); } catch( IllegalArgumentException ex ) { System.err.println( "Ignoring expected exception: "+ex ); } } public static final long SIGN_MASK = 11<<15; public void testHighBit() { assertTrue( "sign bit", ( (short)-1 & SIGN_MASK ) != 0 ); assertFalse( "sign bit", ( (short) 0 & SIGN_MASK ) != 0 ); } private interface ShortGenerator { public short nextShort(); } /** * All long values in sequence starting from the given start value * and using the given increment. * @author thompsonbry */ private static class Sequence implements ShortGenerator { short _start, _inc, _next; public Sequence( short start, short inc ) { _start = start; _inc = inc; _next = start; } public short nextShort() { if( _next == Short.MAX_VALUE ) { throw new RuntimeException( "No more short values."); } short v = _next; _next += _inc; return v; } } /** * Random short values (16 bits of random short), including negatives, * with a uniform distribution. * * @author thompsonbry */ private static class RandomShort implements ShortGenerator { Random _rnd; public RandomShort( Random rnd ) { _rnd = rnd; } public short nextShort() { return (short)_rnd.nextInt(); // truncate. } } /** * Run a large #of pack/unpack operations on a sequence of short values to * demonstrate correctness in that sequence. The sequence is the short values * from -1 to {@link Short#MAX_VALUE} by one (dense coverage). * * @throws IOException */ public void testStressSequence() throws IOException { // dense coverage of the first 1M values. doStressTest( Short.MAX_VALUE+1, new Sequence( (short)-1, (short)1 ) ); } /** * Run a large #of random pack/unpack operations to sample the space while * showing correctness on those samples. * * @throws IOException */ public void testStressRandom() throws IOException { // test on random long values. doStressTest( 0xffff, new RandomShort( new Random() ) ); } /** * Returns the #of bytes into which a short value was packed based on the * first byte. * * @param firstByte * The first byte. * * @return The #of bytes (either one (1) or two (2)). */ static int getNBytes(byte firstByte) { if ((firstByte & 0x80) != 0) { return 2; } else { return 1; } } /** * Run a stress test. Writes some information of possible interest onto * System.err. * * @param ntrials #of trials. * * @param g Generator for the long values. * * @throws IOException */ public void doStressTest( int ntrials, ShortGenerator g ) throws IOException { long nwritten = 0L; long packlen = 0L; long minv = Short.MAX_VALUE, maxv = Short.MIN_VALUE; for( int i=0; i<ntrials; i++ ) { short expected = g.nextShort(); if( expected < 0L ) { DataOutputBuffer dos = new DataOutputBuffer(); try { dos.packShort( expected ); fail( "Expecting rejection of negative value: val="+expected ); } catch( IllegalArgumentException ex ) { // System.err.println( "Ingoring expected exception: "+ex ); } } else { if( expected > maxv ) maxv = expected; if( expected < minv ) minv = expected; DataOutputBuffer dos = new DataOutputBuffer(); int nbytesActual = dos.packShort( expected ); byte[] packed = dos.toByteArray(); final int nbytesExpected = getNBytes( packed[ 0 ] ); DataInputBuffer dis = new DataInputBuffer( packed ); final short actual = dis.unpackShort(); assertEquals( "trial="+i, expected, actual ); assertEquals( "trial="+i+", v="+expected+", nbytes", nbytesExpected, nbytesActual ); assertEquals( "trial="+i+", v="+expected+", nbytes", nbytesExpected, packed.length ); packlen += packed.length; // total #of packed bytes. nwritten++; // count #of non-negative random values. } } System.err.println( "\nWrote "+nwritten+" non-negative long values." ); System.err.println( "minv="+minv+", maxv="+maxv ); System.err.println( "#packed bytes ="+packlen ); System.err.println( "#bytes if not packed="+(nwritten * 8)); long nsaved = ( nwritten * 8 ) - packlen; System.err.println ("#bytes saved ="+nsaved); System.err.println( "%saved by packing ="+nsaved/(nwritten*8f)*100+"%"); } public static void assertEquals( String msg, byte[] expected, byte[] actual ) { assertEquals( msg+": length", expected.length, actual.length ); for( int i=0; i<expected.length; i++ ) { assertEquals( msg+": byte[i="+i+"]", expected[i], actual[i] ); } } } Index: TestAll.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/test/com/bigdata/objndx/TestAll.java,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** TestAll.java 15 Mar 2007 16:11:10 -0000 1.32 --- TestAll.java 10 Apr 2007 18:33:31 -0000 1.33 *************** *** 34,38 **** TestSuite suite = new TestSuite("BTree"); ! /* * test key encoding and comparison support. --- 34,45 ---- TestSuite suite = new TestSuite("BTree"); ! ! /* ! * test fast DataOutput and DataInput implementations. ! */ ! suite.addTestSuite(TestDataOutputBuffer.class); ! suite.addTestSuite(TestShortPacker.class); ! suite.addTestSuite(TestLongPacker.class); ! /* * test key encoding and comparison support. |