com.ibm.wala.util.intset.FixedSizeBitVector Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.ibm.wala.util Show documentation
Show all versions of com.ibm.wala.util Show documentation
T. J. Watson Libraries for Analysis
/*
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*/
package com.ibm.wala.util.intset;
import java.util.Arrays;
public final class FixedSizeBitVector implements Cloneable, java.io.Serializable {
public static final long serialVersionUID = 33181877746462822L;
private static final int LOG_BITS_PER_UNIT = 5;
private static final int MASK = 0xffffffff;
private static final int LOW_MASK = 0x1f;
private int bits[];
private final int nbits;
/** Convert bitIndex to a subscript into the bits[] array. */
private static int subscript(int bitIndex) {
return bitIndex >> LOG_BITS_PER_UNIT;
}
/**
* Creates an empty string with the specified size.
*
* @param nbits the size of the string
*/
public FixedSizeBitVector(int nbits) {
// subscript(nbits) is the length of the array needed to
// hold nbits
if (nbits < 0) {
throw new IllegalArgumentException("illegal nbits: " + nbits);
}
bits = new int[subscript(nbits) + 1];
this.nbits = nbits;
}
/**
* Creates a copy of a Bit String
*
* @param s the string to copy
* @throws IllegalArgumentException if s is null
*/
public FixedSizeBitVector(FixedSizeBitVector s) {
if (s == null) {
throw new IllegalArgumentException("s is null");
}
bits = new int[s.bits.length];
this.nbits = s.nbits;
copyBits(s);
}
/** Sets all bits. */
public void setAll() {
Arrays.fill(bits, MASK);
}
/**
* Sets a bit.
*
* @param bit the bit to be set
*/
public void set(int bit) {
try {
int shiftBits = bit & LOW_MASK;
bits[subscript(bit)] |= (1 << shiftBits);
} catch (ArrayIndexOutOfBoundsException e) {
throw new IllegalArgumentException("invalid bit " + bit, e);
}
}
/** Clears all bits. */
public void clearAll() {
Arrays.fill(bits, 0);
}
/**
* Clears a bit.
*
* @param bit the bit to be cleared
*/
public void clear(int bit) {
try {
int shiftBits = bit & LOW_MASK;
bits[subscript(bit)] &= ~(1 << shiftBits);
} catch (ArrayIndexOutOfBoundsException e) {
throw new IllegalArgumentException("invalid bit: " + bit, e);
}
}
/**
* Gets a bit.
*
* @param bit the bit to be gotten
*/
public boolean get(int bit) {
if (bit < 0) {
throw new IllegalArgumentException("illegal bit: " + bit);
}
int shiftBits = bit & LOW_MASK;
int n = subscript(bit);
try {
return ((bits[n] & (1 << shiftBits)) != 0);
} catch (ArrayIndexOutOfBoundsException e) {
return false;
}
}
/** Logically NOT this bit string */
public void not() {
for (int i = 0; i < bits.length; i++) {
bits[i] ^= MASK;
}
}
/** Return the NOT of a bit string */
public static FixedSizeBitVector not(FixedSizeBitVector s) {
FixedSizeBitVector b = new FixedSizeBitVector(s);
b.not();
return b;
}
/**
* Logically ANDs this bit set with the specified set of bits.
*
* @param set the bit set to be ANDed with
*/
public void and(FixedSizeBitVector set) {
if (set == null) {
throw new IllegalArgumentException("null set");
}
if (this == set) {
return;
}
int n = bits.length;
for (int i = n; i-- > 0; ) {
bits[i] &= set.bits[i];
}
}
/** Return a new bit string as the AND of two others. */
public static FixedSizeBitVector and(FixedSizeBitVector b1, FixedSizeBitVector b2) {
FixedSizeBitVector b = new FixedSizeBitVector(b1);
b.and(b2);
return b;
}
/**
* Logically ORs this bit set with the specified set of bits.
*
* @param set the bit set to be ORed with
* @throws IllegalArgumentException if set == null
*/
public void or(FixedSizeBitVector set) throws IllegalArgumentException {
if (set == null) {
throw new IllegalArgumentException("set == null");
}
if (this == set) { // should help alias analysis
return;
}
int setLength = set.bits.length;
for (int i = setLength; i-- > 0; ) {
bits[i] |= set.bits[i];
}
}
/**
* Return a new FixedSizeBitVector as the OR of two others
*
* @throws IllegalArgumentException if b2 == null
*/
public static FixedSizeBitVector or(FixedSizeBitVector b1, FixedSizeBitVector b2)
throws IllegalArgumentException {
if (b2 == null) {
throw new IllegalArgumentException("b2 == null");
}
FixedSizeBitVector b = new FixedSizeBitVector(b1);
b.or(b2);
return b;
}
/**
* Logically XORs this bit set with the specified set of bits.
*
* @param set the bit set to be XORed with
* @throws IllegalArgumentException if set is null
*/
public void xor(FixedSizeBitVector set) {
if (set == null) {
throw new IllegalArgumentException("set is null");
}
int setLength = set.bits.length;
for (int i = setLength; i-- > 0; ) {
bits[i] ^= set.bits[i];
}
}
/**
* Check if the intersection of the two sets is empty
*
* @param other the set to check intersection with
*/
public boolean intersectionEmpty(FixedSizeBitVector other) {
if (other == null) {
throw new IllegalArgumentException("other is null");
}
int n = bits.length;
for (int i = n; i-- > 0; ) {
if ((bits[i] & other.bits[i]) != 0) return false;
}
return true;
}
/**
* Copies the values of the bits in the specified set into this set.
*
* @param set the bit set to copy the bits from
* @throws IllegalArgumentException if set is null
*/
public void copyBits(FixedSizeBitVector set) {
if (set == null) {
throw new IllegalArgumentException("set is null");
}
int setLength = set.bits.length;
for (int i = setLength; i-- > 0; ) {
bits[i] = set.bits[i];
}
}
/** Gets the hashcode. */
@Override
public int hashCode() {
int h = 1234;
for (int i = bits.length; --i >= 0; ) {
h ^= bits[i] * (i + 1);
}
return h;
}
/** How many bits are set? */
public int populationCount() {
int count = 0;
for (int bit : bits) {
count += Bits.populationCount(bit);
}
return count;
}
/**
* Calculates and returns the set's size in bits. The maximum element in the set is the size - 1st
* element.
*/
public int length() {
return bits.length << LOG_BITS_PER_UNIT;
}
/**
* Compares this object against the specified object.
*
* @param obj the object to compare with
* @return true if the objects are the same; false otherwise.
*/
@Override
public boolean equals(Object obj) {
if ((obj != null) && (obj instanceof FixedSizeBitVector)) {
if (this == obj) { // should help alias analysis
return true;
}
FixedSizeBitVector set = (FixedSizeBitVector) obj;
int n = bits.length;
if (n != set.bits.length) return false;
for (int i = n; i-- > 0; ) {
if (bits[i] != set.bits[i]) {
return false;
}
}
return true;
}
return false;
}
public boolean isZero() {
int setLength = bits.length;
for (int i = setLength; i-- > 0; ) {
if (bits[i] != 0) return false;
}
return true;
}
/** Clones the FixedSizeBitVector. */
@Override
public Object clone() {
final FixedSizeBitVector result;
try {
result = (FixedSizeBitVector) super.clone();
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
result.bits = new int[bits.length];
System.arraycopy(bits, 0, result.bits, 0, result.bits.length);
return result;
}
/** Converts the FixedSizeBitVector to a String. */
@Override
public String toString() {
StringBuilder buffer = new StringBuilder();
boolean needSeparator = false;
buffer.append('{');
// int limit = length();
int limit = this.nbits;
for (int i = 0; i < limit; i++) {
if (get(i)) {
if (needSeparator) {
buffer.append(", ");
} else {
needSeparator = true;
}
buffer.append(i);
}
}
buffer.append('}');
return buffer.toString();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy