BitSet.java revision b1396870f92135aa140bd2b86221768dea5bc11d
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilsonimport java.io.IOException;
21f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilsonimport java.io.ObjectInputStream;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.Serializable;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The {@code BitSet} class implements a bit field. Each element in a
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code BitSet} can be on(1) or off(0). A {@code BitSet} is created with a
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * given size and grows if this size is exceeded. Growth is always rounded to a
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 64 bit boundary.
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class BitSet implements Serializable, Cloneable {
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final long serialVersionUID = 7997698588986878753L;
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
33f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private static final int OFFSET = 6;
34f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
35f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private static final int ELM_SIZE = 1 << OFFSET;
36f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
37f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private static final int RIGHT_BITS = ELM_SIZE - 1;
38f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
39f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private static final long[] TWO_N_ARRAY = new long[] { 0x1L, 0x2L, 0x4L,
40f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            0x8L, 0x10L, 0x20L, 0x40L, 0x80L, 0x100L, 0x200L, 0x400L, 0x800L,
41f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            0x1000L, 0x2000L, 0x4000L, 0x8000L, 0x10000L, 0x20000L, 0x40000L,
42f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            0x80000L, 0x100000L, 0x200000L, 0x400000L, 0x800000L, 0x1000000L,
43f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            0x2000000L, 0x4000000L, 0x8000000L, 0x10000000L, 0x20000000L,
44f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            0x40000000L, 0x80000000L, 0x100000000L, 0x200000000L, 0x400000000L,
45f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            0x800000000L, 0x1000000000L, 0x2000000000L, 0x4000000000L,
46f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            0x8000000000L, 0x10000000000L, 0x20000000000L, 0x40000000000L,
47f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            0x80000000000L, 0x100000000000L, 0x200000000000L, 0x400000000000L,
48f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            0x800000000000L, 0x1000000000000L, 0x2000000000000L,
49f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            0x4000000000000L, 0x8000000000000L, 0x10000000000000L,
50f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            0x20000000000000L, 0x40000000000000L, 0x80000000000000L,
51f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            0x100000000000000L, 0x200000000000000L, 0x400000000000000L,
52f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            0x800000000000000L, 0x1000000000000000L, 0x2000000000000000L,
53f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            0x4000000000000000L, 0x8000000000000000L };
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private long[] bits;
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
57f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private transient boolean needClear;
58f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
59f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private transient int actualArrayLength;
60f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
61f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private transient boolean isLengthActual;
62f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Create a new {@code BitSet} with size equal to 64 bits.
65f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #clear(int)
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #set(int)
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #clear()
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #clear(int, int)
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #set(int, boolean)
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #set(int, int)
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #set(int, int, boolean)
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BitSet() {
75f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        bits = new long[1];
76f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        actualArrayLength = 0;
77f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        isLengthActual = true;
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Create a new {@code BitSet} with size equal to nbits. If nbits is not a
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * multiple of 64, then create a {@code BitSet} with size nbits rounded to
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the next closest multiple of 64.
84f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param nbits
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the size of the bit set.
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NegativeArraySizeException
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code nbits} is negative.
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #clear(int)
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #set(int)
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #clear()
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #clear(int, int)
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #set(int, boolean)
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #set(int, int)
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #set(int, int, boolean)
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BitSet(int nbits) {
98f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (nbits < 0) {
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new NegativeArraySizeException();
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
101f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        bits = new long[(nbits >> OFFSET) + ((nbits & RIGHT_BITS) > 0 ? 1 : 0)];
102f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        actualArrayLength = 0;
103f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        isLengthActual = true;
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Private constructor called from get(int, int) method
108f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param bits
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the size of the bit set
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
112b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    private BitSet(long[] bits, boolean needClear, int actualArrayLength, boolean isLengthActual) {
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.bits = bits;
114f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        this.needClear = needClear;
115f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        this.actualArrayLength = actualArrayLength;
116f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        this.isLengthActual = isLengthActual;
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a copy of this {@code BitSet}.
121f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a copy of this {@code BitSet}.
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Object clone() {
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            BitSet clone = (BitSet) super.clone();
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            clone.bits = bits.clone();
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return clone;
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (CloneNotSupportedException e) {
1311c422fc0ab0692e10a05af6f48c6276c4dad4beaJesse Wilson            throw new AssertionError(e); // android-changed
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Compares the argument to this {@code BitSet} and returns whether they are
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * equal. The object must be an instance of {@code BitSet} with the same
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * bits set.
139f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code BitSet} object to compare.
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a {@code boolean} indicating whether or not this {@code BitSet} and
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code obj} are equal.
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #hashCode
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean equals(Object obj) {
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this == obj) {
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return true;
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (obj instanceof BitSet) {
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long[] bsBits = ((BitSet) obj).bits;
153f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            int length1 = this.actualArrayLength, length2 = ((BitSet) obj).actualArrayLength;
154f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            if (this.isLengthActual && ((BitSet) obj).isLengthActual
155f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                    && length1 != length2) {
156f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                return false;
157f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // If one of the BitSets is larger than the other, check to see if
159f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            // any of its extra bits are set. If so return false.
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (length1 <= length2) {
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i = 0; i < length1; i++) {
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (bits[i] != bsBits[i]) {
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        return false;
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i = length1; i < length2; i++) {
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (bsBits[i] != 0) {
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        return false;
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i = 0; i < length2; i++) {
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (bits[i] != bsBits[i]) {
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        return false;
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i = length2; i < length1; i++) {
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (bits[i] != 0) {
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        return false;
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return true;
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
189b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * Increase the size of the internal array to accommodate {@code len} bits.
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The new array max index will be a multiple of 64.
191f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
192f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @param len
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the index the new array needs to be able to access.
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
195f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private final void growLength(int len) {
196f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        long[] tempBits = new long[Math.max(len, bits.length * 2)];
197f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        System.arraycopy(bits, 0, tempBits, 0, this.actualArrayLength);
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        bits = tempBits;
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Computes the hash code for this {@code BitSet}. If two {@code BitSet}s are equal
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the have to return the same result for {@code hashCode()}.
204f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the {@code int} representing the hash code for this bit
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         set.
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #equals
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see java.util.Hashtable
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int hashCode() {
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long x = 1234;
213f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        for (int i = 0, length = actualArrayLength; i < length; i++) {
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            x ^= bits[i] * (i + 1);
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return (int) ((x >> 32) ^ x);
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
220b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * Retrieves the bit at index {@code index}. Grows the {@code BitSet} if
221b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * {@code index > size}.
222f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
223b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * @param index
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the index of the bit to be retrieved.
225b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * @return {@code true} if the bit at {@code index} is set,
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
228b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     *             if {@code index} is negative.
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #clear(int)
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #set(int)
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #clear()
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #clear(int, int)
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #set(int, boolean)
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #set(int, int)
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #set(int, int, boolean)
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
237b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    public boolean get(int index) {
238b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        checkIndex(index);
239b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        int arrayPos = index >> OFFSET;
240f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (arrayPos < actualArrayLength) {
241b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            return (bits[arrayPos] & TWO_N_ARRAY[index & RIGHT_BITS]) != 0;
242f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
243f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        return false;
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
246b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    private void checkIndex(int index) {
247b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        if (index < 0) {
248b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IndexOutOfBoundsException("index < 0");
249b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        }
250b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    }
251b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes
252b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    private void checkRange(int fromIndex, int toIndex) {
253b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        if (fromIndex < 0 || toIndex < 0 || toIndex < fromIndex) {
254b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IndexOutOfBoundsException("fromIndex=" + fromIndex + " toIndex=" + toIndex);
255b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        }
256b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    }
257b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
259b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * Retrieves the bits starting from {@code fromIndex} to {@code toIndex} and returns
260b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * back a new bitset made of these bits. Grows the {@code BitSet} if {@code toIndex &gt; size}.
261f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
262b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * @param fromIndex
263f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *            inclusive beginning position.
264b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * @param toIndex
265f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *            exclusive ending position.
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return new bitset of the range specified.
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
268b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     *             if {@code fromIndex} or {@code toIndex} is negative, or if
269b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     *             {@code toIndex} is smaller than {@code fromIndex}.
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #get(int)
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
272b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    public BitSet get(int fromIndex, int toIndex) {
273b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        checkRange(fromIndex, toIndex);
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
275f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        int last = actualArrayLength << OFFSET;
276b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        if (fromIndex >= last || fromIndex == toIndex) {
277f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            return new BitSet(0);
278f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
279b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        if (toIndex > last) {
280b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            toIndex = last;
281f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
283b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        int idx1 = fromIndex >> OFFSET;
284b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        int idx2 = (toIndex - 1) >> OFFSET;
285b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        long factor1 = (~0L) << (fromIndex & RIGHT_BITS);
286b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        long factor2 = (~0L) >>> (ELM_SIZE - (toIndex & RIGHT_BITS));
287f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
288f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (idx1 == idx2) {
289b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            long result = (bits[idx1] & (factor1 & factor2)) >>> (fromIndex % ELM_SIZE);
290f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            if (result == 0) {
291f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                return new BitSet(0);
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
293f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            return new BitSet(new long[] { result }, needClear, 1, true);
294f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
295f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        long[] newbits = new long[idx2 - idx1 + 1];
296f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // first fill in the first and last indexes in the new bitset
297f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        newbits[0] = bits[idx1] & factor1;
298f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        newbits[newbits.length - 1] = bits[idx2] & factor2;
299f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
300f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // fill in the in between elements of the new bitset
301f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        for (int i = 1; i < idx2 - idx1; i++) {
302f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            newbits[i] = bits[idx1 + i];
303f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
305b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        // shift all the elements in the new bitset to the right by fromIndex % ELM_SIZE
306b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        int numBitsToShift = fromIndex & RIGHT_BITS;
307f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        int actualLen = newbits.length;
308f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (numBitsToShift != 0) {
309f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            for (int i = 0; i < newbits.length; i++) {
310f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                // shift the current element to the right regardless of
311f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                // sign
312f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                newbits[i] = newbits[i] >>> (numBitsToShift);
313f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
314f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                // apply the last x bits of newbits[i+1] to the current
315f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                // element
316f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                if (i != newbits.length - 1) {
317f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                    newbits[i] |= newbits[i + 1] << (ELM_SIZE - (numBitsToShift));
318f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                }
319f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                if (newbits[i] != 0) {
320f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                    actualLen = i + 1;
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
324f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        return new BitSet(newbits, needClear, actualLen,
325f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                newbits[actualLen - 1] != 0);
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
329b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * Sets the bit at index {@code index} to 1. Grows the {@code BitSet} if
330b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * {@code index > size}.
331f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
332b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * @param index
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the index of the bit to set.
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
335b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     *             if {@code index} is negative.
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #clear(int)
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #clear()
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #clear(int, int)
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
340b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    public void set(int index) {
341b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        checkIndex(index);
342b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        int len = (index >> OFFSET) + 1;
343f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (len > bits.length) {
344f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            growLength(len);
345f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
346b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        bits[len - 1] |= TWO_N_ARRAY[index & RIGHT_BITS];
347f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (len > actualArrayLength) {
348f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            actualArrayLength = len;
349f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            isLengthActual = true;
350f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
351f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        needClear();
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
355b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * Sets the bit at index {@code index} to {@code val}. Grows the
356b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * {@code BitSet} if {@code index > size}.
357f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
358b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * @param index
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the index of the bit to set.
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param val
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value to set the bit.
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
363b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     *             if {@code index} is negative.
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #set(int)
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
366b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    public void set(int index, boolean val) {
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (val) {
368b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            set(index);
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
370b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            clear(index);
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
375b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * Sets the bits starting from {@code fromIndex} to {@code toIndex}. Grows the
376b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * {@code BitSet} if {@code toIndex > size}.
377f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
378b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * @param fromIndex
379f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *            inclusive beginning position.
380b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * @param toIndex
381f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *            exclusive ending position.
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
383b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     *             if {@code fromIndex} or {@code toIndex} is negative, or if
384b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     *             {@code toIndex} is smaller than {@code fromIndex}.
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #set(int)
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
387b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    public void set(int fromIndex, int toIndex) {
388b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        checkRange(fromIndex, toIndex);
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
390b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        if (fromIndex == toIndex) {
391f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            return;
392f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
393b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        int len2 = ((toIndex - 1) >> OFFSET) + 1;
394f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (len2 > bits.length) {
395f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            growLength(len2);
396f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
398b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        int idx1 = fromIndex >> OFFSET;
399b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        int idx2 = (toIndex - 1) >> OFFSET;
400b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        long factor1 = (~0L) << (fromIndex & RIGHT_BITS);
401b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        long factor2 = (~0L) >>> (ELM_SIZE - (toIndex & RIGHT_BITS));
402f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
403f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (idx1 == idx2) {
404f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            bits[idx1] |= (factor1 & factor2);
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
406f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            bits[idx1] |= factor1;
407f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            bits[idx2] |= factor2;
408f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            for (int i = idx1 + 1; i < idx2; i++) {
409f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                bits[i] |= (~0L);
410f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
411f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
412f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (idx2 + 1 > actualArrayLength) {
413f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            actualArrayLength = idx2 + 1;
414f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            isLengthActual = true;
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
416f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        needClear();
417f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    }
418f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
419f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private void needClear() {
420f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        this.needClear = true;
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
424b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * Sets the bits starting from {@code fromIndex} to {@code toIndex} to the given
425b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * {@code val}. Grows the {@code BitSet} if {@code toIndex > size}.
426f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
427b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * @param fromIndex
428f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *            inclusive beginning position.
429b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * @param toIndex
430f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *            exclusive ending position.
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param val
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value to set these bits.
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
434b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     *             if {@code fromIndex} or {@code toIndex} is negative, or if
435b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     *             {@code toIndex} is smaller than {@code fromIndex}.
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #set(int,int)
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
438b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    public void set(int fromIndex, int toIndex, boolean val) {
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (val) {
440b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            set(fromIndex, toIndex);
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
442b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            clear(fromIndex, toIndex);
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Clears all the bits in this {@code BitSet}.
448f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #clear(int)
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #clear(int, int)
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void clear() {
453f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (needClear) {
454f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            for (int i = 0; i < bits.length; i++) {
455f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                bits[i] = 0L;
456f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
457f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            actualArrayLength = 0;
458f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            isLengthActual = true;
459f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            needClear = false;
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
464b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * Clears the bit at index {@code index}. Grows the {@code BitSet} if
465b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * {@code index > size}.
466f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
467b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * @param index
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the index of the bit to clear.
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
470b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     *             if {@code index} is negative.
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #clear(int, int)
472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
473b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    public void clear(int index) {
474b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        checkIndex(index);
475f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (!needClear) {
476f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            return;
477f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
478b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        int arrayPos = index >> OFFSET;
479f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (arrayPos < actualArrayLength) {
480b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            bits[arrayPos] &= ~(TWO_N_ARRAY[index & RIGHT_BITS]);
481f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            if (bits[actualArrayLength - 1] == 0) {
482f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                isLengthActual = false;
483f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
484f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
488b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * Clears the bits starting from {@code fromIndex} to {@code toIndex}. Grows the
489b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * {@code BitSet} if {@code toIndex > size}.
490f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
491b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * @param fromIndex
492f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *            inclusive beginning position.
493b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * @param toIndex
494f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *            exclusive ending position.
495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
496b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     *             if {@code fromIndex} or {@code toIndex} is negative, or if
497b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     *             {@code toIndex} is smaller than {@code fromIndex}.
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #clear(int)
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
500b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    public void clear(int fromIndex, int toIndex) {
501b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        checkRange(fromIndex, toIndex);
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
503f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (!needClear) {
504f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            return;
505f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
506f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        int last = (actualArrayLength << OFFSET);
507b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        if (fromIndex >= last || fromIndex == toIndex) {
508f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            return;
509f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
510b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        if (toIndex > last) {
511b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            toIndex = last;
512f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
514b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        int idx1 = fromIndex >> OFFSET;
515b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        int idx2 = (toIndex - 1) >> OFFSET;
516b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        long factor1 = (~0L) << (fromIndex & RIGHT_BITS);
517b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        long factor2 = (~0L) >>> (ELM_SIZE - (toIndex & RIGHT_BITS));
518f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
519f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (idx1 == idx2) {
520f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            bits[idx1] &= ~(factor1 & factor2);
521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
522f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            bits[idx1] &= ~factor1;
523f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            bits[idx2] &= ~factor2;
524f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            for (int i = idx1 + 1; i < idx2; i++) {
525f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                bits[i] = 0L;
526f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
527f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
528f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if ((actualArrayLength > 0) && (bits[actualArrayLength - 1] == 0)) {
529f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            isLengthActual = false;
530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
534b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * Flips the bit at index {@code index}. Grows the {@code BitSet} if
535b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * {@code index > size}.
536f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
537b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * @param index
538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the index of the bit to flip.
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
540b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     *             if {@code index} is negative.
541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #flip(int, int)
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
543b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    public void flip(int index) {
544b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        checkIndex(index);
545b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        int len = (index >> OFFSET) + 1;
546f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (len > bits.length) {
547f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            growLength(len);
548f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
549b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        bits[len - 1] ^= TWO_N_ARRAY[index & RIGHT_BITS];
550f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (len > actualArrayLength) {
551f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            actualArrayLength = len;
552f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
553f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        isLengthActual = !((actualArrayLength > 0) && (bits[actualArrayLength - 1] == 0));
554f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        needClear();
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
558b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * Flips the bits starting from {@code fromIndex} to {@code toIndex}. Grows the
559b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * {@code BitSet} if {@code toIndex > size}.
560f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
561b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * @param fromIndex
562f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *            inclusive beginning position.
563b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * @param toIndex
564f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *            exclusive ending position.
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
566b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     *             if {@code fromIndex} or {@code toIndex} is negative, or if
567b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     *             {@code toIndex} is smaller than {@code fromIndex}.
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #flip(int)
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
570b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    public void flip(int fromIndex, int toIndex) {
571b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        checkRange(fromIndex, toIndex);
572f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
573b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        if (fromIndex == toIndex) {
574f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            return;
575f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
576b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        int len2 = ((toIndex - 1) >> OFFSET) + 1;
577f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (len2 > bits.length) {
578f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            growLength(len2);
579f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
581b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        int idx1 = fromIndex >> OFFSET;
582b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        int idx2 = (toIndex - 1) >> OFFSET;
583b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        long factor1 = (~0L) << (fromIndex & RIGHT_BITS);
584b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        long factor2 = (~0L) >>> (ELM_SIZE - (toIndex & RIGHT_BITS));
585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
586f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (idx1 == idx2) {
587f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            bits[idx1] ^= (factor1 & factor2);
588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
589f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            bits[idx1] ^= factor1;
590f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            bits[idx2] ^= factor2;
591f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            for (int i = idx1 + 1; i < idx2; i++) {
592f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                bits[i] ^= (~0L);
593f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
595f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (len2 > actualArrayLength) {
596f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            actualArrayLength = len2;
597f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
598f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        isLengthActual = !((actualArrayLength > 0) && (bits[actualArrayLength - 1] == 0));
599f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        needClear();
600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Checks if these two {@code BitSet}s have at least one bit set to true in the same
604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * position.
605f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param bs
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@code BitSet} used to calculate the intersection.
608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if bs intersects with this {@code BitSet},
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean intersects(BitSet bs) {
612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long[] bsBits = bs.bits;
613f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        int length1 = actualArrayLength, length2 = bs.actualArrayLength;
614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (length1 <= length2) {
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = 0; i < length1; i++) {
617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if ((bits[i] & bsBits[i]) != 0L) {
618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return true;
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = 0; i < length2; i++) {
623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if ((bits[i] & bsBits[i]) != 0L) {
624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return true;
625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
633f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * Performs the logical AND of this {@code BitSet} with another
634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code BitSet}. The values of this {@code BitSet} are changed accordingly.
635f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param bs
637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@code BitSet} to AND with.
638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #or
639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #xor
640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void and(BitSet bs) {
642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long[] bsBits = bs.bits;
643f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (!needClear) {
644f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            return;
645f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
646f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        int length1 = actualArrayLength, length2 = bs.actualArrayLength;
647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (length1 <= length2) {
648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = 0; i < length1; i++) {
649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                bits[i] &= bsBits[i];
650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = 0; i < length2; i++) {
653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                bits[i] &= bsBits[i];
654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = length2; i < length1; i++) {
656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                bits[i] = 0;
657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
658f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            actualArrayLength = length2;
659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
660f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        isLengthActual = !((actualArrayLength > 0) && (bits[actualArrayLength - 1] == 0));
661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Clears all bits in the receiver which are also set in the parameter
665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code BitSet}. The values of this {@code BitSet} are changed accordingly.
666f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param bs
668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@code BitSet} to ANDNOT with.
669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void andNot(BitSet bs) {
671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long[] bsBits = bs.bits;
672f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (!needClear) {
673f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            return;
674f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
675f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        int range = actualArrayLength < bs.actualArrayLength ? actualArrayLength
676f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                : bs.actualArrayLength;
677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i = 0; i < range; i++) {
678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            bits[i] &= ~bsBits[i];
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
680f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
681f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (actualArrayLength < range) {
682f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            actualArrayLength = range;
683f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
684f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        isLengthActual = !((actualArrayLength > 0) && (bits[actualArrayLength - 1] == 0));
685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Performs the logical OR of this {@code BitSet} with another {@code BitSet}.
689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The values of this {@code BitSet} are changed accordingly.
690f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param bs
692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@code BitSet} to OR with.
693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #xor
694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #and
695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void or(BitSet bs) {
697f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        int bsActualLen = bs.getActualArrayLength();
698f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (bsActualLen > bits.length) {
699f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            long[] tempBits = new long[bsActualLen];
700f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            System.arraycopy(bs.bits, 0, tempBits, 0, bs.actualArrayLength);
701f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            for (int i = 0; i < actualArrayLength; i++) {
702f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                tempBits[i] |= bits[i];
703f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
704f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            bits = tempBits;
705f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            actualArrayLength = bsActualLen;
706f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            isLengthActual = true;
707f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        } else {
708f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            long[] bsBits = bs.bits;
709f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            for (int i = 0; i < bsActualLen; i++) {
710f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                bits[i] |= bsBits[i];
711f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
712f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            if (bsActualLen > actualArrayLength) {
713f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                actualArrayLength = bsActualLen;
714f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                isLengthActual = true;
715f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
717f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        needClear();
718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Performs the logical XOR of this {@code BitSet} with another {@code BitSet}.
722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The values of this {@code BitSet} are changed accordingly.
723f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param bs
725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@code BitSet} to XOR with.
726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #or
727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #and
728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void xor(BitSet bs) {
730f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        int bsActualLen = bs.getActualArrayLength();
731f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (bsActualLen > bits.length) {
732f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            long[] tempBits = new long[bsActualLen];
733f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            System.arraycopy(bs.bits, 0, tempBits, 0, bs.actualArrayLength);
734f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            for (int i = 0; i < actualArrayLength; i++) {
735f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                tempBits[i] ^= bits[i];
736f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
737f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            bits = tempBits;
738f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            actualArrayLength = bsActualLen;
739f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            isLengthActual = !((actualArrayLength > 0) && (bits[actualArrayLength - 1] == 0));
740f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        } else {
741f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            long[] bsBits = bs.bits;
742f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            for (int i = 0; i < bsActualLen; i++) {
743f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                bits[i] ^= bsBits[i];
744f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
745f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            if (bsActualLen > actualArrayLength) {
746f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                actualArrayLength = bsActualLen;
747f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                isLengthActual = true;
748f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
750f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        needClear();
751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the number of bits this {@code BitSet} has.
755f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of bits contained in this {@code BitSet}.
757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #length
758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int size() {
760f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        return bits.length << OFFSET;
761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the number of bits up to and including the highest bit set.
765f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the length of the {@code BitSet}.
767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int length() {
769f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        int idx = actualArrayLength - 1;
770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (idx >= 0 && bits[idx] == 0) {
771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            --idx;
772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
773f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        actualArrayLength = idx + 1;
774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (idx == -1) {
775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return 0;
776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int i = ELM_SIZE - 1;
778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long val = bits[idx];
779f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        while ((val & (TWO_N_ARRAY[i])) == 0 && i > 0) {
780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            i--;
781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
782f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        return (idx << OFFSET) + i + 1;
783f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    }
784f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
785f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private final int getActualArrayLength() {
786f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (isLengthActual) {
787f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            return actualArrayLength;
788f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
789f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        int idx = actualArrayLength - 1;
790f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        while (idx >= 0 && bits[idx] == 0) {
791f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            --idx;
792f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
793f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        actualArrayLength = idx + 1;
794f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        isLengthActual = true;
795f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        return actualArrayLength;
796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a string containing a concise, human-readable description of the
800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * receiver.
801f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a comma delimited list of the indices of all bits that are set.
803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
806a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        StringBuilder sb = new StringBuilder(bits.length / 2);
807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int bitCount = 0;
808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        sb.append('{');
809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean comma = false;
810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i = 0; i < bits.length; i++) {
811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (bits[i] == 0) {
812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                bitCount += ELM_SIZE;
813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                continue;
814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int j = 0; j < ELM_SIZE; j++) {
816f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                if (((bits[i] & (TWO_N_ARRAY[j])) != 0)) {
817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (comma) {
818f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                        sb.append(", ");
819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    sb.append(bitCount);
821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    comma = true;
822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                bitCount++;
824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        sb.append('}');
827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return sb.toString();
828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
831b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * Returns the position of the first bit that is {@code true} on or after {@code index}.
832f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
833b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * @param index
834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the starting position (inclusive).
835b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * @return -1 if there is no bits that are set to {@code true} on or after {@code index}.
836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
837b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    public int nextSetBit(int index) {
838b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        checkIndex(index);
839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
840b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        if (index >= actualArrayLength << OFFSET) {
841f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            return -1;
842f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
844b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        int idx = index >> OFFSET;
845f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // first check in the same bit set element
846f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (bits[idx] != 0L) {
847b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            for (int j = index & RIGHT_BITS; j < ELM_SIZE; j++) {
848f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                if (((bits[idx] & (TWO_N_ARRAY[j])) != 0)) {
849f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                    return (idx << OFFSET) + j;
850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
853f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
854f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        idx++;
855f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        while (idx < actualArrayLength && bits[idx] == 0L) {
856f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            idx++;
857f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
858f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (idx == actualArrayLength) {
859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return -1;
860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
861f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
862f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // we know for sure there is a bit set to true in this element
863f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // since the bitset value is not 0L
864f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        for (int j = 0; j < ELM_SIZE; j++) {
865f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            if (((bits[idx] & (TWO_N_ARRAY[j])) != 0)) {
866f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                return (idx << OFFSET) + j;
867f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
868f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
869f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
870f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        return -1;
871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
874b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * Returns the position of the first bit that is {@code false} on or after {@code index}.
875f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
876b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes     * @param index
877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the starting position (inclusive).
878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the position of the next bit set to {@code false}, even if it is further
879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         than this {@code BitSet}'s size.
880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
881b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    public int nextClearBit(int index) {
882b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        checkIndex(index);
883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
884f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        int length = actualArrayLength;
885f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        int bssize = length << OFFSET;
886b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        if (index >= bssize) {
887b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            return index;
888f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
890b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        int idx = index >> OFFSET;
891f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // first check in the same bit set element
892f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (bits[idx] != (~0L)) {
893b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            for (int j = index % ELM_SIZE; j < ELM_SIZE; j++) {
894f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                if (((bits[idx] & (TWO_N_ARRAY[j])) == 0)) {
895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return idx * ELM_SIZE + j;
896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
898f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
899f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        idx++;
900f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        while (idx < length && bits[idx] == (~0L)) {
901f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            idx++;
902f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
903f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (idx == length) {
904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return bssize;
905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
906f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
907f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // we know for sure there is a bit set to true in this element
908f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // since the bitset value is not 0L
909f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        for (int j = 0; j < ELM_SIZE; j++) {
910f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            if (((bits[idx] & (TWO_N_ARRAY[j])) == 0)) {
911f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                return (idx << OFFSET) + j;
912f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
913f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
914f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
915f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        return bssize;
916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns true if all the bits in this {@code BitSet} are set to false.
920f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the {@code BitSet} is empty,
922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isEmpty() {
925f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (!needClear) {
926f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            return true;
927f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
928f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        int length = bits.length;
929f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        for (int idx = 0; idx < length; idx++) {
930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (bits[idx] != 0L) {
931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return true;
935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the number of bits that are {@code true} in this {@code BitSet}.
939f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of {@code true} bits in the set.
941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int cardinality() {
943f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (!needClear) {
944f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            return 0;
945f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int count = 0;
947f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        int length = bits.length;
948f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // FIXME: need to test performance, if still not satisfied, change it to
949f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // 256-bits table based
950f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        for (int idx = 0; idx < length; idx++) {
951f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            count += pop(bits[idx] & 0xffffffffL);
952f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            count += pop(bits[idx] >>> 32);
953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return count;
955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
956f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
957f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private final int pop(long x) {
958f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // BEGIN android-note
959f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // delegate to Integer.bitCount(i); consider using native code
960f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        // END android-note
961f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        x = x - ((x >>> 1) & 0x55555555);
962f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        x = (x & 0x33333333) + ((x >>> 2) & 0x33333333);
963f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        x = (x + (x >>> 4)) & 0x0f0f0f0f;
964f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        x = x + (x >>> 8);
965f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        x = x + (x >>> 16);
966f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        return (int) x & 0x0000003f;
967f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    }
968f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
969f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private void readObject(ObjectInputStream ois) throws IOException,
970f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            ClassNotFoundException {
971f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        ois.defaultReadObject();
972f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        this.isLengthActual = false;
973f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        this.actualArrayLength = bits.length;
974f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        this.needClear = this.getActualArrayLength() != 0;
975f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    }
976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
977