2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 package org.apache.lucene.util;
20 import java.io.IOException;
21 import java.util.BitSet;
23 import org.apache.lucene.search.DocIdSetIterator;
25 public class TestFixedBitSet extends LuceneTestCase {
27 void doGet(BitSet a, FixedBitSet b) {
29 for (int i=0; i<max; i++) {
30 if (a.get(i) != b.get(i)) {
31 fail("mismatch: BitSet=["+i+"]="+a.get(i));
36 void doNextSetBit(BitSet a, FixedBitSet b) {
39 aa = a.nextSetBit(aa+1);
40 bb = bb < b.length()-1 ? b.nextSetBit(bb+1) : -1;
45 void doPrevSetBit(BitSet a, FixedBitSet b) {
46 int aa = a.size() + random.nextInt(100);
49 // aa = a.prevSetBit(aa-1);
51 while ((aa >= 0) && (! a.get(aa))) {
54 if (b.length() == 0) {
56 } else if (bb > b.length()-1) {
57 bb = b.prevSetBit(b.length()-1);
61 bb = bb >= 1 ? b.prevSetBit(bb-1) : -1;
67 // test interleaving different FixedBitSetIterator.next()/skipTo()
68 void doIterate(BitSet a, FixedBitSet b, int mode) throws IOException {
69 if (mode==1) doIterate1(a, b);
70 if (mode==2) doIterate2(a, b);
73 void doIterate1(BitSet a, FixedBitSet b) throws IOException {
75 DocIdSetIterator iterator = b.iterator();
77 aa = a.nextSetBit(aa+1);
78 bb = (bb < b.length() && random.nextBoolean()) ? iterator.nextDoc() : iterator.advance(bb + 1);
79 assertEquals(aa == -1 ? DocIdSetIterator.NO_MORE_DOCS : aa, bb);
83 void doIterate2(BitSet a, FixedBitSet b) throws IOException {
85 DocIdSetIterator iterator = b.iterator();
87 aa = a.nextSetBit(aa+1);
88 bb = random.nextBoolean() ? iterator.nextDoc() : iterator.advance(bb + 1);
89 assertEquals(aa == -1 ? DocIdSetIterator.NO_MORE_DOCS : aa, bb);
93 void doRandomSets(int maxSize, int iter, int mode) throws IOException {
97 for (int i=0; i<iter; i++) {
98 int sz = _TestUtil.nextInt(random, 2, maxSize);
99 BitSet a = new BitSet(sz);
100 FixedBitSet b = new FixedBitSet(sz);
102 // test the various ways of setting bits
104 int nOper = random.nextInt(sz);
105 for (int j=0; j<nOper; j++) {
108 idx = random.nextInt(sz);
112 idx = random.nextInt(sz);
116 idx = random.nextInt(sz);
120 idx = random.nextInt(sz);
124 boolean val2 = b.get(idx);
125 boolean val = b.getAndSet(idx);
126 assertTrue(val2 == val);
127 assertTrue(b.get(idx));
129 if (!val) b.clear(idx);
130 assertTrue(b.get(idx) == val);
134 // test that the various ways of accessing the bits are equivalent
137 // test ranges, including possible extension
138 int fromIndex, toIndex;
139 fromIndex = random.nextInt(sz/2);
140 toIndex = fromIndex + random.nextInt(sz - fromIndex);
141 BitSet aa = (BitSet)a.clone(); aa.flip(fromIndex,toIndex);
142 FixedBitSet bb = (FixedBitSet)b.clone(); bb.flip(fromIndex,toIndex);
144 doIterate(aa,bb, mode); // a problem here is from flip or doIterate
146 fromIndex = random.nextInt(sz/2);
147 toIndex = fromIndex + random.nextInt(sz - fromIndex);
148 aa = (BitSet)a.clone(); aa.clear(fromIndex,toIndex);
149 bb = (FixedBitSet)b.clone(); bb.clear(fromIndex,toIndex);
151 doNextSetBit(aa,bb); // a problem here is from clear() or nextSetBit
155 fromIndex = random.nextInt(sz/2);
156 toIndex = fromIndex + random.nextInt(sz - fromIndex);
157 aa = (BitSet)a.clone(); aa.set(fromIndex,toIndex);
158 bb = (FixedBitSet)b.clone(); bb.set(fromIndex,toIndex);
160 doNextSetBit(aa,bb); // a problem here is from set() or nextSetBit
164 if (b0 != null && b0.length() <= b.length()) {
165 assertEquals(a.cardinality(), b.cardinality());
167 BitSet a_and = (BitSet)a.clone(); a_and.and(a0);
168 BitSet a_or = (BitSet)a.clone(); a_or.or(a0);
169 BitSet a_andn = (BitSet)a.clone(); a_andn.andNot(a0);
171 FixedBitSet b_and = (FixedBitSet)b.clone(); assertEquals(b,b_and); b_and.and(b0);
172 FixedBitSet b_or = (FixedBitSet)b.clone(); b_or.or(b0);
173 FixedBitSet b_andn = (FixedBitSet)b.clone(); b_andn.andNot(b0);
175 assertEquals(a0.cardinality(), b0.cardinality());
176 assertEquals(a_or.cardinality(), b_or.cardinality());
178 doIterate(a_and,b_and, mode);
179 doIterate(a_or,b_or, mode);
180 doIterate(a_andn,b_andn, mode);
182 assertEquals(a_and.cardinality(), b_and.cardinality());
183 assertEquals(a_or.cardinality(), b_or.cardinality());
184 assertEquals(a_andn.cardinality(), b_andn.cardinality());
192 // large enough to flush obvious bugs, small enough to run in <.5 sec as part of a
194 public void testSmall() throws IOException {
195 doRandomSets(atLeast(1200), atLeast(1000), 1);
196 doRandomSets(atLeast(1200), atLeast(1000), 2);
199 // uncomment to run a bigger test (~2 minutes).
201 public void testBig() {
202 doRandomSets(2000,200000, 1);
203 doRandomSets(2000,200000, 2);
207 public void testEquals() {
208 // This test can't handle numBits==0:
209 final int numBits = random.nextInt(2000) + 1;
210 FixedBitSet b1 = new FixedBitSet(numBits);
211 FixedBitSet b2 = new FixedBitSet(numBits);
212 assertTrue(b1.equals(b2));
213 assertTrue(b2.equals(b1));
214 for(int iter=0;iter<10*RANDOM_MULTIPLIER;iter++) {
215 int idx = random.nextInt(numBits);
218 assertFalse(b1.equals(b2));
219 assertFalse(b2.equals(b1));
221 assertTrue(b1.equals(b2));
222 assertTrue(b2.equals(b1));
226 // try different type of object
227 assertFalse(b1.equals(new Object()));
230 public void testHashCodeEquals() {
231 // This test can't handle numBits==0:
232 final int numBits = random.nextInt(2000) + 1;
233 FixedBitSet b1 = new FixedBitSet(numBits);
234 FixedBitSet b2 = new FixedBitSet(numBits);
235 assertTrue(b1.equals(b2));
236 assertTrue(b2.equals(b1));
237 for(int iter=0;iter<10*RANDOM_MULTIPLIER;iter++) {
238 int idx = random.nextInt(numBits);
241 assertFalse(b1.equals(b2));
242 assertFalse(b1.hashCode() == b2.hashCode());
244 assertEquals(b1, b2);
245 assertEquals(b1.hashCode(), b2.hashCode());
250 public void testSmallBitSets() {
251 // Make sure size 0-10 bit sets are OK:
252 for(int numBits=0;numBits<10;numBits++) {
253 FixedBitSet b1 = new FixedBitSet(numBits);
254 FixedBitSet b2 = new FixedBitSet(numBits);
255 assertTrue(b1.equals(b2));
256 assertEquals(b1.hashCode(), b2.hashCode());
257 assertEquals(0, b1.cardinality());
260 assertEquals(numBits, b1.cardinality());
262 assertEquals(0, b1.cardinality());
267 private FixedBitSet makeFixedBitSet(int[] a, int numBits) {
268 FixedBitSet bs = new FixedBitSet(numBits);
275 private BitSet makeBitSet(int[] a) {
276 BitSet bs = new BitSet();
283 private void checkPrevSetBitArray(int [] a, int numBits) {
284 FixedBitSet obs = makeFixedBitSet(a, numBits);
285 BitSet bs = makeBitSet(a);
286 doPrevSetBit(bs, obs);
289 public void testPrevSetBit() {
290 checkPrevSetBitArray(new int[] {}, 0);
291 checkPrevSetBitArray(new int[] {0}, 1);
292 checkPrevSetBitArray(new int[] {0,2}, 3);