FileDocCategorySizeDatePackage
HugeEnumSet.javaAPI DocAndroid 1.5 API11279Wed May 06 22:41:04 BST 2009java.util

HugeEnumSet

public final class HugeEnumSet extends EnumSet
This is a concrete subclass of EnumSet designed specifically for enum type with more than 64 elements.

Fields Summary
private final E[]
enums
private long[]
bits
private int
size
private static final int
BIT_IN_LONG
private int
bitsIndex
private int
elementInBits
private long
oldBits
Constructors Summary
HugeEnumSet(Class elementType, E[] enums)
Constructs an instance.

param
elementType non-null; type of the elements
param
enums non-null; prepopulated array of constants in ordinal order

    
    // BEGIN android-changed
                              
        
        super(elementType);
        this.enums = enums;
        bits = new long[(enums.length + BIT_IN_LONG - 1) / BIT_IN_LONG];
        Arrays.fill(bits, 0);
    
Methods Summary
public booleanadd(E element)

        if (!isValidType(element.getDeclaringClass())) {
            throw new ClassCastException();
        }
        calculateElementIndex(element);

        bits[bitsIndex] |= (1l << elementInBits);
        if (oldBits == bits[bitsIndex]) {
            return false;
        }
        size++;
        return true;
    
public booleanaddAll(java.util.Collection collection)

        if (0 == collection.size() || this == collection) {
            return false;
        }
        if (collection instanceof EnumSet) {
            EnumSet set = (EnumSet) collection;
            if (!isValidType(set.elementClass)) {
                throw new ClassCastException();
            }
            HugeEnumSet hugeSet = (HugeEnumSet) set;
            boolean addSuccessful = false;
            for (int i = 0; i < bits.length; i++) {
                oldBits = bits[i];
                bits[i] |= hugeSet.bits[i];
                if (oldBits != bits[i]) {
                    addSuccessful = true;
                    size = size - Long.bitCount(oldBits)
                            + Long.bitCount(bits[i]);
                }
            }
            return addSuccessful;
        }
        return super.addAll(collection);
    
private voidcalculateElementIndex(E element)

        int elementOrdinal = element.ordinal();
        bitsIndex = elementOrdinal / BIT_IN_LONG;
        elementInBits = elementOrdinal % BIT_IN_LONG;
        oldBits = bits[bitsIndex];
    
public voidclear()

        Arrays.fill(bits, 0);
        size = 0;
    
public java.util.HugeEnumSetclone()

        Object set = super.clone();
        if (null != set) {
            ((HugeEnumSet<E>) set).bits = bits.clone();
            return (HugeEnumSet<E>) set;
        }
        return null;
    
protected voidcomplement()

        if (0 != enums.length) {
            bitsIndex = enums.length / BIT_IN_LONG;

            size = 0;
            int bitCount = 0;
            for (int i = 0; i <= bitsIndex; i++) {
                bits[i] = ~bits[i];
                bitCount = Long.bitCount(bits[i]);
                size += bitCount;
            }
            bits[bitsIndex] &= (-1l >>> (BIT_IN_LONG - enums.length
                    % BIT_IN_LONG));
            size -= bitCount;
            bitCount = Long.bitCount(bits[bitsIndex]);
            size += bitCount;
        }
    
public booleancontains(java.lang.Object object)

        if (null == object) {
            return false;
        }
        if (!isValidType(object.getClass())) {
            return false;
        }
        calculateElementIndex((E)object);
        return (bits[bitsIndex] & (1l << elementInBits)) != 0;
    
public booleancontainsAll(java.util.Collection collection)

        if (collection.size() == 0) {
            return true;
        }
        if (collection instanceof HugeEnumSet) {
            HugeEnumSet set = (HugeEnumSet) collection;
            if(isValidType(set.elementClass )) {
                for(int i = 0; i < bits.length; i++) {
                    if((bits[i] & set.bits[i]) != set.bits[i]){
                        return false;
                    }
                    
                }
                return true;
            }
        }
        return !(collection instanceof EnumSet) && super.containsAll(collection);
    
public booleanequals(java.lang.Object object)

        if (null == object) {
            return false;
        }
        if (!isValidType(object.getClass())) {
            return super.equals(object);
        }
        return Arrays.equals(bits, ((HugeEnumSet) object).bits);
    
public java.util.Iteratoriterator()

        return new HugeEnumSetIterator();
    
public booleanremove(java.lang.Object object)

        if (!contains(object)) {
            return false;
        }
        bits[bitsIndex] -= (1l << elementInBits);
        size--;
        return true;
    
public booleanremoveAll(java.util.Collection collection)

        if (0 == collection.size()) {
            return false;
        }
        
        if (collection instanceof EnumSet) {
            EnumSet<E> set = (EnumSet<E>) collection;
            if (!isValidType(set.elementClass)) {
                return false;
            }
            boolean removeSuccessful = false;
            long mask = 0;
            for (int i = 0; i < bits.length; i++) {
                oldBits = bits[i];
                mask = bits[i] & ((HugeEnumSet<E>) set).bits[i];
                if (mask != 0) {
                    bits[i] -= mask;
                    size = (size - Long.bitCount(oldBits) + Long
                            .bitCount(bits[i]));
                    removeSuccessful = true;
                }
            }
            return removeSuccessful;
        }
        return super.removeAll(collection);
    
public booleanretainAll(java.util.Collection collection)

        if (collection instanceof EnumSet) {
            EnumSet<E> set = (EnumSet<E>) collection;
            if (!isValidType(set.elementClass)) {
                clear();
                return true;
            }

            boolean retainSuccessful = false;
            oldBits = 0;
            for (int i = 0; i < bits.length; i++) {
                oldBits = bits[i];
                bits[i] &= ((HugeEnumSet<E>) set).bits[i];
                if (oldBits != bits[i]) {
                    size = size - Long.bitCount(oldBits)
                            + Long.bitCount(bits[i]);
                    retainSuccessful = true;
                }
            }
            return retainSuccessful;
        }
        return super.retainAll(collection);
    
voidsetRange(E start, E end)

        calculateElementIndex(start);
        int startBitsIndex = bitsIndex;
        int startElementInBits = elementInBits;
        calculateElementIndex(end);
        int endBitsIndex = bitsIndex;
        int endElementInBits = elementInBits;
        long range = 0;
        if (startBitsIndex == endBitsIndex) {
            range = (-1l >>> (BIT_IN_LONG -(endElementInBits - startElementInBits + 1))) << startElementInBits;
            size -= Long.bitCount(bits[bitsIndex]);
            bits[bitsIndex] |= range;
            size += Long.bitCount(bits[bitsIndex]);
        } else {
            range = (-1l >>> startElementInBits) << startElementInBits;
            size -= Long.bitCount(bits[startBitsIndex]);
            bits[startBitsIndex] |= range;
            size += Long.bitCount(bits[startBitsIndex]);

            // endElementInBits + 1 is the number of consecutive ones.
            // 63 - endElementInBits is the following zeros of the right most one.
            range = -1l >>> (BIT_IN_LONG - (endElementInBits + 1)) << (63 - endElementInBits);
            size -= Long.bitCount(bits[endBitsIndex]);
            bits[endBitsIndex] |= range;
            size += Long.bitCount(bits[endBitsIndex]);
            for(int i = (startBitsIndex + 1); i <= (endBitsIndex - 1); i++) {
                size -= Long.bitCount(bits[i]);
                bits[i] = -1l;
                size += Long.bitCount(bits[i]);
            }
        }
    
public intsize()

        return size;