1 |
// BitSet - A vector of bits. |
/* BitSet.java -- A vector of bits. |
2 |
|
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. |
|
/* Copyright (C) 1998, 1999, 2000 Free Software Foundation |
|
3 |
|
|
4 |
This file is part of GNU Classpath. |
This file is part of GNU Classpath. |
5 |
|
|
49 |
* while another thread is simultaneously modifying it, the results are |
* while another thread is simultaneously modifying it, the results are |
50 |
* undefined. |
* undefined. |
51 |
* |
* |
|
* @specnote Historically, there has been some confusion as to whether or not |
|
|
* this class should be synchronized. From an efficiency perspective, |
|
|
* it is very undesirable to synchronize it because multiple locks |
|
|
* and explicit lock ordering are required to safely synchronize some |
|
|
* methods. The JCL 1.2 supplement book specifies that as of JDK |
|
|
* 1.2, the class is no longer synchronized. |
|
|
* |
|
52 |
* @author Jochen Hoenicke |
* @author Jochen Hoenicke |
53 |
* @author Tom Tromey <tromey@cygnus.com> |
* @author Tom Tromey <tromey@cygnus.com> |
54 |
* @date October 23, 1998. |
* @author Eric Blake <ebb9@email.byu.edu> |
55 |
* @status API complete to JDK 1.3. |
* @status updated to 1.4 |
56 |
*/ |
*/ |
57 |
public class BitSet implements Cloneable, Serializable |
public class BitSet implements Cloneable, Serializable |
58 |
{ |
{ |
59 |
/** |
/** |
60 |
* Create a new empty bit set. |
* Compatible with JDK 1.0. |
61 |
|
*/ |
62 |
|
private static final long serialVersionUID = 7997698588986878753L; |
63 |
|
|
64 |
|
/** |
65 |
|
* A common mask. |
66 |
|
*/ |
67 |
|
private static final int LONG_MASK = 0x3f; |
68 |
|
|
69 |
|
/** |
70 |
|
* The actual bits. |
71 |
|
* @serial the i'th bit is in bits[i/64] at position i%64 (where position |
72 |
|
* 0 is the least significant). |
73 |
|
*/ |
74 |
|
private long[] bits; |
75 |
|
|
76 |
|
/** |
77 |
|
* Create a new empty bit set. All bits are initially false. |
78 |
*/ |
*/ |
79 |
public BitSet() |
public BitSet() |
80 |
{ |
{ |
84 |
/** |
/** |
85 |
* Create a new empty bit set, with a given size. This |
* Create a new empty bit set, with a given size. This |
86 |
* constructor reserves enough space to represent the integers |
* constructor reserves enough space to represent the integers |
87 |
* from <code>0</code> to <code>nbits-1</code>. |
* from <code>0</code> to <code>nbits-1</code>. |
88 |
* @param nbits the initial size of the bit set. |
* |
89 |
* @throws NegativeArraySizeException if the specified initial |
* @param nbits the initial size of the bit set |
90 |
* size is negative. |
* @throws NegativeArraySizeException if nbits < 0 |
|
* @require nbits >= 0 |
|
91 |
*/ |
*/ |
92 |
public BitSet(int nbits) |
public BitSet(int nbits) |
93 |
{ |
{ |
94 |
if (nbits < 0) |
int length = nbits >>> 6; |
95 |
throw new NegativeArraySizeException(); |
if ((nbits & LONG_MASK) != 0) |
|
int length = nbits / 64; |
|
|
if (nbits % 64 != 0) |
|
96 |
++length; |
++length; |
97 |
bits = new long[length]; |
bits = new long[length]; |
98 |
} |
} |
101 |
* Performs the logical AND operation on this bit set and the |
* Performs the logical AND operation on this bit set and the |
102 |
* given <code>set</code>. This means it builds the intersection |
* given <code>set</code>. This means it builds the intersection |
103 |
* of the two sets. The result is stored into this bit set. |
* of the two sets. The result is stored into this bit set. |
104 |
* @param set the second bit set. |
* |
105 |
* @require set != null |
* @param set the second bit set |
106 |
|
* @throws NullPointerException if set is null |
107 |
*/ |
*/ |
108 |
public void and(BitSet bs) |
public void and(BitSet bs) |
109 |
{ |
{ |
111 |
int i; |
int i; |
112 |
for (i = 0; i < max; ++i) |
for (i = 0; i < max; ++i) |
113 |
bits[i] &= bs.bits[i]; |
bits[i] &= bs.bits[i]; |
114 |
for (; i < bits.length; ++i) |
while (++i < bits.length) |
115 |
bits[i] = 0; |
bits[i] = 0; |
116 |
} |
} |
117 |
|
|
119 |
* Performs the logical AND operation on this bit set and the |
* Performs the logical AND operation on this bit set and the |
120 |
* complement of the given <code>set</code>. This means it |
* complement of the given <code>set</code>. This means it |
121 |
* selects every element in the first set, that isn't in the |
* selects every element in the first set, that isn't in the |
122 |
* second set. The result is stored into this bit set. |
* second set. The result is stored into this bit set. |
123 |
* @param set the second bit set. |
* |
124 |
* @require set != null |
* @param set the second bit set |
125 |
* @since JDK1.2 |
* @throws NullPointerException if set is null |
126 |
|
* @since 1.2 |
127 |
*/ |
*/ |
128 |
public void andNot(BitSet bs) |
public void andNot(BitSet bs) |
129 |
{ |
{ |
130 |
int max = Math.min(bits.length, bs.bits.length); |
int i = Math.min(bits.length, bs.bits.length); |
131 |
int i; |
while (--i > 0) |
|
for (i = 0; i < max; ++i) |
|
132 |
bits[i] &= ~bs.bits[i]; |
bits[i] &= ~bs.bits[i]; |
133 |
} |
} |
134 |
|
|
135 |
/** |
/** |
136 |
|
* Returns the number of bits set to true. |
137 |
|
* |
138 |
|
* @return the number of true bits |
139 |
|
* @since 1.4 |
140 |
|
*/ |
141 |
|
public int cardinality() |
142 |
|
{ |
143 |
|
int card = 0; |
144 |
|
for (int i = bits.length - 1; i >= 0; i--) |
145 |
|
{ |
146 |
|
long a = bits[i]; |
147 |
|
// Take care of common cases. |
148 |
|
if (a == 0) |
149 |
|
continue; |
150 |
|
if (a == -1) |
151 |
|
{ |
152 |
|
card += 64; |
153 |
|
continue; |
154 |
|
} |
155 |
|
|
156 |
|
// Successively collapse alternating bit groups into a sum. |
157 |
|
a = ((a >> 1) & 0x5555555555555555L) + (a & 0x5555555555555555L); |
158 |
|
a = ((a >> 2) & 0x3333333333333333L) + (a & 0x3333333333333333L); |
159 |
|
int b = (int) ((a >>> 32) + a); |
160 |
|
b = ((b >> 4) & 0x0f0f0f0f) + (b & 0x0f0f0f0f); |
161 |
|
b = ((b >> 8) & 0x00ff00ff) + (b & 0x00ff00ff); |
162 |
|
card += ((b >> 16) & 0x0000ffff) + (b & 0x0000ffff); |
163 |
|
} |
164 |
|
return card; |
165 |
|
} |
166 |
|
|
167 |
|
/** |
168 |
|
* Sets all bits in the set to false. |
169 |
|
* |
170 |
|
* @since 1.4 |
171 |
|
*/ |
172 |
|
public void clear() |
173 |
|
{ |
174 |
|
Arrays.fill(bits, 0); |
175 |
|
} |
176 |
|
|
177 |
|
/** |
178 |
* Removes the integer <code>bitIndex</code> from this set. That is |
* Removes the integer <code>bitIndex</code> from this set. That is |
179 |
* the corresponding bit is cleared. If the index is not in the set, |
* the corresponding bit is cleared. If the index is not in the set, |
180 |
* this method does nothing. |
* this method does nothing. |
181 |
* @param bitIndex a non-negative integer. |
* |
182 |
* @exception ArrayIndexOutOfBoundsException if the specified bit index |
* @param bitIndex a non-negative integer |
183 |
* is negative. |
* @throws IndexOutOfBoundsException if bitIndex < 0 |
|
* @require bitIndex >= 0 |
|
184 |
*/ |
*/ |
185 |
public void clear(int pos) |
public void clear(int pos) |
186 |
{ |
{ |
187 |
if (pos < 0) |
int offset = pos >>> 6; |
|
throw new IndexOutOfBoundsException(); |
|
|
int bit = pos % 64; |
|
|
int offset = pos / 64; |
|
188 |
ensure(offset); |
ensure(offset); |
189 |
bits[offset] &= ~(1L << bit); |
// ArrayIndexOutOfBoundsException subclasses IndexOutOfBoundsException, |
190 |
|
// so we'll just let that be our exception. |
191 |
|
bits[offset] &= ~(1L << pos); |
192 |
|
} |
193 |
|
|
194 |
|
/** |
195 |
|
* Sets the bits between from (inclusive) and to (exclusive) to false. |
196 |
|
* |
197 |
|
* @param from the start range (inclusive) |
198 |
|
* @param to the end range (exclusive) |
199 |
|
* @throws IndexOutOfBoundsException if from < 0 || from > to |
200 |
|
* @since 1.4 |
201 |
|
*/ |
202 |
|
public void clear(int from, int to) |
203 |
|
{ |
204 |
|
if (from < 0 || from > to) |
205 |
|
throw new IndexOutOfBoundsException(); |
206 |
|
if (from == to) |
207 |
|
return; |
208 |
|
int lo_offset = from >>> 6; |
209 |
|
int hi_offset = to >>> 6; |
210 |
|
ensure(hi_offset); |
211 |
|
if (lo_offset == hi_offset) |
212 |
|
{ |
213 |
|
bits[hi_offset] &= ((1L << from) - 1) | (-1L << to); |
214 |
|
return; |
215 |
|
} |
216 |
|
|
217 |
|
bits[lo_offset] &= (1L << from) - 1; |
218 |
|
bits[hi_offset] &= -1L << to; |
219 |
|
for (int i = lo_offset + 1; i < hi_offset; i++) |
220 |
|
bits[i] = 0; |
221 |
} |
} |
222 |
|
|
223 |
/** |
/** |
224 |
* Create a clone of this bit set, that is an instance of the same |
* Create a clone of this bit set, that is an instance of the same |
225 |
* class and contains the same elements. But it doesn't change when |
* class and contains the same elements. But it doesn't change when |
226 |
* this bit set changes. |
* this bit set changes. |
227 |
|
* |
228 |
* @return the clone of this object. |
* @return the clone of this object. |
229 |
*/ |
*/ |
230 |
public Object clone() |
public Object clone() |
231 |
{ |
{ |
232 |
BitSet bs = new BitSet(bits.length * 64); |
try |
233 |
System.arraycopy(bits, 0, bs.bits, 0, bits.length); |
{ |
234 |
return bs; |
BitSet bs = (BitSet) super.clone(); |
235 |
|
bs.bits = (long[]) bits.clone(); |
236 |
|
return bs; |
237 |
|
} |
238 |
|
catch (CloneNotSupportedException e) |
239 |
|
{ |
240 |
|
// Impossible to get here. |
241 |
|
return null; |
242 |
|
} |
243 |
} |
} |
244 |
|
|
245 |
/** |
/** |
246 |
* Returns true if the <code>obj</code> is a bit set that contains |
* Returns true if the <code>obj</code> is a bit set that contains |
247 |
* exactly the same elements as this bit set, otherwise false. |
* exactly the same elements as this bit set, otherwise false. |
248 |
* @return true if obj equals this bit set. |
* |
249 |
|
* @param obj the object to compare to |
250 |
|
* @return true if obj equals this bit set |
251 |
*/ |
*/ |
252 |
public boolean equals(Object obj) |
public boolean equals(Object obj) |
253 |
{ |
{ |
258 |
int i; |
int i; |
259 |
for (i = 0; i < max; ++i) |
for (i = 0; i < max; ++i) |
260 |
if (bits[i] != bs.bits[i]) |
if (bits[i] != bs.bits[i]) |
261 |
return false; |
return false; |
262 |
// If one is larger, check to make sure all extra bits are 0. |
// If one is larger, check to make sure all extra bits are 0. |
263 |
for (int j = i; j < bits.length; ++j) |
for (int j = i; j < bits.length; ++j) |
264 |
if (bits[j] != 0) |
if (bits[j] != 0) |
265 |
return false; |
return false; |
266 |
for (int j = i; j < bs.bits.length; ++j) |
for (int j = i; j < bs.bits.length; ++j) |
267 |
if (bs.bits[j] != 0) |
if (bs.bits[j] != 0) |
268 |
return false; |
return false; |
269 |
return true; |
return true; |
270 |
} |
} |
271 |
|
|
272 |
/** |
/** |
273 |
* Returns true if the integer <code>bitIndex</code> is in this bit |
* Sets the bit at the index to the opposite value. |
274 |
* set, otherwise false. |
* |
275 |
* @param bitIndex a non-negative integer |
* @param index the index of the bit |
276 |
* @return the value of the bit at the specified index. |
* @throws IndexOutOfBoundsException if index is negative |
277 |
* @exception ArrayIndexOutOfBoundsException if the specified bit index |
* @since 1.4 |
|
* is negative. |
|
|
* @require bitIndex >= 0 |
|
278 |
*/ |
*/ |
279 |
public boolean get(int pos) |
public void flip(int index) |
280 |
{ |
{ |
281 |
if (pos < 0) |
int offset = index >>> 6; |
282 |
|
ensure(offset); |
283 |
|
// ArrayIndexOutOfBoundsException subclasses IndexOutOfBoundsException, |
284 |
|
// so we'll just let that be our exception. |
285 |
|
bits[offset] ^= 1L << index; |
286 |
|
} |
287 |
|
|
288 |
|
/** |
289 |
|
* Sets a range of bits to the opposite value. |
290 |
|
* |
291 |
|
* @param from the low index (inclusive) |
292 |
|
* @param to the high index (exclusive) |
293 |
|
* @throws IndexOutOfBoundsException if from > to || from < 0 |
294 |
|
* @since 1.4 |
295 |
|
*/ |
296 |
|
public void flip(int from, int to) |
297 |
|
{ |
298 |
|
if (from < 0 || from > to) |
299 |
throw new IndexOutOfBoundsException(); |
throw new IndexOutOfBoundsException(); |
300 |
|
if (from == to) |
301 |
|
return; |
302 |
|
int lo_offset = from >>> 6; |
303 |
|
int hi_offset = to >>> 6; |
304 |
|
ensure(hi_offset); |
305 |
|
if (lo_offset == hi_offset) |
306 |
|
{ |
307 |
|
bits[hi_offset] ^= (-1L << from) & ((1L << to) - 1); |
308 |
|
return; |
309 |
|
} |
310 |
|
|
311 |
int bit = pos % 64; |
bits[lo_offset] ^= -1L << from; |
312 |
int offset = pos / 64; |
bits[hi_offset] ^= (1L << to) - 1; |
313 |
|
for (int i = lo_offset + 1; i < hi_offset; i++) |
314 |
|
bits[i] ^= -1; |
315 |
|
} |
316 |
|
|
317 |
|
/** |
318 |
|
* Returns true if the integer <code>bitIndex</code> is in this bit |
319 |
|
* set, otherwise false. |
320 |
|
* |
321 |
|
* @param pos a non-negative integer |
322 |
|
* @return the value of the bit at the specified index |
323 |
|
* @throws IndexOutOfBoundsException if the index is negative |
324 |
|
*/ |
325 |
|
public boolean get(int pos) |
326 |
|
{ |
327 |
|
int offset = pos >>> 6; |
328 |
if (offset >= bits.length) |
if (offset >= bits.length) |
329 |
return false; |
return false; |
330 |
|
// ArrayIndexOutOfBoundsException subclasses IndexOutOfBoundsException, |
331 |
|
// so we'll just let that be our exception. |
332 |
|
return (bits[offset] & (1L << pos)) != 0; |
333 |
|
} |
334 |
|
|
335 |
|
/** |
336 |
|
* Returns a new <code>BitSet</code> composed of a range of bits from |
337 |
|
* this one. |
338 |
|
* |
339 |
|
* @param from the low index (inclusive) |
340 |
|
* @param to the high index (exclusive) |
341 |
|
* @throws IndexOutOfBoundsException if from > to || from < 0 |
342 |
|
* @since 1.4 |
343 |
|
*/ |
344 |
|
public BitSet get(int from, int to) |
345 |
|
{ |
346 |
|
if (from < 0 || from > to) |
347 |
|
throw new IndexOutOfBoundsException(); |
348 |
|
BitSet bs = new BitSet(to - from); |
349 |
|
int lo_offset = from >>> 6; |
350 |
|
if (lo_offset >= bits.length) |
351 |
|
return bs; |
352 |
|
|
353 |
|
int lo_bit = from & LONG_MASK; |
354 |
|
int hi_offset = to >>> 6; |
355 |
|
if (lo_bit == 0) |
356 |
|
{ |
357 |
|
int len = Math.min(hi_offset - lo_offset + 1, bits.length - lo_offset); |
358 |
|
System.arraycopy(bits, lo_offset, bs.bits, 0, len); |
359 |
|
if (hi_offset < bits.length) |
360 |
|
bs.bits[hi_offset - lo_offset] &= (1L << to) - 1; |
361 |
|
return bs; |
362 |
|
} |
363 |
|
|
364 |
return (bits[offset] & (1L << bit)) == 0 ? false : true; |
int len = Math.min(hi_offset, bits.length - 1); |
365 |
|
int reverse = ~lo_bit; |
366 |
|
int i; |
367 |
|
for (i = 0; lo_offset < len; lo_offset++, i++) |
368 |
|
bs.bits[i] = ((bits[lo_offset] >>> lo_bit) |
369 |
|
| (bits[lo_offset + 1] << reverse)); |
370 |
|
if ((to & LONG_MASK) > lo_bit) |
371 |
|
bs.bits[i++] = bits[lo_offset] >>> lo_bit; |
372 |
|
if (hi_offset < bits.length) |
373 |
|
bs.bits[i - 1] &= (1L << (to - from)) - 1; |
374 |
|
return bs; |
375 |
} |
} |
376 |
|
|
377 |
/** |
/** |
378 |
* Returns a hash code value for this bit set. The hash code of |
* Returns a hash code value for this bit set. The hash code of |
379 |
* two bit sets containing the same integers is identical. The algorithm |
* two bit sets containing the same integers is identical. The algorithm |
380 |
* used to compute it is as follows: |
* used to compute it is as follows: |
381 |
* |
* |
402 |
* </pre> |
* </pre> |
403 |
* |
* |
404 |
* Note that the hash code values changes, if the set is changed. |
* Note that the hash code values changes, if the set is changed. |
405 |
|
* |
406 |
* @return the hash code value for this bit set. |
* @return the hash code value for this bit set. |
407 |
*/ |
*/ |
408 |
public int hashCode() |
public int hashCode() |
409 |
{ |
{ |
410 |
long h = 1234; |
long h = 1234; |
411 |
for (int i = bits.length - 1; i >= 0; --i) |
for (int i = bits.length; i > 0; ) |
412 |
h ^= bits[i] * (i + 1); |
h ^= i * bits[--i]; |
413 |
return (int) ((h >> 32) ^ h); |
return (int) ((h >> 32) ^ h); |
414 |
} |
} |
415 |
|
|
416 |
/** |
/** |
417 |
|
* Returns true if the specified BitSet and this one share at least one |
418 |
|
* common true bit. |
419 |
|
* |
420 |
|
* @param set the set to check for intersection |
421 |
|
* @return true if the sets intersect |
422 |
|
* @throws NullPointerException if set is null |
423 |
|
* @since 1.4 |
424 |
|
*/ |
425 |
|
public boolean intersects(BitSet set) |
426 |
|
{ |
427 |
|
int i = Math.min(bits.length, set.bits.length); |
428 |
|
while (--i >= 0) |
429 |
|
if ((bits[i] & set.bits[i]) != 0) |
430 |
|
return true; |
431 |
|
return false; |
432 |
|
} |
433 |
|
|
434 |
|
/** |
435 |
|
* Returns true if this set contains no true bits. |
436 |
|
* |
437 |
|
* @return true if all bits are false |
438 |
|
* @since 1.4 |
439 |
|
*/ |
440 |
|
public boolean isEmpty() |
441 |
|
{ |
442 |
|
for (int i = bits.length - 1; i >= 0; i--) |
443 |
|
if (bits[i] != 0) |
444 |
|
return false; |
445 |
|
return true; |
446 |
|
} |
447 |
|
|
448 |
|
/** |
449 |
* Returns the logical number of bits actually used by this bit |
* Returns the logical number of bits actually used by this bit |
450 |
* set. It returns the index of the highest set bit plus one. |
* set. It returns the index of the highest set bit plus one. |
451 |
* Note that this method doesn't return the number of set bits. |
* Note that this method doesn't return the number of set bits. |
452 |
* @return the index of the highest set bit plus one. |
* |
453 |
|
* @return the index of the highest set bit plus one. |
454 |
*/ |
*/ |
455 |
public int length() |
public int length() |
456 |
{ |
{ |
469 |
// b >= 0 checks if the highest bit is zero. |
// b >= 0 checks if the highest bit is zero. |
470 |
while (b >= 0) |
while (b >= 0) |
471 |
{ |
{ |
472 |
--len; |
--len; |
473 |
b <<= 1; |
b <<= 1; |
474 |
} |
} |
475 |
|
|
476 |
return len; |
return len; |
477 |
} |
} |
478 |
|
|
479 |
/** |
/** |
480 |
|
* Returns the index of the next false bit, from the specified bit |
481 |
|
* (inclusive). |
482 |
|
* |
483 |
|
* @param from the start location |
484 |
|
* @return the first false bit |
485 |
|
* @throws IndexOutOfBoundsException if from is negative |
486 |
|
* @since 1.4 |
487 |
|
*/ |
488 |
|
public int nextClearBit(int from) |
489 |
|
{ |
490 |
|
int offset = from >>> 6; |
491 |
|
long mask = 1L << from; |
492 |
|
while (offset < bits.length) |
493 |
|
{ |
494 |
|
// ArrayIndexOutOfBoundsException subclasses IndexOutOfBoundsException, |
495 |
|
// so we'll just let that be our exception. |
496 |
|
long h = bits[offset]; |
497 |
|
do |
498 |
|
{ |
499 |
|
if ((h & mask) == 0) |
500 |
|
return from; |
501 |
|
mask <<= 1; |
502 |
|
from++; |
503 |
|
} |
504 |
|
while (mask != 0); |
505 |
|
mask = 1; |
506 |
|
offset++; |
507 |
|
} |
508 |
|
return from; |
509 |
|
} |
510 |
|
|
511 |
|
/** |
512 |
|
* Returns the index of the next true bit, from the specified bit |
513 |
|
* (inclusive). If there is none, -1 is returned. You can iterate over |
514 |
|
* all true bits with this loop:<br> |
515 |
|
* <pre> |
516 |
|
* for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) |
517 |
|
* { // operate on i here } |
518 |
|
* </pre> |
519 |
|
* |
520 |
|
* @param from the start location |
521 |
|
* @return the first true bit, or -1 |
522 |
|
* @throws IndexOutOfBoundsException if from is negative |
523 |
|
* @since 1.4 |
524 |
|
*/ |
525 |
|
public int nextSetBit(int from) |
526 |
|
{ |
527 |
|
int offset = from >>> 6; |
528 |
|
long mask = 1L << from; |
529 |
|
while (offset < bits.length) |
530 |
|
{ |
531 |
|
// ArrayIndexOutOfBoundsException subclasses IndexOutOfBoundsException, |
532 |
|
// so we'll just let that be our exception. |
533 |
|
long h = bits[offset]; |
534 |
|
do |
535 |
|
{ |
536 |
|
if ((h & mask) != 0) |
537 |
|
return from; |
538 |
|
mask <<= 1; |
539 |
|
from++; |
540 |
|
} |
541 |
|
while (mask != 0); |
542 |
|
mask = 1; |
543 |
|
offset++; |
544 |
|
} |
545 |
|
return -1; |
546 |
|
} |
547 |
|
|
548 |
|
/** |
549 |
* Performs the logical OR operation on this bit set and the |
* Performs the logical OR operation on this bit set and the |
550 |
* given <code>set</code>. This means it builds the union |
* given <code>set</code>. This means it builds the union |
551 |
* of the two sets. The result is stored into this bit set, which |
* of the two sets. The result is stored into this bit set, which |
552 |
* grows as necessary. |
* grows as necessary. |
553 |
* @param set the second bit set. |
* |
554 |
* @exception OutOfMemoryError if the current set can't grow. |
* @param bs the second bit set |
555 |
* @require set != null |
* @throws NullPointerException if bs is null |
556 |
*/ |
*/ |
557 |
public void or(BitSet bs) |
public void or(BitSet bs) |
558 |
{ |
{ |
559 |
ensure(bs.bits.length - 1); |
ensure(bs.bits.length - 1); |
560 |
int i; |
for (int i = bs.bits.length - 1; i >= 0; i--) |
|
for (i = 0; i < bs.bits.length; ++i) |
|
561 |
bits[i] |= bs.bits[i]; |
bits[i] |= bs.bits[i]; |
562 |
} |
} |
563 |
|
|
564 |
/** |
/** |
565 |
* Add the integer <code>bitIndex</code> to this set. That is |
* Add the integer <code>bitIndex</code> to this set. That is |
566 |
* the corresponding bit is set to true. If the index was already in |
* the corresponding bit is set to true. If the index was already in |
567 |
* the set, this method does nothing. The size of this structure |
* the set, this method does nothing. The size of this structure |
568 |
* is automatically increased as necessary. |
* is automatically increased as necessary. |
569 |
* @param bitIndex a non-negative integer. |
* |
570 |
* @exception ArrayIndexOutOfBoundsException if the specified bit index |
* @param pos a non-negative integer. |
571 |
* is negative. |
* @throws IndexOutOfBoundsException if pos is negative |
|
* @require bitIndex >= 0 |
|
572 |
*/ |
*/ |
573 |
public void set(int pos) |
public void set(int pos) |
574 |
{ |
{ |
575 |
if (pos < 0) |
int offset = pos >>> 6; |
|
throw new IndexOutOfBoundsException(); |
|
|
int bit = pos % 64; |
|
|
int offset = pos / 64; |
|
576 |
ensure(offset); |
ensure(offset); |
577 |
bits[offset] |= 1L << bit; |
// ArrayIndexOutOfBoundsException subclasses IndexOutOfBoundsException, |
578 |
|
// so we'll just let that be our exception. |
579 |
|
bits[offset] |= 1L << pos; |
580 |
|
} |
581 |
|
|
582 |
|
/** |
583 |
|
* Sets the bit at the given index to the specified value. The size of |
584 |
|
* this structure is automatically increased as necessary. |
585 |
|
* |
586 |
|
* @param index the position to set |
587 |
|
* @param value the value to set it to |
588 |
|
* @throws IndexOutOfBoundsException if index is negative |
589 |
|
* @since 1.4 |
590 |
|
*/ |
591 |
|
public void set(int index, boolean value) |
592 |
|
{ |
593 |
|
// Too bad you can't use ?: with void statements! |
594 |
|
if (value) |
595 |
|
set(index); |
596 |
|
else |
597 |
|
clear(index); |
598 |
|
} |
599 |
|
|
600 |
|
/** |
601 |
|
* Sets the bits between from (inclusive) and to (exclusive) to true. |
602 |
|
* |
603 |
|
* @param from the start range (inclusive) |
604 |
|
* @param to the end range (exclusive) |
605 |
|
* @throws IndexOutOfBoundsException if from < 0 || from > to |
606 |
|
* @since 1.4 |
607 |
|
*/ |
608 |
|
public void set(int from, int to) |
609 |
|
{ |
610 |
|
if (from < 0 || from > to) |
611 |
|
throw new IndexOutOfBoundsException(); |
612 |
|
if (from == to) |
613 |
|
return; |
614 |
|
int lo_offset = from >>> 6; |
615 |
|
int hi_offset = to >>> 6; |
616 |
|
ensure(hi_offset); |
617 |
|
if (lo_offset == hi_offset) |
618 |
|
{ |
619 |
|
bits[hi_offset] |= (-1L << from) & ((1L << to) - 1); |
620 |
|
return; |
621 |
|
} |
622 |
|
|
623 |
|
bits[lo_offset] |= -1L << from; |
624 |
|
bits[hi_offset] |= (1L << to) - 1; |
625 |
|
for (int i = lo_offset + 1; i < hi_offset; i++) |
626 |
|
bits[i] = -1; |
627 |
|
} |
628 |
|
|
629 |
|
/** |
630 |
|
* Sets the bits between from (inclusive) and to (exclusive) to the |
631 |
|
* specified value. |
632 |
|
* |
633 |
|
* @param from the start range (inclusive) |
634 |
|
* @param to the end range (exclusive) |
635 |
|
* @param value the value to set it to |
636 |
|
* @throws IndexOutOfBoundsException if from < 0 || from > to |
637 |
|
* @since 1.4 |
638 |
|
*/ |
639 |
|
public void set(int from, int to, boolean value) |
640 |
|
{ |
641 |
|
// Too bad you can't use ?: with void statements! |
642 |
|
if (value) |
643 |
|
set(from, to); |
644 |
|
else |
645 |
|
clear(from, to); |
646 |
} |
} |
647 |
|
|
648 |
/** |
/** |
649 |
* Returns the number of bits actually used by this bit set. Note |
* Returns the number of bits actually used by this bit set. Note |
650 |
* that this method doesn't return the number of set bits. |
* that this method doesn't return the number of set bits, and that |
651 |
* @returns the number of bits currently used. |
* future requests for larger bits will make this automatically grow. |
652 |
|
* |
653 |
|
* @return the number of bits currently used. |
654 |
*/ |
*/ |
655 |
public int size() |
public int size() |
656 |
{ |
{ |
661 |
* Returns the string representation of this bit set. This |
* Returns the string representation of this bit set. This |
662 |
* consists of a comma separated list of the integers in this set |
* consists of a comma separated list of the integers in this set |
663 |
* surrounded by curly braces. There is a space after each comma. |
* surrounded by curly braces. There is a space after each comma. |
664 |
|
* A sample string is thus "{1, 3, 53}". |
665 |
* @return the string representation. |
* @return the string representation. |
666 |
*/ |
*/ |
667 |
public String toString() |
public String toString() |
668 |
{ |
{ |
669 |
String r = "{"; |
StringBuffer r = new StringBuffer("{"); |
670 |
boolean first = true; |
boolean first = true; |
671 |
for (int i = 0; i < bits.length; ++i) |
for (int i = 0; i < bits.length; ++i) |
672 |
{ |
{ |
673 |
long bit = 1; |
long bit = 1; |
674 |
long word = bits[i]; |
long word = bits[i]; |
675 |
if (word == 0) |
if (word == 0) |
676 |
continue; |
continue; |
677 |
for (int j = 0; j < 64; ++j) |
for (int j = 0; j < 64; ++j) |
678 |
{ |
{ |
679 |
if ((word & bit) != 0) |
if ((word & bit) != 0) |
680 |
{ |
{ |
681 |
if (!first) |
if (! first) |
682 |
r += ", "; |
r.append(", "); |
683 |
r += Integer.toString(64 * i + j); |
r.append(64 * i + j); |
684 |
first = false; |
first = false; |
685 |
} |
} |
686 |
bit <<= 1; |
bit <<= 1; |
687 |
} |
} |
688 |
} |
} |
689 |
|
return r.append("}").toString(); |
|
return r += "}"; |
|
690 |
} |
} |
691 |
|
|
692 |
/** |
/** |
694 |
* given <code>set</code>. This means it builds the symmetric |
* given <code>set</code>. This means it builds the symmetric |
695 |
* remainder of the two sets (the elements that are in one set, |
* remainder of the two sets (the elements that are in one set, |
696 |
* but not in the other). The result is stored into this bit set, |
* but not in the other). The result is stored into this bit set, |
697 |
* which grows as necessary. |
* which grows as necessary. |
698 |
* @param set the second bit set. |
* |
699 |
* @exception OutOfMemoryError if the current set can't grow. |
* @param bs the second bit set |
700 |
* @require set != null |
* @throws NullPointerException if bs is null |
701 |
*/ |
*/ |
702 |
public void xor(BitSet bs) |
public void xor(BitSet bs) |
703 |
{ |
{ |
704 |
ensure(bs.bits.length - 1); |
ensure(bs.bits.length - 1); |
705 |
int i; |
for (int i = bs.bits.length - 1; i > 0; i--) |
|
for (i = 0; i < bs.bits.length; ++i) |
|
706 |
bits[i] ^= bs.bits[i]; |
bits[i] ^= bs.bits[i]; |
707 |
} |
} |
708 |
|
|
709 |
// Make sure the vector is big enough. |
/** |
710 |
|
* Make sure the vector is big enough. |
711 |
|
* |
712 |
|
* @param lastElt the size needed for the bits array |
713 |
|
*/ |
714 |
private final void ensure(int lastElt) |
private final void ensure(int lastElt) |
715 |
{ |
{ |
716 |
if (lastElt + 1 > bits.length) |
if (lastElt >= bits.length) |
717 |
{ |
{ |
718 |
long[] nd = new long[lastElt + 1]; |
long[] nd = new long[lastElt + 1]; |
719 |
System.arraycopy(bits, 0, nd, 0, bits.length); |
System.arraycopy(bits, 0, nd, 0, bits.length); |
720 |
bits = nd; |
bits = nd; |
721 |
} |
} |
722 |
} |
} |
|
|
|
|
// The actual bits. |
|
|
long[] bits; |
|
|
|
|
|
private static final long serialVersionUID = 7997698588986878753L; |
|
723 |
} |
} |