src/share/classes/com/sun/tools/javac/util/Bits.java

Thu, 10 Jun 2010 16:08:01 -0700

author
jjg
date
Thu, 10 Jun 2010 16:08:01 -0700
changeset 581
f2fdd52e4e87
parent 554
9d9f26857129
child 773
5fb14e67c371
permissions
-rw-r--r--

6944312: Potential rebranding issues in openjdk/langtools repository sources
Reviewed-by: darcy

     1 /*
     2  * Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package com.sun.tools.javac.util;
    28 /** A class for extensible, mutable bit sets.
    29  *
    30  *  <p><b>This is NOT part of any supported API.
    31  *  If you write code that depends on this, you do so at your own risk.
    32  *  This code and its internal interfaces are subject to change or
    33  *  deletion without notice.</b>
    34  */
    35 public class Bits {
    38     private final static int wordlen = 32;
    39     private final static int wordshift = 5;
    40     private final static int wordmask = wordlen - 1;
    42     private int[] bits;
    44     /** Construct an initially empty set.
    45      */
    46     public Bits() {
    47         this(new int[1]);
    48     }
    50     /** Construct a set consisting initially of given bit vector.
    51      */
    52     public Bits(int[] bits) {
    53         this.bits = bits;
    54     }
    56     /** Construct a set consisting initially of given range.
    57      */
    58     public Bits(int start, int limit) {
    59         this();
    60         inclRange(start, limit);
    61     }
    63     private void sizeTo(int len) {
    64         if (bits.length < len) {
    65             int[] newbits = new int[len];
    66             System.arraycopy(bits, 0, newbits, 0, bits.length);
    67             bits = newbits;
    68         }
    69     }
    71     /** This set = {}.
    72      */
    73     public void clear() {
    74         for (int i = 0; i < bits.length; i++) bits[i] = 0;
    75     }
    77     /** Return a copy of this set.
    78      */
    79     public Bits dup() {
    80         int[] newbits = new int[bits.length];
    81         System.arraycopy(bits, 0, newbits, 0, bits.length);
    82         return new Bits(newbits);
    83     }
    85     /** Include x in this set.
    86      */
    87     public void incl(int x) {
    88         assert x >= 0;
    89         sizeTo((x >>> wordshift) + 1);
    90         bits[x >>> wordshift] = bits[x >>> wordshift] |
    91             (1 << (x & wordmask));
    92     }
    95     /** Include [start..limit) in this set.
    96      */
    97     public void inclRange(int start, int limit) {
    98         sizeTo((limit >>> wordshift) + 1);
    99         for (int x = start; x < limit; x++)
   100             bits[x >>> wordshift] = bits[x >>> wordshift] |
   101                 (1 << (x & wordmask));
   102     }
   104     /** Exclude x from this set.
   105      */
   106     public void excl(int x) {
   107         assert x >= 0;
   108         sizeTo((x >>> wordshift) + 1);
   109         bits[x >>> wordshift] = bits[x >>> wordshift] &
   110             ~(1 << (x & wordmask));
   111     }
   113     /** Is x an element of this set?
   114      */
   115     public boolean isMember(int x) {
   116         return
   117             0 <= x && x < (bits.length << wordshift) &&
   118             (bits[x >>> wordshift] & (1 << (x & wordmask))) != 0;
   119     }
   121     /** this set = this set & xs.
   122      */
   123     public Bits andSet(Bits xs) {
   124         sizeTo(xs.bits.length);
   125         for (int i = 0; i < xs.bits.length; i++)
   126             bits[i] = bits[i] & xs.bits[i];
   127         return this;
   128     }
   130     /** this set = this set | xs.
   131      */
   132     public Bits orSet(Bits xs) {
   133         sizeTo(xs.bits.length);
   134         for (int i = 0; i < xs.bits.length; i++)
   135             bits[i] = bits[i] | xs.bits[i];
   136         return this;
   137     }
   139     /** this set = this set \ xs.
   140      */
   141     public Bits diffSet(Bits xs) {
   142         for (int i = 0; i < bits.length; i++) {
   143             if (i < xs.bits.length) {
   144                 bits[i] = bits[i] & ~xs.bits[i];
   145             }
   146         }
   147         return this;
   148     }
   150     /** this set = this set ^ xs.
   151      */
   152     public Bits xorSet(Bits xs) {
   153         sizeTo(xs.bits.length);
   154         for (int i = 0; i < xs.bits.length; i++)
   155             bits[i] = bits[i] ^ xs.bits[i];
   156         return this;
   157     }
   159     /** Count trailing zero bits in an int. Algorithm from "Hacker's
   160      *  Delight" by Henry S. Warren Jr. (figure 5-13)
   161      */
   162     private static int trailingZeroBits(int x) {
   163         assert wordlen == 32;
   164         if (x == 0) return 32;
   165         int n = 1;
   166         if ((x & 0xffff) == 0) { n += 16; x >>>= 16; }
   167         if ((x & 0x00ff) == 0) { n +=  8; x >>>=  8; }
   168         if ((x & 0x000f) == 0) { n +=  4; x >>>=  4; }
   169         if ((x & 0x0003) == 0) { n +=  2; x >>>=  2; }
   170         return n - (x&1);
   171     }
   173     /** Return the index of the least bit position >= x that is set.
   174      *  If none are set, returns -1.  This provides a nice way to iterate
   175      *  over the members of a bit set:
   176      *  <pre>
   177      *  for (int i = bits.nextBit(0); i>=0; i = bits.nextBit(i+1)) ...
   178      *  </pre>
   179      */
   180     public int nextBit(int x) {
   181         int windex = x >>> wordshift;
   182         if (windex >= bits.length) return -1;
   183         int word = bits[windex] & ~((1 << (x & wordmask))-1);
   184         while (true) {
   185             if (word != 0)
   186                 return (windex << wordshift) + trailingZeroBits(word);
   187             windex++;
   188             if (windex >= bits.length) return -1;
   189             word = bits[windex];
   190         }
   191     }
   193     /** a string representation of this set.
   194      */
   195     public String toString() {
   196         char[] digits = new char[bits.length * wordlen];
   197         for (int i = 0; i < bits.length * wordlen; i++)
   198             digits[i] = isMember(i) ? '1' : '0';
   199         return new String(digits);
   200     }
   202     /** Test Bits.nextBit(int). */
   203     public static void main(String[] args) {
   204         java.util.Random r = new java.util.Random();
   205         Bits bits = new Bits();
   206         int dupCount = 0;
   207         for (int i=0; i<125; i++) {
   208             int k;
   209             do {
   210                 k = r.nextInt(250);
   211             } while (bits.isMember(k));
   212             System.out.println("adding " + k);
   213             bits.incl(k);
   214         }
   215         int count = 0;
   216         for (int i = bits.nextBit(0); i >= 0; i = bits.nextBit(i+1)) {
   217             System.out.println("found " + i);
   218             count ++;
   219         }
   220         if (count != 125) throw new Error();
   221     }
   222 }

mercurial