/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hdfs.util;
/**
* LightWeightBitSet is a class providing static methods for creating a bit set
* representing membership of objects in a set.
*/
public class LightWeightBitSet {
public static long[] emptySet = new long[0];
private static final int LONG_MASK = 0x3f;
private static final int LONG_SHIFT = 6;
/**
* Get an array of longs that will fit membership information about the given
* number of elements
*
* @param size - the number of elements to fit into the set
* @return an array with sufficient number of longs
*/
public static long[] getBitSet(int size) {
if (size <= 0) {
return emptySet;
}
return new long[getBitArraySize(size)];
}
/**
* Get maximum number of elements that can be represented by the given array
* of longs.
*/
public static int getMaxCapacity(long[] bits) {
if (bits == null)
return 0;
return bits.length << LONG_SHIFT;
}
/**
* Set the bit for the given position to true.
*
* @param bits - bitset
* @param pos - position to be set to true
*/
public static void set(long[] bits, int pos) {
int offset = pos >> LONG_SHIFT;
if (offset >= bits.length)
throw new IndexOutOfBoundsException();
bits[offset] |= 1L << pos;
}
/**
* Set the bit for the given position to false.
*
* @param bits - bitset
* @param pos - position to be set to false
*/
public static void clear(long[] bits, int pos) {
int offset = pos >> LONG_SHIFT;
if (offset >= bits.length)
throw new IndexOutOfBoundsException();
bits[offset] &= ~(1L << pos);
}
/**
* Gets the bit for the given position.
*
* @param bits
* - bitset
* @param pos
* - position to retrieve.
*/
public static boolean get(long[] bits, int pos) {
int offset = pos >> LONG_SHIFT;
if (offset >= bits.length)
return false;
return (bits[offset] & (1L << pos)) != 0;
}
/**
* Checks the number of bits set to 1.
*
* @param bits - bitset
* @return the number of bits set to 1
*/
public static int cardinality(long[] bits) {
int card = 0;
for (int i = bits.length - 1; i >= 0; i--) {
long a = bits[i];
if (a == 0)
continue;
if (a == -1) {
card += 64;
continue;
}
// Successively collapse alternating bit groups into a sum.
a = ((a >> 1) & 0x5555555555555555L) + (a & 0x5555555555555555L);
a = ((a >> 2) & 0x3333333333333333L) + (a & 0x3333333333333333L);
int b = (int) ((a >>> 32) + a);
b = ((b >> 4) & 0x0f0f0f0f) + (b & 0x0f0f0f0f);
b = ((b >> 8) & 0x00ff00ff) + (b & 0x00ff00ff);
card += ((b >> 16) & 0x0000ffff) + (b & 0x0000ffff);
}
return card;
}
/**
* Get the number of longs to store the membership information about spaceSize
* elements.
*
* @param size - number of elements to be represented
* @return the needed number of longs
*/
public static int getBitArraySize(int size) {
int bitMapSize = size >>> LONG_SHIFT;
if ((size & LONG_MASK) != 0)
bitMapSize++;
return bitMapSize;
}
}