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 > 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