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/01/26 09:15:01 UTC

svn commit: r500177 - 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: Fri Jan 26 00:15:00 2007
New Revision: 500177

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

Use unsigned int operations to calculate positions.
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=500177&r1=500176&r2=500177
==============================================================================
--- 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 Fri Jan 26 00:15:00 2007
@@ -70,11 +70,11 @@
 	// value is never null. An empty bitset is represented by a
 	// zero-length array.
 	private byte[]	value;
-	private	short	bitsInLastByte;
+	private	byte	bitsInLastByte;
 
 	private transient int	lengthAsBits;
 
-	private void checkPosition(int p) {
+	private final void checkPosition(int p) {
 		if (p < 0 || lengthAsBits <= p) {
 			throw new
 				IllegalArgumentException("Bit position "+p+
@@ -82,6 +82,18 @@
 		}
 	}
 
+	// Division, multiplication and remainder calcuation of a positive
+	// number with a power of two can be done using shifts and bit
+	// masking. The compiler attempts this optimization but since Java
+	// does not have unsigned ints it will also have to create code to
+	// handle negative values. In this class the argument is
+	// frequently an array index or array length, which is known not
+	// to be negative. These utility methods allow us to perform
+	// "unsigned" operations with 8. Hopefully the extra function call
+	// will be inlined by the compiler.
+	private static int udiv8(int i) { return (i>>3); }
+	private static byte umod8(int i) { return (byte)(i&0x7); }
+
 	/**
 	 * Niladic Constructor
 	 */
@@ -95,6 +107,11 @@
 	 */
 	public FormatableBitSet(int numBits)
 	{
+		if (numBits < 0) {
+			throw new
+			IllegalArgumentException("Bit set size "+ numBits +
+									 " is not allowed");
+		}
 		initializeBits(numBits);
 	}
 
@@ -324,6 +341,11 @@
 	 */
 	public FormatableBitSet shrink(int n)
 	{
+		if (n < 0) {
+			throw new
+			IllegalArgumentException("Bit set size "+ n +
+									 " is not allowed");
+		}
 		int		numBytes;
 		int		lastByteNum;
 
@@ -494,13 +516,12 @@
 	public final boolean isSet(int position)
 	{
 		checkPosition(position);
-
-		int bytepos = position / 8;
-		int bitpos = 7 - (position % 8);
-
-		return ((value[bytepos] & (1 << bitpos)) != 0);
+		final int byteIndex = udiv8(position);
+		final byte bitIndex = umod8(position);
+		return ((value[byteIndex] & (0x80>>bitIndex)) != 0);
 	}
 
+
 	/**
 	 * Bit get -- alias for isSet()
 	 *
@@ -521,11 +542,9 @@
 	public void set(int position)
 	{
 		checkPosition(position);
-
-		int bytepos = position / 8;
-		int bitpos = 7 - (position % 8);
-
-		value[bytepos] |= (1 << bitpos);
+		final int byteIndex = udiv8(position);
+		final byte bitIndex = umod8(position);
+		value[byteIndex] |= (0x80>>bitIndex);
 	}
 
 	/**
@@ -537,11 +556,9 @@
 	public void clear(int position)
 	{
 		checkPosition(position);
-
-		int bytepos = position / 8;
-		int bitpos = 7 - (position % 8);
-
-		value[bytepos] &= ~(1 << bitpos);
+		final int byteIndex = udiv8(position);
+		final byte bitIndex = umod8(position);
+		value[byteIndex] &= ~(0x80>>bitIndex);
 	}
 
 	/**
@@ -575,13 +592,12 @@
 	*
 	* @return	the number of bits
 	*/
-	private static short
+	private static byte
 	numBitsInLastByte(int bits)
 	{
-		int modulo = bits % 8;
-		return (short)((modulo == 0) ?
-				((bits == 0) ? 0 : 8) :
-				modulo);
+		if (bits == 0) return 0;
+		byte lastbits = umod8(bits);
+		return (lastbits != 0 ? lastbits : 8);
 	}
 
 	/**

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=500177&r1=500176&r2=500177
==============================================================================
--- 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 Fri Jan 26 00:15:00 2007
@@ -152,13 +152,8 @@
         assertTrue(nineBits.invariantHolds());
     }
     public void testIntCtorNeg() {
-        // Should throw an exception?
-        FormatableBitSet negBits = new FormatableBitSet(-1);
-        assertEquals(-1,negBits.getLength());
-        assertEquals(0,negBits.getLengthInBytes());
-        assertEquals(0,negBits.getByteArray().length);
-        assertEquals(0,negBits.getNumBitsSet());
-        assertTrue(negBits.invariantHolds());
+        try { FormatableBitSet negBits = new FormatableBitSet(-1); fail(); }
+        catch(IllegalArgumentException iae) {}
     }
 
     // Test cases for the copy constructor
@@ -239,7 +234,7 @@
         try {
             bitset18.shrink(-9);
             fail();
-        } catch (ArrayIndexOutOfBoundsException e) {}
+        } catch (IllegalArgumentException iae) {}
     }
     // Should be allowed?
     public void testShrink0() {