aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/com/jogamp/common/util
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2015-08-02 01:12:21 +0200
committerSven Gothel <[email protected]>2015-08-02 01:12:21 +0200
commit047e9adaf2a5f51f7acfa194a744c99b6bfadaea (patch)
treec701ab77a9387cdec1a61c51b9ed289d5aa755e2 /src/java/com/jogamp/common/util
parent805800e9b02acf54a6cc5a04ce94c9b465c42f43 (diff)
Bitfield: Refine API method names, add clearField(boolean), fix put32(..) and bitCount(), add unit test (passed)
Diffstat (limited to 'src/java/com/jogamp/common/util')
-rw-r--r--src/java/com/jogamp/common/util/Bitfield.java80
-rw-r--r--src/java/com/jogamp/common/util/IntBitfield.java6
2 files changed, 62 insertions, 24 deletions
diff --git a/src/java/com/jogamp/common/util/Bitfield.java b/src/java/com/jogamp/common/util/Bitfield.java
index f7eaeb0..d7ada5a 100644
--- a/src/java/com/jogamp/common/util/Bitfield.java
+++ b/src/java/com/jogamp/common/util/Bitfield.java
@@ -34,26 +34,58 @@ import jogamp.common.util.SyncedBitfield;
* @since 2.3.2
*/
public interface Bitfield {
+ /** Maximum 32 bit Unsigned Integer Value: {@code 0xffffffff} == {@value}. */
+ public static final int UNSIGNED_INT_MAX_VALUE = 0xffffffff;
+
/**
* Bit operation utilities (static).
*/
public static class Util {
/**
+ * Returns the 32 bit mask of n-bits, i.e. n low order 1’s.
+ * <p>
+ * Implementation handles n == 32.
+ * </p>
+ * @throws IndexOutOfBoundsException if {@code b} is out of bounds, i.e. &gt; 32
+ */
+ public static int getBitMask(final int n) {
+ if( 32 > n ) {
+ return ( 1 << n ) - 1;
+ } else if ( 32 == n ) {
+ return UNSIGNED_INT_MAX_VALUE;
+ } else {
+ throw new IndexOutOfBoundsException("n <= 32 expected, is "+n);
+ }
+ }
+
+ /**
* Returns the number of set bits within given 32bit integer in O(1)
- * using <i>HAKEM Bit Count</i>:
+ * using a <i>HAKEM 169 Bit Count</i> inspired implementation:
* <pre>
* http://www.inwap.com/pdp10/hbaker/hakmem/hakmem.html
* http://home.pipeline.com/~hbaker1/hakmem/hacks.html#item169
* http://tekpool.wordpress.com/category/bit-count/
+ * http://www.hackersdelight.org/
* </pre>
*/
- public static final int getBitCount(final int n) {
+ public static final int bitCount(int n) {
// Note: Original used 'unsigned int',
// hence we use the unsigned right-shift '>>>'
- int c = n;
- c -= (n >>> 1) & 033333333333;
- c -= (n >>> 2) & 011111111111;
- return ( (c + ( c >>> 3 ) ) & 030707070707 ) % 63;
+ /**
+ * Original does not work due to lack of 'unsigned' right-shift and modulo,
+ * we need 2-complementary solution, i.e. 'signed'.
+ int c = n;
+ c -= (n >>> 1) & 033333333333;
+ c -= (n >>> 2) & 011111111111;
+ return ( (c + ( c >>> 3 ) ) & 030707070707 ) & 0x3f; // % 63
+ */
+ // Hackers Delight, Figure 5-2, pop1 of pop.c.txt
+ n = n - ((n >>> 1) & 0x55555555);
+ n = (n & 0x33333333) + ((n >>> 2) & 0x33333333);
+ n = (n + (n >>> 4)) & 0x0f0f0f0f;
+ n = n + (n >>> 8);
+ n = n + (n >>> 16);
+ return n & 0x3f;
}
}
/**
@@ -84,12 +116,18 @@ public interface Bitfield {
/**
* Returns the storage size in bit units, e.g. 32 bit for implementations using one {@code int} field.
*/
- int getStorageBitSize();
+ int size();
+
+
+ /**
+ * Set all bits of this bitfield to the given value {@code bit}.
+ */
+ void clearField(final boolean bit);
/**
* Returns {@code length} bits from this storage,
* starting with the lowest bit from the storage position {@code lowBitnum}.
- * @param lowBitnum storage bit position of the lowest bit, restricted to [0..{@link #getStorageBitSize()}-{@code length}].
+ * @param lowBitnum storage bit position of the lowest bit, restricted to [0..{@link #size()}-{@code length}].
* @param length number of bits to read, constrained to [0..32].
* @throws IndexOutOfBoundsException if {@code rightBitnum} is out of bounds
* @see #put32(int, int, int)
@@ -99,8 +137,8 @@ public interface Bitfield {
/**
* Puts {@code length} bits of given {@code data} into this storage,
* starting w/ the lowest bit to the storage position {@code lowBitnum}.
- * @param lowBitnum storage bit position of the lowest bit, restricted to [0..{@link #getStorageBitSize()}-{@code length}].
- * @param length number of bits to read, constrained to [0..32].
+ * @param lowBitnum storage bit position of the lowest bit, restricted to [0..{@link #size()}-{@code length}].
+ * @param length number of bits to write, constrained to [0..32].
* @param data the actual bits to be put into this storage
* @throws IndexOutOfBoundsException if {@code rightBitnum} is out of bounds
* @see #get32(int, int)
@@ -114,8 +152,8 @@ public interface Bitfield {
* Implementation shall operate as if invoking {@link #get32(int, int)}
* and then {@link #put32(int, int, int)} sequentially.
* </p>
- * @param srcLowBitnum source bit number, restricted to [0..{@link #getStorageBitSize()}-1].
- * @param dstLowBitnum destination bit number, restricted to [0..{@link #getStorageBitSize()}-1].
+ * @param srcLowBitnum source bit number, restricted to [0..{@link #size()}-1].
+ * @param dstLowBitnum destination bit number, restricted to [0..{@link #size()}-1].
* @throws IndexOutOfBoundsException if {@code bitnum} is out of bounds
* @see #get32(int, int)
* @see #put32(int, int, int)
@@ -124,7 +162,7 @@ public interface Bitfield {
/**
* Return <code>true</code> if the bit at position <code>bitnum</code> is set, otherwise <code>false</code>.
- * @param bitnum bit number, restricted to [0..{@link #getStorageBitSize()}-1].
+ * @param bitnum bit number, restricted to [0..{@link #size()}-1].
* @throws IndexOutOfBoundsException if {@code bitnum} is out of bounds
*/
boolean get(final int bitnum) throws IndexOutOfBoundsException;
@@ -132,21 +170,21 @@ public interface Bitfield {
/**
* Set or clear the bit at position <code>bitnum</code> according to <code>bit</code>
* and return the previous value.
- * @param bitnum bit number, restricted to [0..{@link #getStorageBitSize()}-1].
+ * @param bitnum bit number, restricted to [0..{@link #size()}-1].
* @throws IndexOutOfBoundsException if {@code bitnum} is out of bounds
*/
void put(final int bitnum, final boolean bit) throws IndexOutOfBoundsException;
/**
* Set the bit at position <code>bitnum</code> according to <code>bit</code>.
- * @param bitnum bit number, restricted to [0..{@link #getStorageBitSize()}-1].
+ * @param bitnum bit number, restricted to [0..{@link #size()}-1].
* @throws IndexOutOfBoundsException if {@code bitnum} is out of bounds
*/
void set(final int bitnum) throws IndexOutOfBoundsException;
/**
* Clear the bit at position <code>bitnum</code> according to <code>bit</code>.
- * @param bitnum bit number, restricted to [0..{@link #getStorageBitSize()}-1].
+ * @param bitnum bit number, restricted to [0..{@link #size()}-1].
* @throws IndexOutOfBoundsException if {@code bitnum} is out of bounds
*/
void clear(final int bitnum) throws IndexOutOfBoundsException;
@@ -154,17 +192,17 @@ public interface Bitfield {
/**
* Copies the bit at position {@code srcBitnum} to position {@code dstBitnum}
* and returning <code>true</code> if the bit is set, otherwise <code>false</code>.
- * @param srcBitnum source bit number, restricted to [0..{@link #getStorageBitSize()}-1].
- * @param dstBitnum destination bit number, restricted to [0..{@link #getStorageBitSize()}-1].
+ * @param srcBitnum source bit number, restricted to [0..{@link #size()}-1].
+ * @param dstBitnum destination bit number, restricted to [0..{@link #size()}-1].
* @throws IndexOutOfBoundsException if {@code bitnum} is out of bounds
*/
boolean copy(final int srcBitnum, final int dstBitnum) throws IndexOutOfBoundsException;
/**
- * Returns the number of set bits within this bitfield.
+ * Returns the number of one bits within this bitfield.
* <p>
- * Utilizes {#link {@link Bitfield.Util#getBitCount(int)}}.
+ * Utilizes {#link {@link Bitfield.Util#bitCount(int)}}.
* </p>
*/
- int getBitCount();
+ int bitCount();
}
diff --git a/src/java/com/jogamp/common/util/IntBitfield.java b/src/java/com/jogamp/common/util/IntBitfield.java
index 3ef5bb7..e7a9d70 100644
--- a/src/java/com/jogamp/common/util/IntBitfield.java
+++ b/src/java/com/jogamp/common/util/IntBitfield.java
@@ -140,10 +140,10 @@ public class IntBitfield {
return prev;
}
/**
- * @deprecated Use {@link Bitfield.Util#getBitCount(int)}.
+ * @deprecated Use {@link Bitfield.Util#bitCount(int)}.
*/
public static final int getBitCount(final int n) {
- return Bitfield.Util.getBitCount(n);
+ return Bitfield.Util.bitCount(n);
}
/**
@@ -155,7 +155,7 @@ public class IntBitfield {
public long getBitCount() {
long c = 0;
for(int i = storage.length-1; i>=0; i--) {
- c += Bitfield.Util.getBitCount(storage[i]);
+ c += Bitfield.Util.bitCount(storage[i]);
}
return c;
}