You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ka...@apache.org on 2007/02/01 11:43:52 UTC

svn commit: r502185 - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/services/io/FormatableBitSet.java testing/org/apache/derbyTesting/unitTests/junit/FormatableBitSetTest.java

Author: kahatlen
Date: Thu Feb  1 02:43:51 2007
New Revision: 502185

URL: http://svn.apache.org/viewvc?view=rev&rev=502185
Log:
DERBY-2191: Cleanup of FormatableBitSet

- Fixed bug in shrink() causing some unused bits to not be cleared.
- Fixed bug in shrink() causing ArrayIndexOutOfBoundsException when
  shrinking to 0.
- Throw exception when shrinking to a size larger than the current
  size or growing to negative size.

Patch contributed by Dyre Tjeldvoll.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/FormatableBitSet.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/FormatableBitSetTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/FormatableBitSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/FormatableBitSet.java?view=diff&rev=502185&r1=502184&r2=502185
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/FormatableBitSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/FormatableBitSet.java Thu Feb  1 02:43:51 2007
@@ -278,23 +278,28 @@
 	}
 
 	/**
-	 * Grow (widen) a FormatableBitSet to N bis
+	 * Grow (widen) a FormatableBitSet so that it contains at least N
+	 * bits. If the bitset already has more than n bits, this is a
+	 * noop. Negative values of n are not allowed.
+	 * ASSUMPTIONS: that all extra bits in the last byte are
+	 * zero.
 	 *
 	 * @param n	The number of bits you want.  The bits are
 	 *			always added as 0 and are appended to the
 	 *			least significant end of the bit array.
 	 *
-	 * ASSUMPTIONS: that all extra bits in the last byte
-	 * are zero.
 	 */
 	public void grow(int n)
 	{
-		if (n <= this.getLength())
-			return;
-
-		int delta = n - this.getLength();
-
+ 		if (n < 0) {
+ 			throw new IllegalArgumentException("Bit set cannot grow from "+
+ 											   lengthAsBits+" to "+n+" bits");
+ 		}
+		if (n <= lengthAsBits) {
+ 			return;
+ 		}
 
+		int delta = n - lengthAsBits;
 		int oldNumBytes = getLengthInBytes();
 
 		/*
@@ -334,42 +339,33 @@
 	}
 
 	/**
-	 * Shrink (narrow) a FormatableBitSet to N bits
+	 * Shrink (narrow) a FormatableBitSet to N bits. N may not be
+	 * larger than the current bitset size, or negative.
 	 *
 	 * @param n	The number of bits the caller wants.  The
 	 * 			bits are always removed from the
 	 *			least significant end of the bit array.
 	 */
-	public FormatableBitSet shrink(int n)
+	public void shrink(int n)
 	{
-		if (n < 0) {
+		if (n < 0 || n > lengthAsBits) {
 			throw new
-			IllegalArgumentException("Bit set size "+ n +
-									 " is not allowed");
-		}
-		int		numBytes;
-		int		lastByteNum;
-
-		if (n >= this.getLength())
-		{
-			return this;
+				IllegalArgumentException("Bit set cannot shrink from "+
+										 lengthAsBits+" to "+n+" bits");
 		}
 
-
-		lastByteNum = numBytesFromBits(n) - 1;
+		final int firstUnusedByte = numBytesFromBits(n);
 		bitsInLastByte = numBitsInLastByte(n);
 		lengthAsBits = n;
 
-		/*
-		** Mask out any left over bits in the
-		** last byte.  Retain the highest bits.
-		*/
-		if (bitsInLastByte != 8)
-		{
-			value[lastByteNum] &= 0xFF00 >> bitsInLastByte;
+		for (int i = firstUnusedByte; i < value.length; ++i) {
+			value[i] = 0;
+		}
+		if (firstUnusedByte > 0) {
+			// Mask out any left over bits in the
+			// last byte.  Retain the highest bits.
+			value[firstUnusedByte-1] &= 0xff00 >> bitsInLastByte;
 		}
-
-		return this;
 	}
 
 	/*

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/FormatableBitSetTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/FormatableBitSetTest.java?view=diff&rev=502185&r1=502184&r2=502185
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/FormatableBitSetTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/FormatableBitSetTest.java Thu Feb  1 02:43:51 2007
@@ -122,21 +122,21 @@
     public void testSetup() {
         assertEquals(0,empty.getLength());
         assertEquals(0,empty.getLengthInBytes());
-        assertEquals(0,empty.getByteArray().length);
         assertEquals(0,empty.getNumBitsSet());
         assertTrue(empty.invariantHolds());
+        assertEquals(0,empty.getByteArray().length);
 
         assertEquals(18,bitset18.getLength());
         assertEquals(3,bitset18.getLengthInBytes());
-        assertEquals(bits24,bitset18.getByteArray());
         assertEquals(9,bitset18.getNumBitsSet());
         assertTrue(bitset18.invariantHolds());
+        assertEquals(bits24,bitset18.getByteArray());
 
         assertEquals(18,bitset18C.getLength());
         assertEquals(3,bitset18C.getLengthInBytes());
-        assertEquals(bits24C,bitset18C.getByteArray());
         assertEquals(9,bitset18C.getNumBitsSet());
         assertTrue(bitset18C.invariantHolds());
+        assertEquals(bits24C,bitset18C.getByteArray());
     }
 
     // Test cases for single arg constructor
@@ -144,33 +144,33 @@
         FormatableBitSet zeroBits = new FormatableBitSet(0);
         assertEquals(0,zeroBits.getLength());
         assertEquals(0,zeroBits.getLengthInBytes());
-        assertEquals(0,zeroBits.getByteArray().length);
         assertEquals(0,zeroBits.getNumBitsSet());
         assertTrue(zeroBits.invariantHolds());
+        assertEquals(0,zeroBits.getByteArray().length);
     }
     public void testIntCtor1() {
         FormatableBitSet oneBit = new FormatableBitSet(1);
         assertEquals(1,oneBit.getLength());
         assertEquals(1,oneBit.getLengthInBytes());
-        assertEquals(1,oneBit.getByteArray().length);
         assertEquals(0,oneBit.getNumBitsSet());
         assertTrue(oneBit.invariantHolds());
+        assertEquals(1,oneBit.getByteArray().length);
     }
     public void testIntCtor8() {
         FormatableBitSet eightBits = new FormatableBitSet(8);
         assertEquals(8,eightBits.getLength());
         assertEquals(1,eightBits.getLengthInBytes());
-        assertEquals(1,eightBits.getByteArray().length);
         assertEquals(0,eightBits.getNumBitsSet());
         assertTrue(eightBits.invariantHolds());
+        assertEquals(1,eightBits.getByteArray().length);
     }
     public void testIntCtor9() {
         FormatableBitSet nineBits = new FormatableBitSet(9);
         assertEquals(9,nineBits.getLength());
         assertEquals(2,nineBits.getLengthInBytes());
-        assertEquals(2,nineBits.getByteArray().length);
         assertEquals(0,nineBits.getNumBitsSet());
         assertTrue(nineBits.invariantHolds());
+        assertEquals(2,nineBits.getByteArray().length);
     }
     public void testIntCtorNeg() {
         try { FormatableBitSet negBits = new FormatableBitSet(-1); fail(); }
@@ -182,8 +182,6 @@
         FormatableBitSet emptyCpy = new FormatableBitSet(empty);
         assertEquals(0,emptyCpy.getLength());
         assertEquals(0,emptyCpy.getLengthInBytes());
-        // FAILURE - the byte array of the copy is not null
-        //assertEquals(null,emptyCpy.getByteArray());
         assertEquals(0,emptyCpy.getNumBitsSet());
         assertTrue(emptyCpy.invariantHolds());
     }
@@ -191,11 +189,11 @@
         FormatableBitSet cpy = new FormatableBitSet(bitset18);
         assertEquals(18,cpy.getLength());
         assertEquals(3,cpy.getLengthInBytes());
-        assertEquals(3,cpy.getByteArray().length);
         assertEquals(9,cpy.getNumBitsSet());
         assertEquals(0,cpy.compare(bitset18));
         assertTrue(cpy.equals(bitset18));
         assertTrue(cpy.invariantHolds());
+        assertEquals(3,cpy.getByteArray().length);
     }
 
     // Test cases for grow(int)
@@ -203,29 +201,109 @@
         empty.grow(18);
         assertEquals(18,empty.getLength());
         assertEquals(3,empty.getLengthInBytes());
-        assertEquals(3,empty.getByteArray().length);
         assertEquals(0,empty.getNumBitsSet());
         assertTrue(bitset18.invariantHolds());
+        assertEquals(3,empty.getByteArray().length);
     }
     public void testGrow() {
         bitset18.grow(25);
         assertEquals(25,bitset18.getLength());
         assertEquals(4,bitset18.getLengthInBytes());
-        assertEquals(4,bitset18.getByteArray().length);
         assertEquals(9,bitset18.getNumBitsSet());
         assertTrue(bitset18.invariantHolds());
+        assertEquals(4,bitset18.getByteArray().length);
     }
-    // OK - should fail?
     public void testGrowSmaller() {
         bitset18.grow(9);
         assertEquals(18,bitset18.getLength());
+        assertEquals(3,bitset18.getLengthInBytes());
+        assertEquals(9,bitset18.getNumBitsSet());
         assertTrue(bitset18.invariantHolds());
+        assertEquals(3,bitset18.getByteArray().length);
     }
-    // OK - should fail?
     public void testGrowNeg() {
-        bitset18.grow(-9);
-        assertEquals(18,bitset18.getLength());
-        assertTrue(bitset18.invariantHolds());
+        try { bitset18.grow(-9); fail(); }
+        catch (IllegalArgumentException iae) {}
+    }
+    public void testGrow0() {
+        empty.grow(0);
+        assertEquals(0,empty.getLength());
+        assertEquals(0,empty.getLengthInBytes());
+        assertEquals(0,empty.getNumBitsSet());
+        assertTrue(empty.invariantHolds());
+        assertEquals(0,empty.getByteArray().length);
+    }
+    public void testGrow1() {
+        empty.grow(1);
+        assertEquals(1,empty.getLength());
+        assertEquals(1,empty.getLengthInBytes());
+        assertEquals(0,empty.getNumBitsSet());
+        assertTrue(empty.invariantHolds());
+        assertEquals(1,empty.getByteArray().length);
+    }
+    public void testGrow2() {
+        empty.grow(2);
+        assertEquals(2,empty.getLength());
+        assertEquals(1,empty.getLengthInBytes());
+        assertEquals(0,empty.getNumBitsSet());
+        assertTrue(empty.invariantHolds());
+        assertEquals(1,empty.getByteArray().length);
+    }
+    public void testGrow3() {
+        empty.grow(3);
+        assertEquals(3,empty.getLength());
+        assertEquals(1,empty.getLengthInBytes());
+        assertEquals(0,empty.getNumBitsSet());
+        assertTrue(empty.invariantHolds());
+        assertEquals(1,empty.getByteArray().length);
+    }
+    public void testGrow4() {
+        empty.grow(4);
+        assertEquals(4,empty.getLength());
+        assertEquals(1,empty.getLengthInBytes());
+        assertEquals(0,empty.getNumBitsSet());
+        assertTrue(empty.invariantHolds());
+        assertEquals(1,empty.getByteArray().length);
+    }
+    public void testGrow5() {
+        empty.grow(5);
+        assertEquals(5,empty.getLength());
+        assertEquals(1,empty.getLengthInBytes());
+        assertEquals(0,empty.getNumBitsSet());
+        assertTrue(empty.invariantHolds());
+        assertEquals(1,empty.getByteArray().length);
+    }
+    public void testGrow6() {
+        empty.grow(6);
+        assertEquals(6,empty.getLength());
+        assertEquals(1,empty.getLengthInBytes());
+        assertEquals(0,empty.getNumBitsSet());
+        assertTrue(empty.invariantHolds());
+        assertEquals(1,empty.getByteArray().length);
+    }
+    public void testGrow7() {
+        empty.grow(7);
+        assertEquals(7,empty.getLength());
+        assertEquals(1,empty.getLengthInBytes());
+        assertEquals(0,empty.getNumBitsSet());
+        assertTrue(empty.invariantHolds());
+        assertEquals(1,empty.getByteArray().length);
+    }
+    public void testGrow8() {
+        empty.grow(8);
+        assertEquals(8,empty.getLength());
+        assertEquals(1,empty.getLengthInBytes());
+        assertEquals(0,empty.getNumBitsSet());
+        assertTrue(empty.invariantHolds());
+        assertEquals(1,empty.getByteArray().length);
+    }
+    public void testGrow9() {
+        empty.grow(9);
+        assertEquals(9,empty.getLength());
+        assertEquals(2,empty.getByteArray().length);
+        assertEquals(0,empty.getNumBitsSet());
+        assertTrue(empty.invariantHolds());
+        assertEquals(2,empty.getLengthInBytes());
     }
 
     // Test cases for shrink(int)
@@ -233,23 +311,21 @@
         empty.shrink(0);
         assertEquals(0,empty.getLength());
         assertEquals(0,empty.getLengthInBytes());
-        assertEquals(0,empty.getByteArray().length);
         assertEquals(0,empty.getNumBitsSet());
         assertTrue(empty.invariantHolds());
+        assertEquals(0,empty.getByteArray().length);
     }
     public void testShrink() {
         bitset18.shrink(9);
         assertEquals(9,bitset18.getLength());
         assertEquals(2,bitset18.getLengthInBytes());
-        assertEquals(2,bitset18.getByteArray().length);
         assertEquals(5,bitset18.getNumBitsSet());
         assertTrue(bitset18.invariantHolds());
+        assertEquals(2,bitset18.getByteArray().length);
     }
-    // OK - should fail?
     public void testShrinkLarger() {
-        bitset18.shrink(25);
-        assertEquals(18,bitset18.getLength());
-        assertTrue(bitset18.invariantHolds());
+        try { bitset18.shrink(25); fail(); }
+        catch (IllegalArgumentException iae) {}
     }
     public void testShrinkNeg() {
         try {
@@ -257,14 +333,93 @@
             fail();
         } catch (IllegalArgumentException iae) {}
     }
-    // Should be allowed?
     public void testShrink0() {
-        try { bitset18.shrink(0); fail(); }
-        catch (ArrayIndexOutOfBoundsException e) {}
-        //      assertEquals(0,bitset18.getLength());
-        //      assertEquals(0,bitset18.getLengthInBytes());
-        //      assertEquals(0,bitset18.getByteArray().length);
-        //      assertEquals(0,bitset18.getNumBitsSet());
+        bitset18.shrink(0);
+        assertEquals(0,bitset18.getLength());
+        assertEquals(0,bitset18.getLengthInBytes());
+        assertTrue(bitset18.invariantHolds());
+        assertEquals(0,bitset18.getNumBitsSet());
+        assertEquals(0,bitset18.getByteArray().length);
+    }
+    public void testShrink1() {
+        bitset18.shrink(1);
+        assertEquals(1,bitset18.getLength());
+        assertEquals(1,bitset18.getLengthInBytes());
+        assertEquals(1,bitset18.getNumBitsSet());
+        assertTrue(bitset18.invariantHolds());
+        assertEquals(1,bitset18.getByteArray().length);
+    }
+    public void testShrink2() {
+        bitset18.shrink(2);
+        assertEquals(2,bitset18.getLength());
+        assertEquals(1,bitset18.getLengthInBytes());
+        assertEquals(2,bitset18.getNumBitsSet());
+        assertTrue(bitset18.invariantHolds());
+        assertEquals(1,bitset18.getByteArray().length);
+    }
+    public void testShrink3() {
+        bitset18.shrink(3);
+        assertEquals(3,bitset18.getLength());
+        assertEquals(1,bitset18.getLengthInBytes());
+        assertEquals(2,bitset18.getNumBitsSet());
+        assertTrue(bitset18.invariantHolds());
+        assertEquals(1,bitset18.getByteArray().length);
+    }
+    public void testShrink4() {
+        bitset18.shrink(4);
+        assertEquals(4,bitset18.getLength());
+        assertEquals(1,bitset18.getLengthInBytes());
+        assertEquals(2,bitset18.getNumBitsSet());
+        assertTrue(bitset18.invariantHolds());
+        assertEquals(1,bitset18.getByteArray().length);
+    }
+    public void testShrink5() {
+        bitset18.shrink(5);
+        assertEquals(5,bitset18.getLength());
+        assertEquals(1,bitset18.getLengthInBytes());
+        assertEquals(3,bitset18.getNumBitsSet());
+        assertTrue(bitset18.invariantHolds());
+        assertEquals(1,bitset18.getByteArray().length);
+    }
+    public void testShrink6() {
+        bitset18.shrink(6);
+        assertEquals(6,bitset18.getLength());
+        assertEquals(1,bitset18.getLengthInBytes());
+        assertEquals(4,bitset18.getNumBitsSet());
+        assertTrue(bitset18.invariantHolds());
+        assertEquals(1,bitset18.getByteArray().length);
+    }
+    public void testShrink7() {
+        bitset18.shrink(7);
+        assertEquals(7,bitset18.getLength());
+        assertEquals(1,bitset18.getLengthInBytes());
+        assertEquals(5,bitset18.getNumBitsSet());
+        assertTrue(bitset18.invariantHolds());
+        assertEquals(1,bitset18.getByteArray().length);
+    }
+    public void testShrink8() {
+        bitset18.shrink(8);
+        assertEquals(8,bitset18.getLength());
+        assertEquals(1,bitset18.getLengthInBytes());
+        assertEquals(5,bitset18.getNumBitsSet());
+        assertTrue(bitset18.invariantHolds());
+        assertEquals(1,bitset18.getByteArray().length);
+    }
+    public void testShrink9() {
+        bitset18.shrink(9);
+        assertEquals(9,bitset18.getLength());
+        assertEquals(2,bitset18.getLengthInBytes());
+        assertEquals(5,bitset18.getNumBitsSet());
+        assertTrue(bitset18.invariantHolds());
+        assertEquals(2,bitset18.getByteArray().length);
+    }
+    public void testShrink10() {
+        bitset18.shrink(10);
+        assertEquals(10,bitset18.getLength());
+        assertEquals(2,bitset18.getLengthInBytes());
+        assertEquals(5,bitset18.getNumBitsSet());
+        assertTrue(bitset18.invariantHolds());
+        assertEquals(2,bitset18.getByteArray().length);
     }
 
     // Test cases for compare(FormatableBitSet)
@@ -478,10 +633,10 @@
         bitset18.xor(empty);
         assertEquals(18,bitset18.getLength());
         assertEquals(3,bitset18.getLengthInBytes());
-        assertEquals(3,bitset18.getByteArray().length);
         assertEquals(9,bitset18.getNumBitsSet());
         assertTrue(cpy.equals(bitset18));
         assertTrue(bitset18.invariantHolds());
+        assertEquals(3,bitset18.getByteArray().length);
     }
     public void testXORWithComplement() {
         bitset18.set(2);
@@ -497,9 +652,9 @@
         bitset18.xor(bitset18C);
         assertEquals(18,bitset18.getLength());
         assertEquals(3,bitset18.getLengthInBytes());
-        assertEquals(3,bitset18.getByteArray().length);
         assertEquals(13,bitset18.getNumBitsSet());
         assertTrue(bitset18.invariantHolds());
+        assertEquals(3,bitset18.getByteArray().length);
     }
     public void testXORWithLarger() {
         bitset18.shrink(9);