1 7 8 package java.util; 9 10 import java.io.*; 11 12 42 public class BitSet implements Cloneable , java.io.Serializable { 43 48 private final static int ADDRESS_BITS_PER_UNIT = 6; 49 private final static int BITS_PER_UNIT = 1 << ADDRESS_BITS_PER_UNIT; 50 private final static int BIT_INDEX_MASK = BITS_PER_UNIT - 1; 51 52 53 private static final long WORD_MASK = 0xffffffffffffffffL; 54 55 63 private long bits[]; 65 70 private transient int unitsInUse = 0; 71 72 73 private static final long serialVersionUID = 7997698588986878753L; 74 75 78 private static int unitIndex(int bitIndex) { 79 return bitIndex >> ADDRESS_BITS_PER_UNIT; 80 } 81 82 85 private static long bit(int bitIndex) { 86 return 1L << (bitIndex & BIT_INDEX_MASK); 87 } 88 89 94 private void recalculateUnitsInUse() { 95 int i; 97 for (i = unitsInUse-1; i >= 0; i--) 98 if(bits[i] != 0) 99 break; 100 101 unitsInUse = i+1; } 103 104 107 public BitSet() { 108 this(BITS_PER_UNIT); 109 } 110 111 120 public BitSet(int nbits) { 121 if (nbits < 0) 123 throw new NegativeArraySizeException ("nbits < 0: " + nbits); 124 125 bits = new long[(unitIndex(nbits-1) + 1)]; 126 } 127 128 132 private void ensureCapacity(int unitsRequired) { 133 if (bits.length < unitsRequired) { 134 int request = Math.max(2 * bits.length, unitsRequired); 136 long newBits[] = new long[request]; 137 System.arraycopy(bits, 0, newBits, 0, unitsInUse); 138 bits = newBits; 139 } 140 } 141 142 150 public void flip(int bitIndex) { 151 if (bitIndex < 0) 152 throw new IndexOutOfBoundsException ("bitIndex < 0: " + bitIndex); 153 154 int unitIndex = unitIndex(bitIndex); 155 int unitsRequired = unitIndex+1; 156 157 if (unitsInUse < unitsRequired) { 158 ensureCapacity(unitsRequired); 159 bits[unitIndex] ^= bit(bitIndex); 160 unitsInUse = unitsRequired; 161 } else { 162 bits[unitIndex] ^= bit(bitIndex); 163 if (bits[unitsInUse-1] == 0) 164 recalculateUnitsInUse(); 165 } 166 } 167 168 180 public void flip(int fromIndex, int toIndex) { 181 if (fromIndex < 0) 182 throw new IndexOutOfBoundsException ("fromIndex < 0: " + fromIndex); 183 if (toIndex < 0) 184 throw new IndexOutOfBoundsException ("toIndex < 0: " + toIndex); 185 if (fromIndex > toIndex) 186 throw new IndexOutOfBoundsException ("fromIndex: " + fromIndex + 187 " > toIndex: " + toIndex); 188 189 int endUnitIndex = unitIndex(toIndex); 191 int unitsRequired = endUnitIndex + 1; 192 193 if (unitsInUse < unitsRequired) { 194 ensureCapacity(unitsRequired); 195 unitsInUse = unitsRequired; 196 } 197 198 int startUnitIndex = unitIndex(fromIndex); 199 long bitMask = 0; 200 if (startUnitIndex == endUnitIndex) { 201 bitMask = (1L << (toIndex & BIT_INDEX_MASK)) - 203 (1L << (fromIndex & BIT_INDEX_MASK)); 204 bits[startUnitIndex] ^= bitMask; 205 if (bits[unitsInUse-1] == 0) 206 recalculateUnitsInUse(); 207 return; 208 } 209 210 bitMask = bitsLeftOf(fromIndex & BIT_INDEX_MASK); 213 bits[startUnitIndex] ^= bitMask; 214 215 if (endUnitIndex - startUnitIndex > 1) { 217 for(int i=startUnitIndex+1; i<endUnitIndex; i++) 218 bits[i] ^= WORD_MASK; 219 } 220 221 bitMask = bitsRightOf(toIndex & BIT_INDEX_MASK); 223 bits[endUnitIndex] ^= bitMask; 224 225 if (bits[unitsInUse-1] == 0) 227 recalculateUnitsInUse(); 228 } 229 230 234 private static long bitsRightOf(int x) { 235 return (x==0 ? 0 : WORD_MASK >>> (64-x)); 236 } 237 238 242 private static long bitsLeftOf(int x) { 243 return WORD_MASK << x; 244 } 245 246 253 public void set(int bitIndex) { 254 if (bitIndex < 0) 255 throw new IndexOutOfBoundsException ("bitIndex < 0: " + bitIndex); 256 257 int unitIndex = unitIndex(bitIndex); 258 int unitsRequired = unitIndex + 1; 259 260 if (unitsInUse < unitsRequired) { 261 ensureCapacity(unitsRequired); 262 bits[unitIndex] |= bit(bitIndex); 263 unitsInUse = unitsRequired; 264 } else { 265 bits[unitIndex] |= bit(bitIndex); 266 } 267 } 268 269 277 public void set(int bitIndex, boolean value) { 278 if (value) 279 set(bitIndex); 280 else 281 clear(bitIndex); 282 } 283 284 295 public void set(int fromIndex, int toIndex) { 296 if (fromIndex < 0) 297 throw new IndexOutOfBoundsException ("fromIndex < 0: " + fromIndex); 298 if (toIndex < 0) 299 throw new IndexOutOfBoundsException ("toIndex < 0: " + toIndex); 300 if (fromIndex > toIndex) 301 throw new IndexOutOfBoundsException ("fromIndex: " + fromIndex + 302 " > toIndex: " + toIndex); 303 304 int endUnitIndex = unitIndex(toIndex); 306 int unitsRequired = endUnitIndex + 1; 307 308 if (unitsInUse < unitsRequired) { 309 ensureCapacity(unitsRequired); 310 unitsInUse = unitsRequired; 311 } 312 313 int startUnitIndex = unitIndex(fromIndex); 314 long bitMask = 0; 315 if (startUnitIndex == endUnitIndex) { 316 bitMask = (1L << (toIndex & BIT_INDEX_MASK)) - 318 (1L << (fromIndex & BIT_INDEX_MASK)); 319 bits[startUnitIndex] |= bitMask; 320 return; 321 } 322 323 bitMask = bitsLeftOf(fromIndex & BIT_INDEX_MASK); 326 bits[startUnitIndex] |= bitMask; 327 328 if (endUnitIndex - startUnitIndex > 1) { 330 for(int i=startUnitIndex+1; i<endUnitIndex; i++) 331 bits[i] |= WORD_MASK; 332 } 333 334 bitMask = bitsRightOf(toIndex & BIT_INDEX_MASK); 336 bits[endUnitIndex] |= bitMask; 337 } 338 339 351 public void set(int fromIndex, int toIndex, boolean value) { 352 if (value) 353 set(fromIndex, toIndex); 354 else 355 clear(fromIndex, toIndex); 356 } 357 358 365 public void clear(int bitIndex) { 366 if (bitIndex < 0) 367 throw new IndexOutOfBoundsException ("bitIndex < 0: " + bitIndex); 368 369 int unitIndex = unitIndex(bitIndex); 370 if (unitIndex >= unitsInUse) 371 return; 372 373 bits[unitIndex] &= ~bit(bitIndex); 374 if (bits[unitsInUse-1] == 0) 375 recalculateUnitsInUse(); 376 } 377 378 389 public void clear(int fromIndex, int toIndex) { 390 if (fromIndex < 0) 391 throw new IndexOutOfBoundsException ("fromIndex < 0: " + fromIndex); 392 if (toIndex < 0) 393 throw new IndexOutOfBoundsException ("toIndex < 0: " + toIndex); 394 if (fromIndex > toIndex) 395 throw new IndexOutOfBoundsException ("fromIndex: " + fromIndex + 396 " > toIndex: " + toIndex); 397 398 int startUnitIndex = unitIndex(fromIndex); 399 if (startUnitIndex >= unitsInUse) 400 return; 401 int endUnitIndex = unitIndex(toIndex); 402 403 long bitMask = 0; 404 if (startUnitIndex == endUnitIndex) { 405 bitMask = (1L << (toIndex & BIT_INDEX_MASK)) - 407 (1L << (fromIndex & BIT_INDEX_MASK)); 408 bits[startUnitIndex] &= ~bitMask; 409 if (bits[unitsInUse-1] == 0) 410 recalculateUnitsInUse(); 411 return; 412 } 413 414 bitMask = bitsLeftOf(fromIndex & BIT_INDEX_MASK); 417 bits[startUnitIndex] &= ~bitMask; 418 419 if (endUnitIndex - startUnitIndex > 1) { 421 for(int i=startUnitIndex+1; i<endUnitIndex; i++) { 422 if (i < unitsInUse) 423 bits[i] = 0; 424 } 425 } 426 427 if (endUnitIndex < unitsInUse) { 429 bitMask = bitsRightOf(toIndex & BIT_INDEX_MASK); 430 bits[endUnitIndex] &= ~bitMask; 431 } 432 433 if (bits[unitsInUse-1] == 0) 434 recalculateUnitsInUse(); 435 } 436 437 442 public void clear() { 443 while (unitsInUse > 0) 444 bits[--unitsInUse] = 0; 445 } 446 447 457 public boolean get(int bitIndex) { 458 if (bitIndex < 0) 459 throw new IndexOutOfBoundsException ("bitIndex < 0: " + bitIndex); 460 461 boolean result = false; 462 int unitIndex = unitIndex(bitIndex); 463 if (unitIndex < unitsInUse) 464 result = ((bits[unitIndex] & bit(bitIndex)) != 0); 465 466 return result; 467 } 468 469 481 public BitSet get(int fromIndex, int toIndex) { 482 if (fromIndex < 0) 483 throw new IndexOutOfBoundsException ("fromIndex < 0: " + fromIndex); 484 if (toIndex < 0) 485 throw new IndexOutOfBoundsException ("toIndex < 0: " + toIndex); 486 if (fromIndex > toIndex) 487 throw new IndexOutOfBoundsException ("fromIndex: " + fromIndex + 488 " > toIndex: " + toIndex); 489 490 if (length() <= fromIndex || fromIndex == toIndex) 492 return new BitSet (0); 493 494 if (length() < toIndex) 496 toIndex = length(); 497 498 BitSet result = new BitSet (toIndex - fromIndex); 499 int startBitIndex = fromIndex & BIT_INDEX_MASK; 500 int endBitIndex = toIndex & BIT_INDEX_MASK; 501 int targetWords = (toIndex - fromIndex + 63)/64; 502 int sourceWords = unitIndex(toIndex) - unitIndex(fromIndex) + 1; 503 int inverseIndex = 64 - startBitIndex; 504 int targetIndex = 0; 505 int sourceIndex = unitIndex(fromIndex); 506 507 while (targetIndex < targetWords - 1) 509 result.bits[targetIndex++] = 510 (bits[sourceIndex++] >>> startBitIndex) | 511 ((inverseIndex==64) ? 0 : bits[sourceIndex] << inverseIndex); 512 513 result.bits[targetIndex] = (sourceWords == targetWords ? 515 (bits[sourceIndex] & bitsRightOf(endBitIndex)) >>> startBitIndex : 516 (bits[sourceIndex++] >>> startBitIndex) | ((inverseIndex==64) ? 0 : 517 (getBits(sourceIndex) & bitsRightOf(endBitIndex)) << inverseIndex)); 518 519 result.unitsInUse = targetWords; 521 result.recalculateUnitsInUse(); 522 return result; 523 } 524 525 529 private long getBits(int j) { 530 return (j < unitsInUse) ? bits[j] : 0; 531 } 532 533 550 public int nextSetBit(int fromIndex) { 551 if (fromIndex < 0) 552 throw new IndexOutOfBoundsException ("fromIndex < 0: " + fromIndex); 553 int u = unitIndex(fromIndex); 554 if (u >= unitsInUse) 555 return -1; 556 int testIndex = (fromIndex & BIT_INDEX_MASK); 557 long unit = bits[u] >> testIndex; 558 559 if (unit == 0) 560 testIndex = 0; 561 562 while((unit==0) && (u < unitsInUse-1)) 563 unit = bits[++u]; 564 565 if (unit == 0) 566 return -1; 567 568 testIndex += trailingZeroCnt(unit); 569 return ((u * BITS_PER_UNIT) + testIndex); 570 } 571 572 private static int trailingZeroCnt(long val) { 573 int byteVal = (int)val & 0xff; 575 if (byteVal != 0) 576 return trailingZeroTable[byteVal]; 577 578 byteVal = (int)(val >>> 8) & 0xff; 579 if (byteVal != 0) 580 return trailingZeroTable[byteVal] + 8; 581 582 byteVal = (int)(val >>> 16) & 0xff; 583 if (byteVal != 0) 584 return trailingZeroTable[byteVal] + 16; 585 586 byteVal = (int)(val >>> 24) & 0xff; 587 if (byteVal != 0) 588 return trailingZeroTable[byteVal] + 24; 589 590 byteVal = (int)(val >>> 32) & 0xff; 591 if (byteVal != 0) 592 return trailingZeroTable[byteVal] + 32; 593 594 byteVal = (int)(val >>> 40) & 0xff; 595 if (byteVal != 0) 596 return trailingZeroTable[byteVal] + 40; 597 598 byteVal = (int)(val >>> 48) & 0xff; 599 if (byteVal != 0) 600 return trailingZeroTable[byteVal] + 48; 601 602 byteVal = (int)(val >>> 56) & 0xff; 603 return trailingZeroTable[byteVal] + 56; 604 } 605 606 610 private final static byte trailingZeroTable[] = { 611 -25, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 612 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 613 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 614 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 615 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 616 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 617 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 618 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 619 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 620 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 621 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 622 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 623 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 624 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 625 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 626 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0}; 627 628 637 public int nextClearBit(int fromIndex) { 638 if (fromIndex < 0) 639 throw new IndexOutOfBoundsException ("fromIndex < 0: " + fromIndex); 640 641 int u = unitIndex(fromIndex); 642 if (u >= unitsInUse) 643 return fromIndex; 644 int testIndex = (fromIndex & BIT_INDEX_MASK); 645 long unit = bits[u] >> testIndex; 646 647 if (unit == (WORD_MASK >> testIndex)) 648 testIndex = 0; 649 650 while((unit==WORD_MASK) && (u < unitsInUse-1)) 651 unit = bits[++u]; 652 653 if (unit == WORD_MASK) 654 return length(); 655 656 if (unit == 0) 657 return u * BITS_PER_UNIT + testIndex; 658 659 testIndex += trailingZeroCnt(~unit); 660 return ((u * BITS_PER_UNIT) + testIndex); 661 } 662 663 671 public int length() { 672 if (unitsInUse == 0) 673 return 0; 674 675 long highestUnit = bits[unitsInUse - 1]; 676 int highPart = (int)(highestUnit >>> 32); 677 return 64 * (unitsInUse - 1) + 678 (highPart == 0 ? bitLen((int)highestUnit) 679 : 32 + bitLen((int)highPart)); 680 } 681 682 685 private static int bitLen(int w) { 686 return 688 (w < 1<<15 ? 689 (w < 1<<7 ? 690 (w < 1<<3 ? 691 (w < 1<<1 ? (w < 1<<0 ? (w<0 ? 32 : 0) : 1) : (w < 1<<2 ? 2 : 3)) : 692 (w < 1<<5 ? (w < 1<<4 ? 4 : 5) : (w < 1<<6 ? 6 : 7))) : 693 (w < 1<<11 ? 694 (w < 1<<9 ? (w < 1<<8 ? 8 : 9) : (w < 1<<10 ? 10 : 11)) : 695 (w < 1<<13 ? (w < 1<<12 ? 12 : 13) : (w < 1<<14 ? 14 : 15)))) : 696 (w < 1<<23 ? 697 (w < 1<<19 ? 698 (w < 1<<17 ? (w < 1<<16 ? 16 : 17) : (w < 1<<18 ? 18 : 19)) : 699 (w < 1<<21 ? (w < 1<<20 ? 20 : 21) : (w < 1<<22 ? 22 : 23))) : 700 (w < 1<<27 ? 701 (w < 1<<25 ? (w < 1<<24 ? 24 : 25) : (w < 1<<26 ? 26 : 27)) : 702 (w < 1<<29 ? (w < 1<<28 ? 28 : 29) : (w < 1<<30 ? 30 : 31))))); 703 } 704 705 712 public boolean isEmpty() { 713 return (unitsInUse == 0); 714 } 715 716 726 public boolean intersects(BitSet set) { 727 for(int i = Math.min(unitsInUse, set.unitsInUse)-1; i>=0; i--) 728 if ((bits[i] & set.bits[i]) != 0) 729 return true; 730 return false; 731 } 732 733 741 public int cardinality() { 742 int sum = 0; 743 for (int i=0; i<unitsInUse; i++) 744 sum += bitCount(bits[i]); 745 return sum; 746 } 747 748 755 private static int bitCount(long val) { 756 val -= (val & 0xaaaaaaaaaaaaaaaaL) >>> 1; 757 val = (val & 0x3333333333333333L) + ((val >>> 2) & 0x3333333333333333L); 758 val = (val + (val >>> 4)) & 0x0f0f0f0f0f0f0f0fL; 759 val += val >>> 8; 760 val += val >>> 16; 761 return ((int)(val) + (int)(val >>> 32)) & 0xff; 762 } 763 764 773 public void and(BitSet set) { 774 if (this == set) 775 return; 776 777 int oldUnitsInUse = unitsInUse; 779 unitsInUse = Math.min(unitsInUse, set.unitsInUse); 780 int i; 781 for(i=0; i<unitsInUse; i++) 782 bits[i] &= set.bits[i]; 783 784 for( ; i < oldUnitsInUse; i++) 786 bits[i] = 0; 787 788 if (unitsInUse > 0 && bits[unitsInUse - 1] == 0) 790 recalculateUnitsInUse(); 791 } 792 793 802 public void or(BitSet set) { 803 if (this == set) 804 return; 805 806 ensureCapacity(set.unitsInUse); 807 808 int unitsInCommon = Math.min(unitsInUse, set.unitsInUse); 810 int i; 811 for(i=0; i<unitsInCommon; i++) 812 bits[i] |= set.bits[i]; 813 814 for(; i<set.unitsInUse; i++) 816 bits[i] = set.bits[i]; 817 818 if (unitsInUse < set.unitsInUse) 819 unitsInUse = set.unitsInUse; 820 } 821 822 836 public void xor(BitSet set) { 837 int unitsInCommon; 838 839 if (unitsInUse >= set.unitsInUse) { 840 unitsInCommon = set.unitsInUse; 841 } else { 842 unitsInCommon = unitsInUse; 843 int newUnitsInUse = set.unitsInUse; 844 ensureCapacity(newUnitsInUse); 845 unitsInUse = newUnitsInUse; 846 } 847 848 int i; 850 for (i=0; i<unitsInCommon; i++) 851 bits[i] ^= set.bits[i]; 852 853 for ( ; i<set.unitsInUse; i++) 855 bits[i] = set.bits[i]; 856 857 recalculateUnitsInUse(); 858 } 859 860 868 public void andNot(BitSet set) { 869 int unitsInCommon = Math.min(unitsInUse, set.unitsInUse); 870 871 for (int i=0; i<unitsInCommon; i++) { 873 bits[i] &= ~set.bits[i]; 874 } 875 876 recalculateUnitsInUse(); 877 } 878 879 905 public int hashCode() { 906 long h = 1234; 907 for (int i = bits.length; --i >= 0; ) 908 h ^= bits[i] * (i + 1); 909 910 return (int)((h >> 32) ^ h); 911 } 912 913 920 public int size() { 921 return bits.length << ADDRESS_BITS_PER_UNIT; 922 } 923 924 939 public boolean equals(Object obj) { 940 if (!(obj instanceof BitSet )) 941 return false; 942 if (this == obj) 943 return true; 944 945 BitSet set = (BitSet ) obj; 946 int minUnitsInUse = Math.min(unitsInUse, set.unitsInUse); 947 948 for (int i = 0; i < minUnitsInUse; i++) 950 if (bits[i] != set.bits[i]) 951 return false; 952 953 if (unitsInUse > minUnitsInUse) { 955 for (int i = minUnitsInUse; i<unitsInUse; i++) 956 if (bits[i] != 0) 957 return false; 958 } else { 959 for (int i = minUnitsInUse; i<set.unitsInUse; i++) 960 if (set.bits[i] != 0) 961 return false; 962 } 963 964 return true; 965 } 966 967 978 public Object clone() { 979 BitSet result = null; 980 try { 981 result = (BitSet ) super.clone(); 982 } catch (CloneNotSupportedException e) { 983 throw new InternalError (); 984 } 985 result.bits = new long[bits.length]; 986 System.arraycopy(bits, 0, result.bits, 0, unitsInUse); 987 return result; 988 } 989 990 995 private void readObject(java.io.ObjectInputStream in) 996 throws IOException, ClassNotFoundException { 997 998 in.defaultReadObject(); 999 unitsInUse = bits.length; 1003 recalculateUnitsInUse(); 1004 } 1005 1006 1029 public String toString() { 1030 int numBits = unitsInUse << ADDRESS_BITS_PER_UNIT; 1031 StringBuffer buffer = new StringBuffer (8*numBits + 2); 1032 String separator = ""; 1033 buffer.append('{'); 1034 1035 for (int i = 0 ; i < numBits; i++) { 1036 if (get(i)) { 1037 buffer.append(separator); 1038 separator = ", "; 1039 buffer.append(i); 1040 } 1041 } 1042 1043 buffer.append('}'); 1044 return buffer.toString(); 1045 } 1046} 1047 | Popular Tags |