That not fast
This commit is contained in:
@@ -1,563 +0,0 @@
|
|||||||
/*
|
|
||||||
* Javolution - Java(TM) Solution for Real-Time and Embedded Systems
|
|
||||||
* Copyright (C) 2012 - Javolution (http://javolution.org/)
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software is
|
|
||||||
* freely granted, provided that this notice is preserved.
|
|
||||||
*/
|
|
||||||
package io.akarin.api.internal.utils;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.BitSet;
|
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
import java.util.PrimitiveIterator;
|
|
||||||
import java.util.Spliterator;
|
|
||||||
import java.util.Spliterators;
|
|
||||||
import java.util.stream.IntStream;
|
|
||||||
import java.util.stream.StreamSupport;
|
|
||||||
|
|
||||||
import io.akarin.api.internal.utils.misc.MathLib;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A high-performance bit-set integrated with the collection framework as a set of {@link Index indices}
|
|
||||||
* and obeying the collection semantic for methods such as {@link #size} (cardinality) or {@link #equals}
|
|
||||||
* (same set of indices).</p>
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
|
|
||||||
* @version 7.0, September 13, 2015
|
|
||||||
*/
|
|
||||||
public class FastBitSet extends BitSet implements Cloneable, java.io.Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 0x700L; // Version.
|
|
||||||
private static final long[] ALL_CLEARED = new long[0];
|
|
||||||
|
|
||||||
/** Holds the bits (64 bits per long). */
|
|
||||||
private long[] bits;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new bit-set (all bits cleared).
|
|
||||||
*/
|
|
||||||
public FastBitSet() {
|
|
||||||
bits = ALL_CLEARED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs the logical AND operation on this bit set and the
|
|
||||||
* given bit set. This means it builds the intersection
|
|
||||||
* of the two sets. The result is stored into this bit set.
|
|
||||||
*
|
|
||||||
* @param that the second bit set.
|
|
||||||
*/
|
|
||||||
public final void and(FastBitSet that) {
|
|
||||||
long[] thatBits = that.toLongArray();
|
|
||||||
int n = MathLib.min(this.bits.length, thatBits.length);
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
this.bits[i] &= thatBits[i];
|
|
||||||
}
|
|
||||||
for (int i = n; i < bits.length; i++) {
|
|
||||||
this.bits[i] = 0L;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs the logical AND operation on this bit set and the
|
|
||||||
* complement of the given bit set. This means it
|
|
||||||
* selects every element in the first set, that isn't in the
|
|
||||||
* second set. The result is stored into this bit set.
|
|
||||||
*
|
|
||||||
* @param that the second bit set
|
|
||||||
*/
|
|
||||||
public final void andNot(FastBitSet that) {
|
|
||||||
long[] thatBits = that.toLongArray();
|
|
||||||
int n = MathLib.min(this.bits.length, thatBits.length);
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
this.bits[i] &= ~thatBits[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the number of bits set to {@code true} (or the size of this
|
|
||||||
* set).
|
|
||||||
*
|
|
||||||
* @return the number of bits being set.
|
|
||||||
*/
|
|
||||||
public final int cardinality() {
|
|
||||||
int sum = 0;
|
|
||||||
for (int i = 0; i < bits.length; i++) {
|
|
||||||
sum += MathLib.bitCount(bits[i]);
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void clear() {
|
|
||||||
bits = ALL_CLEARED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the specified integer value from this set. That is
|
|
||||||
* the corresponding bit is cleared.
|
|
||||||
*
|
|
||||||
* @param bitIndex a non-negative integer.
|
|
||||||
* @throws IndexOutOfBoundsException if {@code index < 0}
|
|
||||||
*/
|
|
||||||
public final void clear(int bitIndex) {
|
|
||||||
int longIndex = bitIndex >> 6;
|
|
||||||
if (longIndex >= bits.length)
|
|
||||||
return;
|
|
||||||
bits[longIndex] &= ~(1L << bitIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the bits from the specified {@code fromIndex} (inclusive) to the
|
|
||||||
* specified {@code toIndex} (exclusive) to {@code false}.
|
|
||||||
*
|
|
||||||
* @param fromIndex index of the first bit to be cleared.
|
|
||||||
* @param toIndex index after the last bit to be cleared.
|
|
||||||
* @throws IndexOutOfBoundsException if
|
|
||||||
* {@code (fromIndex < 0) | (toIndex < fromIndex)}
|
|
||||||
*/
|
|
||||||
public final void clear(int fromIndex, int toIndex) {
|
|
||||||
if ((fromIndex < 0) || (toIndex < fromIndex))
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
int i = fromIndex >>> 6;
|
|
||||||
if (i >= bits.length)
|
|
||||||
return; // Ensures that i < _length
|
|
||||||
int j = toIndex >>> 6;
|
|
||||||
if (i == j) {
|
|
||||||
bits[i] &= ((1L << fromIndex) - 1) | (-1L << toIndex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bits[i] &= (1L << fromIndex) - 1;
|
|
||||||
if (j < bits.length) {
|
|
||||||
bits[j] &= -1L << toIndex;
|
|
||||||
}
|
|
||||||
for (int k = i + 1; (k < j) && (k < bits.length); k++) {
|
|
||||||
bits[k] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final FastBitSet clone() {
|
|
||||||
FastBitSet copy = new FastBitSet();
|
|
||||||
copy.bits = this.bits.clone();
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// BitSet Operations.
|
|
||||||
//
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the bit at the index to the opposite value.
|
|
||||||
*
|
|
||||||
* @param bitIndex the index of the bit.
|
|
||||||
* @throws IndexOutOfBoundsException if {@code bitIndex < 0}
|
|
||||||
*/
|
|
||||||
public final void flip(int bitIndex) {
|
|
||||||
int i = bitIndex >> 6;
|
|
||||||
ensureCapacity(i + 1);
|
|
||||||
bits[i] ^= 1L << bitIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a range of bits to the opposite value.
|
|
||||||
*
|
|
||||||
* @param fromIndex the low index (inclusive).
|
|
||||||
* @param toIndex the high index (exclusive).
|
|
||||||
* @throws IndexOutOfBoundsException if
|
|
||||||
* {@code (fromIndex < 0) | (toIndex < fromIndex)}
|
|
||||||
*/
|
|
||||||
public final void flip(int fromIndex, int toIndex) {
|
|
||||||
if ((fromIndex < 0) || (toIndex < fromIndex))
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
int i = fromIndex >>> 6;
|
|
||||||
int j = toIndex >>> 6;
|
|
||||||
ensureCapacity(j + 1);
|
|
||||||
if (i == j) {
|
|
||||||
bits[i] ^= (-1L << fromIndex) & ((1L << toIndex) - 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bits[i] ^= -1L << fromIndex;
|
|
||||||
bits[j] ^= (1L << toIndex) - 1;
|
|
||||||
for (int k = i + 1; k < j; k++) {
|
|
||||||
bits[k] ^= -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns {@code true } if the specified integer is in
|
|
||||||
* this bit set; {@code false } otherwise.
|
|
||||||
*
|
|
||||||
* @param bitIndex a non-negative integer.
|
|
||||||
* @return the value of the bit at the specified index.
|
|
||||||
* @throws IndexOutOfBoundsException if {@code bitIndex < 0}
|
|
||||||
*/
|
|
||||||
public final boolean get(int bitIndex) {
|
|
||||||
int i = bitIndex >> 6;
|
|
||||||
return (i >= bits.length) ? false : (bits[i] & (1L << bitIndex)) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a new bit set composed of a range of bits from this one.
|
|
||||||
*
|
|
||||||
* @param fromIndex the low index (inclusive).
|
|
||||||
* @param toIndex the high index (exclusive).
|
|
||||||
* @return a context allocated bit set instance.
|
|
||||||
* @throws IndexOutOfBoundsException if
|
|
||||||
* {@code (fromIndex < 0) | (toIndex < fromIndex)}
|
|
||||||
*/
|
|
||||||
public final FastBitSet get(int fromIndex, int toIndex) {
|
|
||||||
if (fromIndex < 0 || fromIndex > toIndex)
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
FastBitSet bitSet = new FastBitSet();
|
|
||||||
int length = MathLib.min(bits.length, (toIndex >>> 6) + 1);
|
|
||||||
bitSet.bits = new long[length];
|
|
||||||
System.arraycopy(bits, 0, bitSet.bits, 0, length);
|
|
||||||
bitSet.clear(0, fromIndex);
|
|
||||||
bitSet.clear(toIndex, length << 6);
|
|
||||||
return bitSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the specified bit, returns <code>true</code>
|
|
||||||
* if previously set. */
|
|
||||||
public final boolean getAndSet(int bitIndex, boolean value) {
|
|
||||||
int i = bitIndex >> 6;
|
|
||||||
ensureCapacity(i + 1);
|
|
||||||
boolean previous = (bits[i] & (1L << bitIndex)) != 0;
|
|
||||||
if (value) {
|
|
||||||
bits[i] |= 1L << bitIndex;
|
|
||||||
} else {
|
|
||||||
bits[i] &= ~(1L << bitIndex);
|
|
||||||
}
|
|
||||||
return previous;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getAny(int index) {
|
|
||||||
return get(index) ? index : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns {@code true} if this bit set shares at least one
|
|
||||||
* common bit with the specified bit set.
|
|
||||||
*
|
|
||||||
* @param that the bit set to check for intersection
|
|
||||||
* @return {@code true} if the sets intersect; {@code false} otherwise.
|
|
||||||
*/
|
|
||||||
public final boolean intersects(FastBitSet that) {
|
|
||||||
long[] thatBits = that.toLongArray();
|
|
||||||
int i = MathLib.min(this.bits.length, thatBits.length);
|
|
||||||
while (--i >= 0) {
|
|
||||||
if ((bits[i] & thatBits[i]) != 0) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final boolean isEmpty() {
|
|
||||||
return size() == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the logical number of bits actually used by this bit
|
|
||||||
* set. It returns the index of the highest set bit plus one.
|
|
||||||
*
|
|
||||||
* <p> Note: This method does not return the number of set bits
|
|
||||||
* which is returned by {@link #size} </p>
|
|
||||||
*
|
|
||||||
* @return the index of the highest set bit plus one.
|
|
||||||
*/
|
|
||||||
public final int length() {
|
|
||||||
trim();
|
|
||||||
if (bits.length == 0) return 0;
|
|
||||||
return (bits.length << 6) - MathLib.numberOfLeadingZeros(bits[bits.length -1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the index of the next {@code false} bit, from the specified bit
|
|
||||||
* (inclusive).
|
|
||||||
*
|
|
||||||
* @param fromIndex the start location.
|
|
||||||
* @return the first {@code false} bit.
|
|
||||||
* @throws IndexOutOfBoundsException if {@code fromIndex < 0}
|
|
||||||
*/
|
|
||||||
public final int nextClearBit(int fromIndex) {
|
|
||||||
int offset = fromIndex >> 6;
|
|
||||||
long mask = 1L << fromIndex;
|
|
||||||
while (offset < bits.length) {
|
|
||||||
long h = bits[offset];
|
|
||||||
do {
|
|
||||||
if ((h & mask) == 0) { return fromIndex; }
|
|
||||||
mask <<= 1;
|
|
||||||
fromIndex++;
|
|
||||||
} while (mask != 0);
|
|
||||||
mask = 1;
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
return fromIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the index of the next {@code true} bit, from the specified bit
|
|
||||||
* (inclusive). If there is none, {@code -1} is returned.
|
|
||||||
* The following code will iterates through the bit set:[code]
|
|
||||||
* for (int i=nextSetBit(0); i >= 0; i = nextSetBit(i+1)) {
|
|
||||||
* ...
|
|
||||||
* }[/code]
|
|
||||||
*
|
|
||||||
* @param fromIndex the start location.
|
|
||||||
* @return the first {@code false} bit.
|
|
||||||
* @throws IndexOutOfBoundsException if {@code fromIndex < 0}
|
|
||||||
*/
|
|
||||||
public final int nextSetBit(int fromIndex) {
|
|
||||||
int offset = fromIndex >> 6;
|
|
||||||
long mask = 1L << fromIndex;
|
|
||||||
while (offset < bits.length) {
|
|
||||||
long h = bits[offset];
|
|
||||||
do {
|
|
||||||
if ((h & mask) != 0)
|
|
||||||
return fromIndex;
|
|
||||||
mask <<= 1;
|
|
||||||
fromIndex++;
|
|
||||||
} while (mask != 0);
|
|
||||||
mask = 1;
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs the logical OR operation on this bit set and the one specified.
|
|
||||||
* In other words, builds the union of the two sets.
|
|
||||||
* The result is stored into this bit set.
|
|
||||||
*
|
|
||||||
* @param that the second bit set.
|
|
||||||
*/
|
|
||||||
public final void or(FastBitSet that) {
|
|
||||||
long[] thatBits = (that instanceof FastBitSet) ? ((FastBitSet) that).bits
|
|
||||||
: that.toLongArray();
|
|
||||||
ensureCapacity(thatBits.length);
|
|
||||||
for (int i = thatBits.length; --i >= 0;) {
|
|
||||||
bits[i] |= thatBits[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the index of the previous {@code false} bit,
|
|
||||||
* from the specified bit (inclusive).
|
|
||||||
*
|
|
||||||
* @param fromIndex the start location.
|
|
||||||
* @return the first {@code false} bit.
|
|
||||||
* @throws IndexOutOfBoundsException if {@code fromIndex < -1}
|
|
||||||
*/
|
|
||||||
public final int previousClearBit(int fromIndex) {
|
|
||||||
int offset = fromIndex >> 6;
|
|
||||||
long mask = 1L << fromIndex;
|
|
||||||
while (offset >= 0) {
|
|
||||||
long h = bits[offset];
|
|
||||||
do {
|
|
||||||
if ((h & mask) == 0)
|
|
||||||
return fromIndex;
|
|
||||||
mask >>= 1;
|
|
||||||
fromIndex--;
|
|
||||||
} while (mask != 0);
|
|
||||||
mask = 1L << 63;
|
|
||||||
offset--;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the index of the previous {@code true} bit, from the
|
|
||||||
* specified bit (inclusive). If there is none, {@code -1} is returned.
|
|
||||||
* The following code will iterates through the bit set:[code]
|
|
||||||
* for (int i = length(); (i = previousSetBit(i-1)) >= 0; ) {
|
|
||||||
* ...
|
|
||||||
* }[/code]
|
|
||||||
*
|
|
||||||
* @param fromIndex the start location.
|
|
||||||
* @return the first {@code false} bit.
|
|
||||||
* @throws IndexOutOfBoundsException if {@code fromIndex < -1}
|
|
||||||
*/
|
|
||||||
public final int previousSetBit(int fromIndex) {
|
|
||||||
int offset = fromIndex >> 6;
|
|
||||||
long mask = 1L << fromIndex;
|
|
||||||
while (offset >= 0) {
|
|
||||||
long h = bits[offset];
|
|
||||||
do {
|
|
||||||
if ((h & mask) != 0)
|
|
||||||
return fromIndex;
|
|
||||||
mask >>= 1;
|
|
||||||
fromIndex--;
|
|
||||||
} while (mask != 0);
|
|
||||||
mask = 1L << 63;
|
|
||||||
offset--;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int removeAny(int index) {
|
|
||||||
return getAndSet(index, false) ? index : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds the specified integer to this set (corresponding bit is set to
|
|
||||||
* {@code true}.
|
|
||||||
*
|
|
||||||
* @param bitIndex a non-negative integer.
|
|
||||||
* @throws IndexOutOfBoundsException if {@code bitIndex < 0}
|
|
||||||
*/
|
|
||||||
public final void set(int bitIndex) {
|
|
||||||
int i = bitIndex >> 6;
|
|
||||||
ensureCapacity(i + 1);
|
|
||||||
bits[i] |= 1L << bitIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the bit at the given index to the specified value.
|
|
||||||
*
|
|
||||||
* @param bitIndex the position to set.
|
|
||||||
* @param value the value to set it to.
|
|
||||||
* @throws IndexOutOfBoundsException if {@code bitIndex < 0}
|
|
||||||
*/
|
|
||||||
public final void set(int bitIndex, boolean value) {
|
|
||||||
if (value) {
|
|
||||||
set(bitIndex);
|
|
||||||
} else {
|
|
||||||
clear(bitIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the bits from the specified {@code fromIndex} (inclusive) to the
|
|
||||||
* specified {@code toIndex} (exclusive) to {@code true}.
|
|
||||||
*
|
|
||||||
* @param fromIndex index of the first bit to be set.
|
|
||||||
* @param toIndex index after the last bit to be set.
|
|
||||||
* @throws IndexOutOfBoundsException if
|
|
||||||
* {@code (fromIndex < 0) | (toIndex < fromIndex)}
|
|
||||||
*/
|
|
||||||
public final void set(int fromIndex, int toIndex) {
|
|
||||||
if ((fromIndex < 0) || (toIndex < fromIndex))
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
int i = fromIndex >>> 6;
|
|
||||||
int j = toIndex >>> 6;
|
|
||||||
ensureCapacity(j + 1);
|
|
||||||
if (i == j) {
|
|
||||||
bits[i] |= (-1L << fromIndex) & ((1L << toIndex) - 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bits[i] |= -1L << fromIndex;
|
|
||||||
bits[j] |= (1L << toIndex) - 1;
|
|
||||||
for (int k = i + 1; k < j; k++) {
|
|
||||||
bits[k] = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the bits between from (inclusive) and to (exclusive) to the
|
|
||||||
* specified value.
|
|
||||||
*
|
|
||||||
* @param fromIndex the start range (inclusive).
|
|
||||||
* @param toIndex the end range (exclusive).
|
|
||||||
* @param value the value to set it to.
|
|
||||||
* @throws IndexOutOfBoundsException if {@code bitIndex < 0}
|
|
||||||
*/
|
|
||||||
public final void set(int fromIndex, int toIndex, boolean value) {
|
|
||||||
if (value) {
|
|
||||||
set(fromIndex, toIndex);
|
|
||||||
} else {
|
|
||||||
clear(fromIndex, toIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final int size() {
|
|
||||||
return cardinality();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the minimal length <code>long[]</code> representation of this bitset.
|
|
||||||
*
|
|
||||||
* @return Array of longs representing this bitset
|
|
||||||
*/
|
|
||||||
public final long[] toLongArray() {
|
|
||||||
trim();
|
|
||||||
return bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs the logical XOR operation on this bit set and the one specified.
|
|
||||||
* In other words, builds the symmetric remainder of the two sets
|
|
||||||
* (the elements that are in one set, but not in the other).
|
|
||||||
* The result is stored into this bit set.
|
|
||||||
*
|
|
||||||
* @param that the second bit set.
|
|
||||||
*/
|
|
||||||
public final void xor(FastBitSet that) {
|
|
||||||
long[] thatBits = (that instanceof FastBitSet) ? ((FastBitSet) that).bits
|
|
||||||
: that.toLongArray();
|
|
||||||
ensureCapacity(thatBits.length);
|
|
||||||
for (int i = thatBits.length; --i >= 0;) {
|
|
||||||
bits[i] ^= thatBits[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks capacity.
|
|
||||||
private void ensureCapacity(int capacity) {
|
|
||||||
if (bits.length < capacity) {
|
|
||||||
bits = Arrays.copyOf(bits, MathLib.max(bits.length * 2, capacity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Removes trailing zeros.
|
|
||||||
private void trim() {
|
|
||||||
int n = bits.length;
|
|
||||||
while ((--n >= 0) && (bits[n] == 0L)) {}
|
|
||||||
if (++n != bits.length) { // Trim.
|
|
||||||
bits = Arrays.copyOf(bits, n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a stream of indices for which this {@code BitSet}
|
|
||||||
* contains a bit in the set state. The indices are returned
|
|
||||||
* in order, from lowest to highest. The size of the stream
|
|
||||||
* is the number of bits in the set state, equal to the value
|
|
||||||
* returned by the {@link #cardinality()} method.
|
|
||||||
*
|
|
||||||
* <p>The bit set must remain constant during the execution of the
|
|
||||||
* terminal stream operation. Otherwise, the result of the terminal
|
|
||||||
* stream operation is undefined.
|
|
||||||
*
|
|
||||||
* @return a stream of integers representing set indices
|
|
||||||
* @since 1.8
|
|
||||||
*/
|
|
||||||
public IntStream stream() {
|
|
||||||
class BitSetIterator implements PrimitiveIterator.OfInt {
|
|
||||||
int next = nextSetBit(0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasNext() {
|
|
||||||
return next != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int nextInt() {
|
|
||||||
if (next != -1) {
|
|
||||||
int ret = next;
|
|
||||||
next = nextSetBit(next+1);
|
|
||||||
return ret;
|
|
||||||
} else {
|
|
||||||
throw new NoSuchElementException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return StreamSupport.intStream(
|
|
||||||
() -> Spliterators.spliterator(
|
|
||||||
new BitSetIterator(), cardinality(),
|
|
||||||
Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED),
|
|
||||||
Spliterator.SIZED | Spliterator.SUBSIZED |
|
|
||||||
Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED,
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,8 @@ package net.minecraft.server;
|
|||||||
|
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.collect.Iterators;
|
import com.google.common.collect.Iterators;
|
||||||
|
|
||||||
|
import java.util.BitSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
@@ -24,7 +26,7 @@ public class RegistryID<K> implements Registry {
|
|||||||
this.b = (K[]) (new Object[i]);
|
this.b = (K[]) (new Object[i]);
|
||||||
this.c = new int[i];
|
this.c = new int[i];
|
||||||
this.d = (K[]) (new Object[i]);
|
this.d = (K[]) (new Object[i]);
|
||||||
this.usedIds = new io.akarin.api.internal.utils.FastBitSet(); // Akarin - 1.13 backport
|
this.usedIds = new BitSet(); // Akarin - 1.13 backport
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId(@Nullable K k0) {
|
public int getId(@Nullable K k0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user