Home » openjdk-7 » java » util » [javadoc | source]

    1   /* Licensed to the Apache Software Foundation (ASF) under one or more
    2    * contributor license agreements.  See the NOTICE file distributed with
    3    * this work for additional information regarding copyright ownership.
    4    * The ASF licenses this file to You under the Apache License, Version 2.0
    5    * (the "License"); you may not use this file except in compliance with
    6    * the License.  You may obtain a copy of the License at
    7    * 
    8    *     http://www.apache.org/licenses/LICENSE-2.0
    9    * 
   10    * Unless required by applicable law or agreed to in writing, software
   11    * distributed under the License is distributed on an "AS IS" BASIS,
   12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   13    * See the License for the specific language governing permissions and
   14    * limitations under the License.
   15    */
   16   
   17   package java.util;
   18   
   19   
   20   /**
   21    * A concrete EnumSet for enums with 64 or fewer elements.
   22    */
   23   @SuppressWarnings("serial")
   24   final class MiniEnumSet<E extends Enum<E>> extends EnumSet<E> {
   25       private static final int MAX_ELEMENTS = 64;
   26       
   27       private int size;
   28       
   29       private final E[] enums;    
   30       
   31       private long bits;
   32       
   33       MiniEnumSet(Class<E> elementType) {
   34           super(elementType);
   35           enums = elementType.getEnumConstants();
   36       }
   37       
   38       private class MiniEnumSetIterator implements Iterator<E> {
   39   
   40           /**
   41            * The bits yet to be returned for bits. As values from the current index are returned,
   42            * their bits are zeroed out.
   43            */
   44           private long currentBits = bits;
   45   
   46           /**
   47            * The single bit of the next value to return.
   48            */
   49           private long mask = currentBits & -currentBits; // the lowest 1 bit in currentBits
   50   
   51           /**
   52            * The candidate for removal. If null, no value may be removed.
   53            */
   54           private E last;
   55   
   56           public boolean hasNext() {
   57               return mask != 0;
   58           }
   59   
   60           public E next() {
   61               if (mask == 0) {
   62                   throw new NoSuchElementException();
   63               }
   64   
   65               int ordinal = Long.numberOfTrailingZeros(mask);
   66               last = enums[ordinal];
   67   
   68               currentBits &= ~mask;
   69               mask = currentBits & -currentBits; // the lowest 1 bit in currentBits
   70   
   71               return last;
   72           }
   73   
   74           public void remove() {
   75               if (last == null) {
   76                   throw new IllegalStateException();
   77               }
   78   
   79               MiniEnumSet.this.remove(last);
   80               last = null;
   81           }
   82       }
   83   
   84       @Override
   85       public Iterator<E> iterator() {
   86           return new MiniEnumSetIterator();
   87       }
   88   
   89       @Override
   90       public int size() {
   91           return size;
   92       }
   93       
   94       @Override
   95       public void clear() {
   96           bits = 0;
   97           size = 0;
   98       }
   99       
  100       @Override
  101       public boolean add(E element) {
  102           if (!isValidType(element.getDeclaringClass())) {
  103               throw new ClassCastException();
  104           }
  105   
  106           long oldBits = bits;
  107           long newBits = oldBits | (1L << element.ordinal());
  108           if (oldBits != newBits) {
  109               bits = newBits;
  110               size++;
  111               return true;
  112           }
  113           return false;
  114       }
  115       
  116       @Override
  117       public boolean addAll(Collection<? extends E> collection) {
  118           if (collection.isEmpty()) {
  119               return false;
  120           }
  121           if (collection instanceof EnumSet) {
  122               EnumSet<?> set = (EnumSet<?>) collection;
  123               if (!isValidType(set.elementClass)) {
  124                   throw new ClassCastException();
  125               }
  126   
  127               MiniEnumSet<?> miniSet = (MiniEnumSet<?>) set;
  128               long oldBits = bits;
  129               long newBits = oldBits | miniSet.bits;
  130               bits = newBits;
  131               size = Long.bitCount(newBits);
  132               return (oldBits != newBits);
  133           }
  134           return super.addAll(collection);
  135       }
  136       
  137       @Override
  138       public boolean contains(Object object) {
  139           if (object == null || !isValidType(object.getClass())) {
  140               return false;
  141           }
  142   
  143           @SuppressWarnings("unchecked") // guarded by isValidType()
  144           Enum<E> element = (Enum<E>) object;
  145           int ordinal = element.ordinal();
  146           return (bits & (1L << ordinal)) != 0;
  147       }
  148       
  149       @Override
  150       public boolean containsAll(Collection<?> collection) {
  151           if (collection.isEmpty()) {
  152               return true;
  153           }
  154           if (collection instanceof MiniEnumSet) {
  155               MiniEnumSet<?> set = (MiniEnumSet<?>) collection;
  156               long setBits = set.bits;
  157               return isValidType(set.elementClass) && ((bits & setBits) == setBits);
  158           }
  159           return !(collection instanceof EnumSet) && super.containsAll(collection);  
  160       }
  161       
  162       @Override
  163       public boolean removeAll(Collection<?> collection) {
  164           if (collection.isEmpty()) {
  165               return false;
  166           }
  167           if (collection instanceof EnumSet) {
  168               EnumSet<?> set = (EnumSet<?>) collection;
  169               if (!isValidType(set.elementClass)) {
  170                   return false;
  171               }
  172   
  173               MiniEnumSet<E> miniSet = (MiniEnumSet<E>) set;
  174               long oldBits = bits;
  175               long newBits = oldBits & ~miniSet.bits;
  176               if (oldBits != newBits) {
  177                   bits = newBits;
  178                   size = Long.bitCount(newBits);
  179                   return true;
  180               }
  181               return false;
  182           }
  183           return super.removeAll(collection);
  184       }
  185   
  186       @Override
  187       public boolean retainAll(Collection<?> collection) {
  188           if (collection instanceof EnumSet) {
  189               EnumSet<?> set = (EnumSet<?>) collection;
  190               if (!isValidType(set.elementClass)) {
  191                   if (size > 0) {
  192                       clear();
  193                       return true;
  194                   } else {
  195                       return false;
  196                   }
  197               }
  198   
  199               MiniEnumSet<E> miniSet = (MiniEnumSet<E>) set;
  200               long oldBits = bits;
  201               long newBits = oldBits & miniSet.bits;
  202               if (oldBits != newBits) {
  203                   bits = newBits;
  204                   size = Long.bitCount(newBits);
  205                   return true;
  206               }
  207               return false;
  208           }
  209           return super.retainAll(collection);
  210       }
  211       
  212       @Override
  213       public boolean remove(Object object) {
  214           if (object == null || !isValidType(object.getClass())) {
  215               return false;
  216           }
  217   
  218           @SuppressWarnings("unchecked") // guarded by isValidType() 
  219           Enum<E> element = (Enum<E>) object;
  220           int ordinal = element.ordinal();
  221           long oldBits = bits;
  222           long newBits = oldBits & ~(1L << ordinal);
  223           if (oldBits != newBits) {
  224               bits = newBits;
  225               size--;
  226               return true;
  227           }
  228           return false;
  229       }
  230       
  231       @Override
  232       public boolean equals(Object object) {
  233           if (!(object instanceof EnumSet)) {
  234               return super.equals(object);
  235           }
  236           EnumSet<?> set =(EnumSet<?>) object;
  237           if (!isValidType(set.elementClass)) {
  238               return size == 0 && set.isEmpty();
  239           }
  240           return bits == ((MiniEnumSet<?>) set).bits;
  241       }
  242       
  243       @Override
  244       void complement() {
  245           if (enums.length != 0) {
  246               bits = ~bits;
  247               bits &= (-1L >>> (MAX_ELEMENTS - enums.length));
  248               size = enums.length - size;
  249           }
  250       }
  251       
  252       @Override
  253       void setRange(E start, E end) {
  254           int length = end.ordinal() - start.ordinal() + 1;
  255           long range = (-1L >>> (MAX_ELEMENTS - length)) << start.ordinal();
  256           bits |= range;
  257           size = Long.bitCount(bits);
  258       }
  259   }

Home » openjdk-7 » java » util » [javadoc | source]