Mega Code Archive

 
Categories / Java / Language Basics
 

A list of bits

/*  * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,  * Version 1.0, and under the Eclipse Public License, Version 1.0  * (http://h2database.com/html/license.html).  * Initial Developer: H2 Group  */ //package org.h2.util; /**  * A list of bits.  */ public final class BitField {     private static final int ADDRESS_BITS = 6;     private static final int BITS = 64;     private static final int ADDRESS_MASK = BITS - 1;     private long[] data;     private int maxLength;     public BitField() {         this(64);     }     public BitField(int capacity) {         data = new long[capacity >>> 3];     }     /**      * Get the index of the next bit that is not set.      *      * @param fromIndex where to start searching      * @return the index of the next disabled bit      */     public int nextClearBit(int fromIndex) {         int i = fromIndex >> ADDRESS_BITS;         int max = data.length;         for (; i < max; i++) {             if (data[i] == -1) {                 continue;             }             int j = Math.max(fromIndex, i << ADDRESS_BITS);             for (int end = j + 64; j < end; j++) {                 if (!get(j)) {                     return j;                 }             }         }         return max << ADDRESS_BITS;     }     /**      * Get the bit at the given index.      *      * @param i the index      * @return true if the bit is enabled      */     public boolean get(int i) {         int addr = i >> ADDRESS_BITS;         if (addr >= data.length) {             return false;         }         return (data[addr] & getBitMask(i)) != 0;     }     /**      * Get the next 8 bits at the given index.      * The index must be a multiple of 8.      *      * @param i the index      * @return the next 8 bits      */     public int getByte(int i) {         int addr = i >> ADDRESS_BITS;         if (addr >= data.length) {             return 0;         }         return (int) (data[addr] >>> (i & (7 << 3)) & 255);     }     /**      * Combine the next 8 bits at the given index with OR.      * The index must be a multiple of 8.      *      * @param i the index      * @param x the next 8 bits (0 - 255)      */     public void setByte(int i, int x) {         int addr = i >> ADDRESS_BITS;         checkCapacity(addr);         data[addr] |= ((long) x) << (i & (7 << 3));         if (maxLength < i && x != 0) {             maxLength = i + 7;         }     }     /**      * Set bit at the given index to 'true'.      *      * @param i the index      */     public void set(int i) {         int addr = i >> ADDRESS_BITS;         checkCapacity(addr);         data[addr] |= getBitMask(i);         if (maxLength < i) {             maxLength = i;         }     }     /**      * Set bit at the given index to 'false'.      *      * @param i the index      */     public void clear(int i) {         int addr = i >> ADDRESS_BITS;         if (addr >= data.length) {             return;         }         data[addr] &= ~getBitMask(i);     }     private static long getBitMask(int i) {         return 1L << (i & ADDRESS_MASK);     }     private void checkCapacity(int size) {         if (size >= data.length) {             expandCapacity(size);         }     }     private void expandCapacity(int size) {         while (size >= data.length) {             int newSize = data.length == 0 ? 1 : data.length * 2;             long[] d = new long[newSize];             System.arraycopy(data, 0, d, 0, data.length);             data = d;         }     }     /**      * Enable or disable a number of bits.      *      * @param fromIndex the index of the first bit to enable or disable      * @param toIndex one plus the index of the last bit to enable or disable      * @param value the new value      */     public void set(int fromIndex, int toIndex, boolean value) {         // go backwards so that OutOfMemory happens         // before some bytes are modified         for (int i = toIndex - 1; i >= fromIndex; i--) {             set(i, value);         }         if (value) {             if (toIndex > maxLength) {                 maxLength = toIndex;             }         } else {             if (toIndex >= maxLength) {                 maxLength = fromIndex;             }         }     }     private void set(int i, boolean value) {         if (value) {             set(i);         } else {             clear(i);         }     }     /**      * Get the index of the highest set bit plus one, or 0 if no bits are set.      *      * @return the length of the bit field      */     public int length() {         int m = maxLength >> ADDRESS_BITS;         while (m > 0 && data[m] == 0) {             m--;         }         maxLength = (m << ADDRESS_BITS) +             (64 - Long.numberOfLeadingZeros(data[m]));         return maxLength;     } }