1 /** 2 * Copyright 2012 JogAmp Community. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without modification, are 5 * permitted provided that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain the above copyright notice, this list of 8 * conditions and the following disclaimer. 9 * 10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 * of conditions and the following disclaimer in the documentation and/or other materials 12 * provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED 15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * 24 * The views and conclusions contained in the software and documentation are those of the 25 * authors and should not be interpreted as representing official policies, either expressed 26 * or implied, of JogAmp Community. 27 */ 28 package com.jogamp.common.util; 29 30 /** 31 * @deprecated Use {@link Bitfield} implementations via {@link Bitfield.Factory#create(int)}. 32 * <p> 33 * Simple bitfield holder class using an int[] storage. 34 * </p> 35 * <p> 36 * IntBitfield allows convenient access of a wide field of transient bits using efficient storage in O(1). 37 * </p> 38 * <p> 39 * It can be used e.g. to map key-codes to pressed-state etc. 40 * </p> 41 */ 42 public class IntBitfield { 43 /** Unit size in bits, here 32 bits for one int unit. */ 44 public static final int UNIT_SIZE = 32; 45 46 private static final long UNIT_SHIFT_L = 5L; 47 private static final int UNIT_SHIFT_I = 5; 48 49 private final int[] storage; 50 private final long bitsCountL; 51 private final int bitsCountI; 52 53 /** 54 * @param bitCount 55 */ IntBitfield(final long bitCount)56 public IntBitfield(final long bitCount) { 57 final int units = (int) Math.max(1L, ( bitCount + 31L ) >>> UNIT_SHIFT_L); 58 this.storage = new int[units]; 59 this.bitsCountL = (long)units << UNIT_SHIFT_L ; 60 this.bitsCountI = bitsCountL > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)bitsCountL; 61 } 62 63 /** 64 * @param bitCount 65 */ IntBitfield(final int bitCount)66 public IntBitfield(final int bitCount) { 67 final int units = Math.max(1, ( bitCount + 31 ) >>> UNIT_SHIFT_I); 68 this.storage = new int[units]; 69 this.bitsCountI = units << UNIT_SHIFT_I; 70 this.bitsCountL = bitsCountI; 71 } 72 check(final long bitnum)73 private final void check(final long bitnum) { 74 if( 0 > bitnum || bitnum >= bitsCountL ) { 75 throw new ArrayIndexOutOfBoundsException("Bitnum should be within [0.."+(bitsCountL-1)+"], but is "+bitnum); 76 } 77 } check(final int bitnum)78 private final void check(final int bitnum) { 79 if( 0 > bitnum || bitnum >= bitsCountI ) { 80 throw new ArrayIndexOutOfBoundsException("Bitnum should be within [0.."+(bitsCountI-1)+"], but is "+bitnum); 81 } 82 } 83 84 /** Return the capacity of this bit field, i.e. the number of bits stored int this field. */ capacity()85 public final long capacity() { return bitsCountL; } 86 87 /** Return <code>true</code> if the bit at position <code>bitnum</code> is set, otherwise <code>false</code>. */ get(final long bitnum)88 public final boolean get(final long bitnum) { 89 check(bitnum); 90 final int u = (int) ( bitnum >>> UNIT_SHIFT_L ); 91 final int b = (int) ( bitnum - ( (long)u << UNIT_SHIFT_L ) ); 92 return 0 != ( storage[u] & ( 1 << b ) ) ; 93 } 94 95 /** Return <code>true</code> if the bit at position <code>bitnum</code> is set, otherwise <code>false</code>. */ get(final int bitnum)96 public final boolean get(final int bitnum) { 97 check(bitnum); 98 final int u = bitnum >>> UNIT_SHIFT_I; 99 final int b = bitnum - ( u << UNIT_SHIFT_I ); 100 return 0 != ( storage[u] & ( 1 << b ) ) ; 101 } 102 103 /** 104 * Set or clear the bit at position <code>bitnum</code> according to <code>bit</code> 105 * and return the previous value. 106 */ put(final long bitnum, final boolean bit)107 public final boolean put(final long bitnum, final boolean bit) { 108 check(bitnum); 109 final int u = (int) ( bitnum >>> UNIT_SHIFT_L ); 110 final int b = (int) ( bitnum - ( (long)u << UNIT_SHIFT_L ) ); 111 final int m = 1 << b; 112 final boolean prev = 0 != ( storage[u] & m ) ; 113 if( prev != bit ) { 114 if( bit ) { 115 storage[u] |= m; 116 } else { 117 storage[u] &= ~m; 118 } 119 } 120 return prev; 121 } 122 123 /** 124 * Set or clear the bit at position <code>bitnum</code> according to <code>bit</code> 125 * and return the previous value. 126 */ put(final int bitnum, final boolean bit)127 public final boolean put(final int bitnum, final boolean bit) { 128 check(bitnum); 129 final int u = bitnum >>> UNIT_SHIFT_I; 130 final int b = bitnum - ( u << UNIT_SHIFT_I ); 131 final int m = 1 << b; 132 final boolean prev = 0 != ( storage[u] & m ) ; 133 if( prev != bit ) { 134 if( bit ) { 135 storage[u] |= m; 136 } else { 137 storage[u] &= ~m; 138 } 139 } 140 return prev; 141 } 142 /** 143 * @deprecated Use {@link Bitfield.Util#bitCount(int)}. 144 */ getBitCount(final int n)145 public static final int getBitCount(final int n) { 146 return Bitfield.Util.bitCount(n); 147 } 148 149 /** 150 * Returns the number of set bits within this bitfield. 151 * <p> 152 * Utilizes {#link {@link #getBitCount(int)}}. 153 * </p> 154 */ getBitCount()155 public long getBitCount() { 156 long c = 0; 157 for(int i = storage.length-1; i>=0; i--) { 158 c += Bitfield.Util.bitCount(storage[i]); 159 } 160 return c; 161 } 162 } 163