1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* Licensed to the Apache Software Foundation (ASF) under one or more 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 7f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util; 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 2155392539fea537abfb6581b474918f9d611fba27Jesse Wilson * A concrete EnumSet for enums with more than 64 elements. 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project@SuppressWarnings("serial") 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectfinal class HugeEnumSet<E extends Enum<E>> extends EnumSet<E> { 25f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 2655392539fea537abfb6581b474918f9d611fba27Jesse Wilson private static final int BIT_IN_LONG = 64; 2755392539fea537abfb6581b474918f9d611fba27Jesse Wilson 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final private E[] enums; 29f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private long[] bits; 31f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int size; 33f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs an instance. 36f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param elementType non-null; type of the elements 38fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes * @param enums non-null; pre-populated array of constants in ordinal 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * order 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HugeEnumSet(Class<E> elementType, E[] enums) { 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(elementType); 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.enums = enums; 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bits = new long[(enums.length + BIT_IN_LONG - 1) / BIT_IN_LONG]; 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 46f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private class HugeEnumSetIterator implements Iterator<E> { 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 4955392539fea537abfb6581b474918f9d611fba27Jesse Wilson /** 5055392539fea537abfb6581b474918f9d611fba27Jesse Wilson * The bits yet to be returned for the long in bits[index]. As values from the current index 5155392539fea537abfb6581b474918f9d611fba27Jesse Wilson * are returned, their bits are zeroed out. When this reaches zero, the index must be 5255392539fea537abfb6581b474918f9d611fba27Jesse Wilson * incremented. 5355392539fea537abfb6581b474918f9d611fba27Jesse Wilson */ 5455392539fea537abfb6581b474918f9d611fba27Jesse Wilson private long currentBits = bits[0]; 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 5655392539fea537abfb6581b474918f9d611fba27Jesse Wilson /** 5755392539fea537abfb6581b474918f9d611fba27Jesse Wilson * The index into HugeEnumSet.bits of the next value to return. 5855392539fea537abfb6581b474918f9d611fba27Jesse Wilson */ 5955392539fea537abfb6581b474918f9d611fba27Jesse Wilson private int index; 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 6155392539fea537abfb6581b474918f9d611fba27Jesse Wilson /** 6255392539fea537abfb6581b474918f9d611fba27Jesse Wilson * The single bit of the next value to return. 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 6455392539fea537abfb6581b474918f9d611fba27Jesse Wilson private long mask; 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 6655392539fea537abfb6581b474918f9d611fba27Jesse Wilson /** 6755392539fea537abfb6581b474918f9d611fba27Jesse Wilson * The candidate for removal. If null, no value may be removed. 6855392539fea537abfb6581b474918f9d611fba27Jesse Wilson */ 6955392539fea537abfb6581b474918f9d611fba27Jesse Wilson private E last; 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private HugeEnumSetIterator() { 7255392539fea537abfb6581b474918f9d611fba27Jesse Wilson computeNextElement(); 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 7555392539fea537abfb6581b474918f9d611fba27Jesse Wilson /** 7655392539fea537abfb6581b474918f9d611fba27Jesse Wilson * Assigns mask and index to the next available value, cycling currentBits as necessary. 7755392539fea537abfb6581b474918f9d611fba27Jesse Wilson */ 7855392539fea537abfb6581b474918f9d611fba27Jesse Wilson void computeNextElement() { 7955392539fea537abfb6581b474918f9d611fba27Jesse Wilson while (true) { 8055392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (currentBits != 0) { 8155392539fea537abfb6581b474918f9d611fba27Jesse Wilson mask = currentBits & -currentBits; // the lowest 1 bit in currentBits 8255392539fea537abfb6581b474918f9d611fba27Jesse Wilson return; 8355392539fea537abfb6581b474918f9d611fba27Jesse Wilson } else if (++index < bits.length) { 8455392539fea537abfb6581b474918f9d611fba27Jesse Wilson currentBits = bits[index]; 8555392539fea537abfb6581b474918f9d611fba27Jesse Wilson } else { 8655392539fea537abfb6581b474918f9d611fba27Jesse Wilson mask = 0; 8755392539fea537abfb6581b474918f9d611fba27Jesse Wilson return; 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean hasNext() { 9355392539fea537abfb6581b474918f9d611fba27Jesse Wilson return mask != 0; 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public E next() { 9755392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (mask == 0) { 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NoSuchElementException(); 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 10055392539fea537abfb6581b474918f9d611fba27Jesse Wilson 10155392539fea537abfb6581b474918f9d611fba27Jesse Wilson int ordinal = Long.numberOfTrailingZeros(mask) + index * BIT_IN_LONG; 10255392539fea537abfb6581b474918f9d611fba27Jesse Wilson last = enums[ordinal]; 10355392539fea537abfb6581b474918f9d611fba27Jesse Wilson 10455392539fea537abfb6581b474918f9d611fba27Jesse Wilson currentBits &= ~mask; 10555392539fea537abfb6581b474918f9d611fba27Jesse Wilson computeNextElement(); 10655392539fea537abfb6581b474918f9d611fba27Jesse Wilson 10755392539fea537abfb6581b474918f9d611fba27Jesse Wilson return last; 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void remove() { 11155392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (last == null) { 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalStateException(); 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 11455392539fea537abfb6581b474918f9d611fba27Jesse Wilson 11555392539fea537abfb6581b474918f9d611fba27Jesse Wilson HugeEnumSet.this.remove(last); 11655392539fea537abfb6581b474918f9d611fba27Jesse Wilson last = null; 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 119f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean add(E element) { 122415c7497ec02890a73eb293f98f69c1f6983389bElliott Hughes elementClass.cast(element); // Called to throw ClassCastException. 12355392539fea537abfb6581b474918f9d611fba27Jesse Wilson int ordinal = element.ordinal(); 12455392539fea537abfb6581b474918f9d611fba27Jesse Wilson int index = ordinal / BIT_IN_LONG; 12555392539fea537abfb6581b474918f9d611fba27Jesse Wilson int inBits = ordinal % BIT_IN_LONG; 12655392539fea537abfb6581b474918f9d611fba27Jesse Wilson long oldBits = bits[index]; 12755392539fea537abfb6581b474918f9d611fba27Jesse Wilson long newBits = oldBits | (1L << inBits); 12855392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (oldBits != newBits) { 12955392539fea537abfb6581b474918f9d611fba27Jesse Wilson bits[index] = newBits; 13055392539fea537abfb6581b474918f9d611fba27Jesse Wilson size++; 13155392539fea537abfb6581b474918f9d611fba27Jesse Wilson return true; 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 13355392539fea537abfb6581b474918f9d611fba27Jesse Wilson return false; 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 135f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean addAll(Collection<? extends E> collection) { 13855392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (collection.isEmpty() || collection == this) { 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 14155392539fea537abfb6581b474918f9d611fba27Jesse Wilson 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (collection instanceof EnumSet) { 14355392539fea537abfb6581b474918f9d611fba27Jesse Wilson EnumSet<?> set = (EnumSet) collection; // raw type due to javac bug 6548436 144415c7497ec02890a73eb293f98f69c1f6983389bElliott Hughes set.elementClass.asSubclass(elementClass); // Called to throw ClassCastException. 14555392539fea537abfb6581b474918f9d611fba27Jesse Wilson 14655392539fea537abfb6581b474918f9d611fba27Jesse Wilson HugeEnumSet<E> hugeSet = (HugeEnumSet<E>) set; 14755392539fea537abfb6581b474918f9d611fba27Jesse Wilson boolean changed = false; 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < bits.length; i++) { 14955392539fea537abfb6581b474918f9d611fba27Jesse Wilson long oldBits = bits[i]; 15055392539fea537abfb6581b474918f9d611fba27Jesse Wilson long newBits = oldBits | hugeSet.bits[i]; 15155392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (oldBits != newBits) { 15255392539fea537abfb6581b474918f9d611fba27Jesse Wilson bits[i] = newBits; 15355392539fea537abfb6581b474918f9d611fba27Jesse Wilson size += Long.bitCount(newBits) - Long.bitCount(oldBits); 15455392539fea537abfb6581b474918f9d611fba27Jesse Wilson changed = true; 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 15755392539fea537abfb6581b474918f9d611fba27Jesse Wilson return changed; 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return super.addAll(collection); 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 161f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int size() { 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return size; 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 166f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void clear() { 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Arrays.fill(bits, 0); 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project size = 0; 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 172f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected void complement() { 17555392539fea537abfb6581b474918f9d611fba27Jesse Wilson size = 0; 17655392539fea537abfb6581b474918f9d611fba27Jesse Wilson for (int i = 0, length = bits.length; i < length; i++) { 17755392539fea537abfb6581b474918f9d611fba27Jesse Wilson long b = ~bits[i]; 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 17955392539fea537abfb6581b474918f9d611fba27Jesse Wilson // zero out unused bits on the last element 18055392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (i == length - 1) { 18155392539fea537abfb6581b474918f9d611fba27Jesse Wilson b &= -1L >>> (BIT_IN_LONG - (enums.length % BIT_IN_LONG)); 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 18355392539fea537abfb6581b474918f9d611fba27Jesse Wilson 18455392539fea537abfb6581b474918f9d611fba27Jesse Wilson size += Long.bitCount(b); 18555392539fea537abfb6581b474918f9d611fba27Jesse Wilson bits[i] = b; 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 188f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean contains(Object object) { 19155392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (object == null || !isValidType(object.getClass())) { 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 19455392539fea537abfb6581b474918f9d611fba27Jesse Wilson 19555392539fea537abfb6581b474918f9d611fba27Jesse Wilson @SuppressWarnings("unchecked") // guarded by isValidType() 19655392539fea537abfb6581b474918f9d611fba27Jesse Wilson int ordinal = ((E) object).ordinal(); 19755392539fea537abfb6581b474918f9d611fba27Jesse Wilson int index = ordinal / BIT_IN_LONG; 19855392539fea537abfb6581b474918f9d611fba27Jesse Wilson int inBits = ordinal % BIT_IN_LONG; 19955392539fea537abfb6581b474918f9d611fba27Jesse Wilson return (bits[index] & (1L << inBits)) != 0; 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 201f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public HugeEnumSet<E> clone() { 20455392539fea537abfb6581b474918f9d611fba27Jesse Wilson HugeEnumSet<E> set = (HugeEnumSet<E>) super.clone(); 20555392539fea537abfb6581b474918f9d611fba27Jesse Wilson set.bits = bits.clone(); 20655392539fea537abfb6581b474918f9d611fba27Jesse Wilson return set; 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 208f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean containsAll(Collection<?> collection) { 21155392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (collection.isEmpty()) { 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (collection instanceof HugeEnumSet) { 21555392539fea537abfb6581b474918f9d611fba27Jesse Wilson HugeEnumSet<?> set = (HugeEnumSet<?>) collection; 21655392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (isValidType(set.elementClass)) { 21755392539fea537abfb6581b474918f9d611fba27Jesse Wilson for (int i = 0; i < bits.length; i++) { 21855392539fea537abfb6581b474918f9d611fba27Jesse Wilson long setBits = set.bits[i]; 21955392539fea537abfb6581b474918f9d611fba27Jesse Wilson if ((bits[i] & setBits) != setBits) { 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return !(collection instanceof EnumSet) && super.containsAll(collection); 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 228f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean equals(Object object) { 23155392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (object == null) { 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isValidType(object.getClass())) { 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return super.equals(object); 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 23755392539fea537abfb6581b474918f9d611fba27Jesse Wilson return Arrays.equals(bits, ((HugeEnumSet<?>) object).bits); 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 239f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Iterator<E> iterator() { 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new HugeEnumSetIterator(); 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 244f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean remove(Object object) { 24755392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (object == null || !isValidType(object.getClass())) { 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 25055392539fea537abfb6581b474918f9d611fba27Jesse Wilson 25155392539fea537abfb6581b474918f9d611fba27Jesse Wilson @SuppressWarnings("unchecked") // guarded by isValidType() 25255392539fea537abfb6581b474918f9d611fba27Jesse Wilson int ordinal = ((E) object).ordinal(); 25355392539fea537abfb6581b474918f9d611fba27Jesse Wilson int index = ordinal / BIT_IN_LONG; 25455392539fea537abfb6581b474918f9d611fba27Jesse Wilson int inBits = ordinal % BIT_IN_LONG; 25555392539fea537abfb6581b474918f9d611fba27Jesse Wilson long oldBits = bits[index]; 25655392539fea537abfb6581b474918f9d611fba27Jesse Wilson long newBits = oldBits & ~(1L << inBits); 25755392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (oldBits != newBits) { 25855392539fea537abfb6581b474918f9d611fba27Jesse Wilson bits[index] = newBits; 25955392539fea537abfb6581b474918f9d611fba27Jesse Wilson size--; 26055392539fea537abfb6581b474918f9d611fba27Jesse Wilson return true; 26155392539fea537abfb6581b474918f9d611fba27Jesse Wilson } 26255392539fea537abfb6581b474918f9d611fba27Jesse Wilson return false; 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 264f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean removeAll(Collection<?> collection) { 26755392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (collection.isEmpty()) { 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 270f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (collection instanceof EnumSet) { 27255392539fea537abfb6581b474918f9d611fba27Jesse Wilson EnumSet<?> set = (EnumSet<?>) collection; 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isValidType(set.elementClass)) { 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 27655392539fea537abfb6581b474918f9d611fba27Jesse Wilson 27755392539fea537abfb6581b474918f9d611fba27Jesse Wilson HugeEnumSet<E> hugeSet = (HugeEnumSet<E>) set; 27855392539fea537abfb6581b474918f9d611fba27Jesse Wilson boolean changed = false; 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < bits.length; i++) { 28055392539fea537abfb6581b474918f9d611fba27Jesse Wilson long oldBits = bits[i]; 28155392539fea537abfb6581b474918f9d611fba27Jesse Wilson long newBits = oldBits & ~hugeSet.bits[i]; 28255392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (oldBits != newBits) { 28355392539fea537abfb6581b474918f9d611fba27Jesse Wilson bits[i] = newBits; 28455392539fea537abfb6581b474918f9d611fba27Jesse Wilson size += Long.bitCount(newBits) - Long.bitCount(oldBits); 28555392539fea537abfb6581b474918f9d611fba27Jesse Wilson changed = true; 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 28855392539fea537abfb6581b474918f9d611fba27Jesse Wilson return changed; 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return super.removeAll(collection); 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 292f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean retainAll(Collection<?> collection) { 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (collection instanceof EnumSet) { 29655392539fea537abfb6581b474918f9d611fba27Jesse Wilson EnumSet<?> set = (EnumSet<?>) collection; 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isValidType(set.elementClass)) { 29855392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (size > 0) { 29955392539fea537abfb6581b474918f9d611fba27Jesse Wilson clear(); 30055392539fea537abfb6581b474918f9d611fba27Jesse Wilson return true; 30155392539fea537abfb6581b474918f9d611fba27Jesse Wilson } else { 30255392539fea537abfb6581b474918f9d611fba27Jesse Wilson return false; 30355392539fea537abfb6581b474918f9d611fba27Jesse Wilson } 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 30655392539fea537abfb6581b474918f9d611fba27Jesse Wilson HugeEnumSet<E> hugeSet = (HugeEnumSet<E>) set; 30755392539fea537abfb6581b474918f9d611fba27Jesse Wilson boolean changed = false; 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < bits.length; i++) { 30955392539fea537abfb6581b474918f9d611fba27Jesse Wilson long oldBits = bits[i]; 31055392539fea537abfb6581b474918f9d611fba27Jesse Wilson long newBits = oldBits & hugeSet.bits[i]; 31155392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (oldBits != newBits) { 31255392539fea537abfb6581b474918f9d611fba27Jesse Wilson bits[i] = newBits; 31355392539fea537abfb6581b474918f9d611fba27Jesse Wilson size += Long.bitCount(newBits) - Long.bitCount(oldBits); 31455392539fea537abfb6581b474918f9d611fba27Jesse Wilson changed = true; 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 31755392539fea537abfb6581b474918f9d611fba27Jesse Wilson return changed; 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return super.retainAll(collection); 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 321f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project void setRange(E start, E end) { 32455392539fea537abfb6581b474918f9d611fba27Jesse Wilson int startOrdinal = start.ordinal(); 32555392539fea537abfb6581b474918f9d611fba27Jesse Wilson int startIndex = startOrdinal / BIT_IN_LONG; 32655392539fea537abfb6581b474918f9d611fba27Jesse Wilson int startInBits = startOrdinal % BIT_IN_LONG; 32755392539fea537abfb6581b474918f9d611fba27Jesse Wilson 32855392539fea537abfb6581b474918f9d611fba27Jesse Wilson int endOrdinal = end.ordinal(); 32955392539fea537abfb6581b474918f9d611fba27Jesse Wilson int endIndex = endOrdinal / BIT_IN_LONG; 33055392539fea537abfb6581b474918f9d611fba27Jesse Wilson int endInBits = endOrdinal % BIT_IN_LONG; 33155392539fea537abfb6581b474918f9d611fba27Jesse Wilson 33255392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (startIndex == endIndex) { 33355392539fea537abfb6581b474918f9d611fba27Jesse Wilson long range = (-1L >>> (BIT_IN_LONG -(endInBits - startInBits + 1))) << startInBits; 33455392539fea537abfb6581b474918f9d611fba27Jesse Wilson size -= Long.bitCount(bits[startIndex]); 33555392539fea537abfb6581b474918f9d611fba27Jesse Wilson bits[startIndex] |= range; 33655392539fea537abfb6581b474918f9d611fba27Jesse Wilson size += Long.bitCount(bits[startIndex]); 33755392539fea537abfb6581b474918f9d611fba27Jesse Wilson 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 33955392539fea537abfb6581b474918f9d611fba27Jesse Wilson long range = (-1L >>> startInBits) << startInBits; 34055392539fea537abfb6581b474918f9d611fba27Jesse Wilson size -= Long.bitCount(bits[startIndex]); 34155392539fea537abfb6581b474918f9d611fba27Jesse Wilson bits[startIndex] |= range; 34255392539fea537abfb6581b474918f9d611fba27Jesse Wilson size += Long.bitCount(bits[startIndex]); 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 34455392539fea537abfb6581b474918f9d611fba27Jesse Wilson // endInBits + 1 is the number of consecutive ones. 34555392539fea537abfb6581b474918f9d611fba27Jesse Wilson // 63 - endInBits is the following zeros of the right most one. 34655392539fea537abfb6581b474918f9d611fba27Jesse Wilson range = -1L >>> (BIT_IN_LONG - (endInBits + 1)); 34755392539fea537abfb6581b474918f9d611fba27Jesse Wilson size -= Long.bitCount(bits[endIndex]); 34855392539fea537abfb6581b474918f9d611fba27Jesse Wilson bits[endIndex] |= range; 34955392539fea537abfb6581b474918f9d611fba27Jesse Wilson size += Long.bitCount(bits[endIndex]); 35055392539fea537abfb6581b474918f9d611fba27Jesse Wilson for (int i = (startIndex + 1); i <= (endIndex - 1); i++) { 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project size -= Long.bitCount(bits[i]); 35255392539fea537abfb6581b474918f9d611fba27Jesse Wilson bits[i] = -1L; 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project size += Long.bitCount(bits[i]); 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 358