{
private final static int NOT_CACHED = 0;
private final static int CACHED = 1;
private final static int AT_END = 2;
/** Current iterator state. */
private int state = NOT_CACHED;
/**
* The next element to be returned from {@link #next()} if
* fetched.
*/
private E nextElement;
/**
* {@inheritDoc}
*/
@Override
public boolean hasNext()
{
if (state == NOT_CACHED)
{
state = CACHED;
nextElement = fetch();
}
return state == CACHED;
}
/**
* {@inheritDoc}
*/
@Override
public E next()
{
if (!hasNext())
throw new NoSuchElementException();
state = NOT_CACHED;
return nextElement;
}
/**
* Default implementation throws {@link UnsupportedOperationException}.
*/
@Override
public void remove()
{
throw new UnsupportedOperationException();
}
/**
* Fetch next element. The implementation must
* return {@link #done()} when all elements have been
* fetched.
*/
protected abstract E fetch();
/**
* Call when done.
*/
protected final E done()
{
state = AT_END;
return null;
}
}
hppc-0.6.1/hppc-core/src/main/java/com/carrotsearch/hppc/ArraySizingStrategy.java 0000664 0000000 0000000 00000002211 12403265743 0030006 0 ustar 00root root 0000000 0000000 package com.carrotsearch.hppc;
/**
* Resizing (growth) strategy for array-backed buffers.
*/
public interface ArraySizingStrategy
{
/**
* Array sizing strategies may require that the initial size fulfills
* certain constraints (is a prime or a power of two, for example). This
* method must return the first size that fulfills these conditions
* and is greater or equal to capacity
.
*/
int round(int capacity);
/**
* @param currentBufferLength Current size of the array (buffer). This number
* should comply with the strategy's policies (it is a result of initial rounding
* or further growths). It can also be zero, indicating the growth from an empty
* buffer.
*
* @param elementsCount Number of elements stored in the buffer.
*
* @param expectedAdditions Expected number of additions (resize hint).
*
* @return Must return a new size at least as big as to hold
* elementsCount + expectedAdditions
.
*/
int grow(int currentBufferLength, int elementsCount, int expectedAdditions);
}
hppc-0.6.1/hppc-core/src/main/java/com/carrotsearch/hppc/BitSet.java 0000664 0000000 0000000 00000074612 12403265743 0025231 0 ustar 00root root 0000000 0000000 /*
* Repackaged from org.apache.lucene.util.OpenBitSet (Lucene).
* svn rev. 1479633, https://svn.apache.org/repos/asf/lucene/dev/trunk
*
* Minor changes in class hierarchy, removed serialization and several methods.
* Added container adapters.
*/
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.carrotsearch.hppc;
import java.util.*;
import com.carrotsearch.hppc.cursors.IntCursor;
import com.carrotsearch.hppc.cursors.LongCursor;
import com.carrotsearch.hppc.predicates.IntPredicate;
import com.carrotsearch.hppc.predicates.LongPredicate;
import com.carrotsearch.hppc.procedures.IntProcedure;
import com.carrotsearch.hppc.procedures.LongProcedure;
/**
* An "open" BitSet implementation that allows direct access to the array of words storing
* the bits.
*
* Unlike java.util.bitset, the fact that bits are packed into an array of longs is part
* of the interface. This allows efficient implementation of other algorithms by someone
* other than the author. It also allows one to efficiently implement alternate
* serialization or interchange formats.
*
* The index range for a bitset can easily exceed positive int
range in Java
* (0x7fffffff), so many methods in this class accept or return a long
. There
* are adapter methods that return views compatible with
* {@link LongLookupContainer} and {@link IntLookupContainer} interfaces.
*
* @see #asIntLookupContainer()
* @see #asLongLookupContainer()
*
* @author "Original implementation from the Lucene project."
*/
public class BitSet implements Cloneable
{
/**
* The initial default number of bits ({@value #DEFAULT_NUM_BITS}).
*/
private static final long DEFAULT_NUM_BITS = 64;
/**
* Internal representation of bits in this bit set.
*/
public long [] bits;
/**
* The number of words (longs) used in the {@link #bits} array.
*/
public int wlen;
/**
* Constructs a bit set with the default capacity.
*/
public BitSet()
{
this(DEFAULT_NUM_BITS);
}
/**
* Constructs an BitSet large enough to hold numBits.
*/
public BitSet(long numBits)
{
bits = new long [bits2words(numBits)];
wlen = bits.length;
}
/**
* Constructs an BitSet from an existing long[].
* The first 64 bits are in long[0], with bit index 0 at the least significant bit,
* and bit index 63 at the most significant. Given a bit index, the word containing it
* is long[index/64], and it is at bit number index%64 within that word.
*
* numWords are the number of elements in the array that contain set bits (non-zero
* longs). numWords should be <= bits.length, and any existing words in the array at
* position >= numWords should be zero.
*/
public BitSet(long [] bits, int numWords)
{
this.bits = bits;
this.wlen = numWords;
}
/**
* Static constructor-like method similar to other (generic) collections.
*/
public static BitSet newInstance()
{
return new BitSet();
}
/**
* @return Returns an iterator over all set bits of this bitset. The iterator should
* be faster than using a loop around {@link #nextSetBit(int)}.
*/
public BitSetIterator iterator()
{
return new BitSetIterator(bits, wlen);
}
/**
* Returns the current capacity in bits (1 greater than the index of the last bit).
*/
public long capacity()
{
return bits.length << 6;
}
/**
* Returns the current capacity of this set. Included for compatibility. This is not
* equal to {@link #cardinality}.
*
* @see #cardinality()
* @see java.util.BitSet#size()
*/
public long size()
{
return capacity();
}
/**
* @see java.util.BitSet#length()
*/
public long length()
{
trimTrailingZeros();
if (wlen == 0) return 0;
return (((long) wlen - 1) << 6)
+ (64 - Long.numberOfLeadingZeros(bits[wlen - 1]));
}
/**
* Returns true if there are no set bits
*/
public boolean isEmpty()
{
return cardinality() == 0;
}
/**
* Returns true or false for the specified bit index.
*/
public boolean get(int index)
{
int i = index >> 6; // div 64
// signed shift will keep a negative index and force an
// array-index-out-of-bounds-exception, removing the need for an explicit check.
if (i >= bits.length) return false;
int bit = index & 0x3f; // mod 64
long bitmask = 1L << bit;
return (bits[i] & bitmask) != 0;
}
/**
* Returns true or false for the specified bit index.
*/
public boolean get(long index)
{
int i = (int) (index >> 6); // div 64
if (i >= bits.length) return false;
int bit = (int) index & 0x3f; // mod 64
long bitmask = 1L << bit;
return (bits[i] & bitmask) != 0;
}
/**
* Sets a bit, expanding the set size if necessary.
*/
public void set(long index)
{
int wordNum = expandingWordNum(index);
int bit = (int) index & 0x3f;
long bitmask = 1L << bit;
bits[wordNum] |= bitmask;
}
/**
* Sets a range of bits, expanding the set size if necessary
*
* @param startIndex lower index
* @param endIndex one-past the last bit to set
*/
public void set(long startIndex, long endIndex)
{
if (endIndex <= startIndex) return;
int startWord = (int) (startIndex >> 6);
// since endIndex is one past the end, this is index of the last
// word to be changed.
int endWord = expandingWordNum(endIndex - 1);
long startmask = -1L << startIndex;
long endmask = -1L >>> -endIndex; // 64-(endIndex&0x3f) is the same as -endIndex
// due to wrap
if (startWord == endWord)
{
bits[startWord] |= (startmask & endmask);
return;
}
bits[startWord] |= startmask;
Arrays.fill(bits, startWord + 1, endWord, -1L);
bits[endWord] |= endmask;
}
protected int expandingWordNum(long index)
{
int wordNum = (int) (index >> 6);
if (wordNum >= wlen)
{
ensureCapacity(index + 1);
wlen = wordNum + 1;
}
return wordNum;
}
/** Clears all bits. */
public void clear()
{
Arrays.fill(bits, 0);
this.wlen = 0;
}
/**
* clears a bit, allowing access beyond the current set size without changing the
* size.
*/
public void clear(long index)
{
int wordNum = (int) (index >> 6); // div 64
if (wordNum >= wlen) return;
int bit = (int) index & 0x3f; // mod 64
long bitmask = 1L << bit;
bits[wordNum] &= ~bitmask;
}
/**
* Clears a range of bits. Clearing past the end does not change the size of the set.
*
* @param startIndex lower index
* @param endIndex one-past the last bit to clear
*/
public void clear(int startIndex, int endIndex)
{
if (endIndex <= startIndex) return;
int startWord = (startIndex >> 6);
if (startWord >= wlen) return;
// since endIndex is one past the end, this is index of the last
// word to be changed.
int endWord = ((endIndex - 1) >> 6);
long startmask = -1L << startIndex;
long endmask = -1L >>> -endIndex; // 64-(endIndex&0x3f) is the same as -endIndex
// due to wrap
// invert masks since we are clearing
startmask = ~startmask;
endmask = ~endmask;
if (startWord == endWord)
{
bits[startWord] &= (startmask | endmask);
return;
}
bits[startWord] &= startmask;
int middle = Math.min(wlen, endWord);
Arrays.fill(bits, startWord + 1, middle, 0L);
if (endWord < wlen)
{
bits[endWord] &= endmask;
}
}
/**
* Clears a range of bits. Clearing past the end does not change the size of the set.
*
* @param startIndex lower index
* @param endIndex one-past the last bit to clear
*/
public void clear(long startIndex, long endIndex)
{
if (endIndex <= startIndex) return;
int startWord = (int) (startIndex >> 6);
if (startWord >= wlen) return;
// since endIndex is one past the end, this is index of the last
// word to be changed.
int endWord = (int) ((endIndex - 1) >> 6);
long startmask = -1L << startIndex;
long endmask = -1L >>> -endIndex; // 64-(endIndex&0x3f) is the same as -endIndex
// due to wrap
// invert masks since we are clearing
startmask = ~startmask;
endmask = ~endmask;
if (startWord == endWord)
{
bits[startWord] &= (startmask | endmask);
return;
}
bits[startWord] &= startmask;
int middle = Math.min(wlen, endWord);
Arrays.fill(bits, startWord + 1, middle, 0L);
if (endWord < wlen)
{
bits[endWord] &= endmask;
}
}
/**
* Sets a bit and returns the previous value. The index should be less than the BitSet
* size.
*/
public boolean getAndSet(int index)
{
int wordNum = index >> 6; // div 64
int bit = index & 0x3f; // mod 64
long bitmask = 1L << bit;
boolean val = (bits[wordNum] & bitmask) != 0;
bits[wordNum] |= bitmask;
return val;
}
/**
* Sets a bit and returns the previous value. The index should be less than the BitSet
* size.
*/
public boolean getAndSet(long index)
{
int wordNum = (int) (index >> 6); // div 64
int bit = (int) index & 0x3f; // mod 64
long bitmask = 1L << bit;
boolean val = (bits[wordNum] & bitmask) != 0;
bits[wordNum] |= bitmask;
return val;
}
/**
* Flips a bit, expanding the set size if necessary.
*/
public void flip(long index)
{
int wordNum = expandingWordNum(index);
int bit = (int) index & 0x3f; // mod 64
long bitmask = 1L << bit;
bits[wordNum] ^= bitmask;
}
/**
* flips a bit and returns the resulting bit value. The index should be less than the
* BitSet size.
*/
public boolean flipAndGet(int index)
{
int wordNum = index >> 6; // div 64
int bit = index & 0x3f; // mod 64
long bitmask = 1L << bit;
bits[wordNum] ^= bitmask;
return (bits[wordNum] & bitmask) != 0;
}
/**
* flips a bit and returns the resulting bit value. The index should be less than the
* BitSet size.
*/
public boolean flipAndGet(long index)
{
int wordNum = (int) (index >> 6); // div 64
int bit = (int) index & 0x3f; // mod 64
long bitmask = 1L << bit;
bits[wordNum] ^= bitmask;
return (bits[wordNum] & bitmask) != 0;
}
/**
* Flips a range of bits, expanding the set size if necessary
*
* @param startIndex lower index
* @param endIndex one-past the last bit to flip
*/
public void flip(long startIndex, long endIndex)
{
if (endIndex <= startIndex) return;
int startWord = (int) (startIndex >> 6);
// since endIndex is one past the end, this is index of the last
// word to be changed.
int endWord = expandingWordNum(endIndex - 1);
long startmask = -1L << startIndex;
long endmask = -1L >>> -endIndex; // 64-(endIndex&0x3f) is the same as -endIndex
// due to wrap
if (startWord == endWord)
{
bits[startWord] ^= (startmask & endmask);
return;
}
bits[startWord] ^= startmask;
for (int i = startWord + 1; i < endWord; i++)
{
bits[i] = ~bits[i];
}
bits[endWord] ^= endmask;
}
/** @return the number of set bits */
public long cardinality()
{
return BitUtil.pop_array(bits, 0, wlen);
}
/**
* Returns the popcount or cardinality of the intersection of the two sets. Neither
* set is modified.
*/
public static long intersectionCount(BitSet a, BitSet b)
{
return BitUtil.pop_intersect(a.bits, b.bits, 0, Math.min(a.wlen, b.wlen));
}
/**
* Returns the popcount or cardinality of the union of the two sets. Neither set is
* modified.
*/
public static long unionCount(BitSet a, BitSet b)
{
long tot = BitUtil.pop_union(a.bits, b.bits, 0, Math.min(a.wlen, b.wlen));
if (a.wlen < b.wlen)
{
tot += BitUtil.pop_array(b.bits, a.wlen, b.wlen - a.wlen);
}
else if (a.wlen > b.wlen)
{
tot += BitUtil.pop_array(a.bits, b.wlen, a.wlen - b.wlen);
}
return tot;
}
/**
* Returns the popcount or cardinality of "a and not b" or "intersection(a, not(b))".
* Neither set is modified.
*/
public static long andNotCount(BitSet a, BitSet b)
{
long tot = BitUtil.pop_andnot(a.bits, b.bits, 0, Math.min(a.wlen, b.wlen));
if (a.wlen > b.wlen)
{
tot += BitUtil.pop_array(a.bits, b.wlen, a.wlen - b.wlen);
}
return tot;
}
/**
* Returns the popcount or cardinality of the exclusive-or of the two sets. Neither
* set is modified.
*/
public static long xorCount(BitSet a, BitSet b)
{
long tot = BitUtil.pop_xor(a.bits, b.bits, 0, Math.min(a.wlen, b.wlen));
if (a.wlen < b.wlen)
{
tot += BitUtil.pop_array(b.bits, a.wlen, b.wlen - a.wlen);
}
else if (a.wlen > b.wlen)
{
tot += BitUtil.pop_array(a.bits, b.wlen, a.wlen - b.wlen);
}
return tot;
}
/**
* Returns the index of the first set bit starting at the index specified. -1 is
* returned if there are no more set bits.
*/
public int nextSetBit(int index)
{
int i = index >> 6;
if (i >= wlen) return -1;
int subIndex = index & 0x3f; // index within the word
long word = bits[i] >> subIndex; // skip all the bits to the right of index
if (word != 0)
{
return (i << 6) + subIndex + Long.numberOfTrailingZeros(word);
}
while (++i < wlen)
{
word = bits[i];
if (word != 0) return (i << 6) + Long.numberOfTrailingZeros(word);
}
return -1;
}
/**
* Returns the index of the first set bit starting at the index specified. -1 is
* returned if there are no more set bits.
*/
public long nextSetBit(long index)
{
int i = (int) (index >>> 6);
if (i >= wlen) return -1;
int subIndex = (int) index & 0x3f; // index within the word
long word = bits[i] >>> subIndex; // skip all the bits to the right of index
if (word != 0)
{
return (((long) i) << 6) + (subIndex + Long.numberOfTrailingZeros(word));
}
while (++i < wlen)
{
word = bits[i];
if (word != 0) return (((long) i) << 6) + Long.numberOfTrailingZeros(word);
}
return -1;
}
@Override
public Object clone()
{
try
{
BitSet obs = (BitSet) super.clone();
obs.bits = (long []) obs.bits.clone(); // hopefully an array clone is as
// fast(er) than arraycopy
return obs;
}
catch (CloneNotSupportedException e)
{
throw new RuntimeException(e);
}
}
/** this = this AND other */
public void intersect(BitSet other)
{
int newLen = Math.min(this.wlen, other.wlen);
long [] thisArr = this.bits;
long [] otherArr = other.bits;
// testing against zero can be more efficient
int pos = newLen;
while (--pos >= 0)
{
thisArr[pos] &= otherArr[pos];
}
if (this.wlen > newLen)
{
// fill zeros from the new shorter length to the old length
Arrays.fill(bits, newLen, this.wlen, 0);
}
this.wlen = newLen;
}
/** this = this OR other */
public void union(BitSet other)
{
int newLen = Math.max(wlen, other.wlen);
ensureCapacityWords(newLen);
long [] thisArr = this.bits;
long [] otherArr = other.bits;
int pos = Math.min(wlen, other.wlen);
while (--pos >= 0)
{
thisArr[pos] |= otherArr[pos];
}
if (this.wlen < newLen)
{
System.arraycopy(otherArr, this.wlen, thisArr, this.wlen, newLen - this.wlen);
}
this.wlen = newLen;
}
/** Remove all elements set in other. this = this AND_NOT other */
public void remove(BitSet other)
{
int idx = Math.min(wlen, other.wlen);
long [] thisArr = this.bits;
long [] otherArr = other.bits;
while (--idx >= 0)
{
thisArr[idx] &= ~otherArr[idx];
}
}
/** this = this XOR other */
public void xor(BitSet other)
{
int newLen = Math.max(wlen, other.wlen);
ensureCapacityWords(newLen);
long [] thisArr = this.bits;
long [] otherArr = other.bits;
int pos = Math.min(wlen, other.wlen);
while (--pos >= 0)
{
thisArr[pos] ^= otherArr[pos];
}
if (this.wlen < newLen)
{
System.arraycopy(otherArr, this.wlen, thisArr, this.wlen, newLen - this.wlen);
}
this.wlen = newLen;
}
// some BitSet compatibility methods
// ** see {@link intersect} */
public void and(BitSet other)
{
intersect(other);
}
// ** see {@link union} */
public void or(BitSet other)
{
union(other);
}
// ** see {@link andNot} */
public void andNot(BitSet other)
{
remove(other);
}
/** returns true if the sets have any elements in common */
public boolean intersects(BitSet other)
{
int pos = Math.min(this.wlen, other.wlen);
long [] thisArr = this.bits;
long [] otherArr = other.bits;
while (--pos >= 0)
{
if ((thisArr[pos] & otherArr[pos]) != 0) return true;
}
return false;
}
/**
* Expand the long[] with the size given as a number of words (64 bit longs).
* getNumWords() is unchanged by this call.
*/
public void ensureCapacityWords(int numWords)
{
if (bits.length < numWords)
{
bits = grow(bits, numWords);
}
}
public static long [] grow(long [] array, int minSize)
{
if (array.length < minSize)
{
long [] newArray = new long [getNextSize(minSize)];
System.arraycopy(array, 0, newArray, 0, array.length);
return newArray;
}
else return array;
}
public static int getNextSize(int targetSize)
{
/*
* This over-allocates proportional to the list size, making room for additional
* growth. The over-allocation is mild, but is enough to give linear-time
* amortized behavior over a long sequence of appends() in the presence of a
* poorly-performing system realloc(). The growth pattern is: 0, 4, 8, 16, 25, 35,
* 46, 58, 72, 88, ...
*/
return (targetSize >> 3) + (targetSize < 9 ? 3 : 6) + targetSize;
}
/**
* Ensure that the long[] is big enough to hold numBits, expanding it if necessary.
* getNumWords() is unchanged by this call.
*/
public void ensureCapacity(long numBits)
{
ensureCapacityWords(bits2words(numBits));
}
/**
* Lowers {@link #wlen}, the number of words in use, by checking for trailing zero
* words.
*/
public void trimTrailingZeros()
{
int idx = wlen - 1;
while (idx >= 0 && bits[idx] == 0)
idx--;
wlen = idx + 1;
}
/** returns the number of 64 bit words it would take to hold numBits */
public static int bits2words(long numBits)
{
return (int) (((numBits - 1) >>> 6) + 1);
}
/** returns true if both sets have the same bits set */
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (!(o instanceof BitSet)) return false;
BitSet a;
BitSet b = (BitSet) o;
// make a the larger set.
if (b.wlen > this.wlen)
{
a = b;
b = this;
}
else
{
a = this;
}
// check for any set bits out of the range of b
for (int i = a.wlen - 1; i >= b.wlen; i--)
{
if (a.bits[i] != 0) return false;
}
for (int i = b.wlen - 1; i >= 0; i--)
{
if (a.bits[i] != b.bits[i]) return false;
}
return true;
}
@Override
public int hashCode()
{
// Start with a zero hash and use a mix that results in zero if the input is zero.
// This effectively truncates trailing zeros without an explicit check.
long h = 0;
for (int i = bits.length; --i >= 0;)
{
h ^= bits[i];
h = (h << 1) | (h >>> 63); // rotate left
}
// fold leftmost bits into right and add a constant to prevent
// empty sets from returning 0, which is too common.
return (int) ((h >> 32) ^ h) + 0x98761234;
}
@Override
public String toString()
{
long bit = nextSetBit(0);
if (bit < 0)
{
return "{}";
}
final StringBuilder builder = new StringBuilder();
builder.append("{");
builder.append(Long.toString(bit));
while ((bit = nextSetBit(bit + 1)) >= 0)
{
builder.append(", ");
builder.append(Long.toString(bit));
}
builder.append("}");
return builder.toString();
}
/**
* Returns a view over this bitset data compatible with {@link IntLookupContainer}. A new
* object is always returned, but its methods reflect the current state of the bitset
* (the view is not a snapshot).
*
*
Methods of the returned {@link IntLookupContainer} may throw a {@link RuntimeException}
* if the cardinality of this bitset exceeds the int range.
*/
public IntLookupContainer asIntLookupContainer()
{
return new IntLookupContainer()
{
@Override
public int size()
{
return getCurrentCardinality();
}
@Override
public boolean isEmpty()
{
return BitSet.this.isEmpty();
}
@Override
public Iterator iterator()
{
return new Iterator() {
private long nextBitSet = BitSet.this.nextSetBit(0);
private final IntCursor cursor = new IntCursor();
@Override
public boolean hasNext()
{
return nextBitSet >= 0;
}
@Override
public IntCursor next()
{
final long value = nextBitSet;
if (value < 0) throw new NoSuchElementException();
if (value > Integer.MAX_VALUE)
throw new RuntimeException("BitSet range larger than maximum positive integer.");
nextBitSet = BitSet.this.nextSetBit(value + 1);
cursor.index = cursor.value = (int) value;
return cursor;
}
@Override
public void remove()
{
throw new UnsupportedOperationException();
}
};
}
@Override
public int [] toArray()
{
final int [] data = new int [getCurrentCardinality()];
final BitSetIterator i = BitSet.this.iterator();
for (int j = 0, bit = i.nextSetBit(); bit >= 0; bit = i.nextSetBit())
{
data[j++] = bit;
}
return data;
}
@Override
public T forEach(T predicate)
{
final BitSetIterator i = BitSet.this.iterator();
for (int bit = i.nextSetBit(); bit >= 0; bit = i.nextSetBit())
{
if (predicate.apply(bit) == false)
break;
}
return predicate;
}
@Override
public T forEach(T procedure)
{
final BitSetIterator i = BitSet.this.iterator();
for (int bit = i.nextSetBit(); bit >= 0; bit = i.nextSetBit())
{
procedure.apply(bit);
}
return procedure;
}
@Override
public boolean contains(int index)
{
return index < 0 || BitSet.this.get(index);
}
/**
* Rounds the bitset's cardinality to an integer or throws a
* {@link RuntimeException} if the cardinality exceeds maximum int range.
*/
private int getCurrentCardinality()
{
long cardinality = BitSet.this.cardinality();
if (cardinality > Integer.MAX_VALUE)
throw new RuntimeException("Bitset is larger than maximum positive integer: "
+ cardinality);
return (int) cardinality;
}
};
}
/**
* Returns a view over this bitset data compatible with {@link LongLookupContainer}. A new
* object is always returned, but its methods reflect the current state of the bitset
* (the view is not a snapshot).
*/
public LongLookupContainer asLongLookupContainer()
{
return new LongLookupContainer()
{
@Override
public int size()
{
return getCurrentCardinality();
}
@Override
public boolean isEmpty()
{
return BitSet.this.isEmpty();
}
@Override
public Iterator iterator()
{
return new Iterator() {
private long nextBitSet = BitSet.this.nextSetBit(0);
private final LongCursor cursor = new LongCursor();
@Override
public boolean hasNext()
{
return nextBitSet >= 0;
}
@Override
public LongCursor next()
{
final long value = nextBitSet;
if (value < 0) throw new NoSuchElementException();
nextBitSet = BitSet.this.nextSetBit(value + 1);
cursor.index = (int) value;
cursor.value = value;
return cursor;
}
@Override
public void remove()
{
throw new UnsupportedOperationException();
}
};
}
@Override
public long [] toArray()
{
final long [] data = new long [getCurrentCardinality()];
final BitSet bset = BitSet.this;
int j = 0;
for (long bit = bset.nextSetBit((long) 0); bit >= 0; bit = bset.nextSetBit(bit + 1))
{
data[j++] = bit;
}
return data;
}
@Override
public T forEach(T predicate)
{
final BitSet bset = BitSet.this;
for (long bit = bset.nextSetBit((long) 0); bit >= 0; bit = bset.nextSetBit(bit + 1))
{
if (predicate.apply(bit) == false)
break;
}
return predicate;
}
@Override
public T forEach(T procedure)
{
final BitSet bset = BitSet.this;
for (long bit = bset.nextSetBit((long) 0); bit >= 0; bit = bset.nextSetBit(bit + 1))
{
procedure.apply(bit);
}
return procedure;
}
@Override
public boolean contains(long index)
{
return index < 0 || BitSet.this.get(index);
}
/**
* Rounds the bitset's cardinality to an integer or throws a
* {@link RuntimeException} if the cardinality exceeds maximum int range.
*/
private int getCurrentCardinality()
{
long cardinality = BitSet.this.cardinality();
if (cardinality > Integer.MAX_VALUE)
throw new RuntimeException("Bitset is larger than maximum positive integer: "
+ cardinality);
return (int) cardinality;
}
};
}
}
hppc-0.6.1/hppc-core/src/main/java/com/carrotsearch/hppc/BitSetIterator.java 0000664 0000000 0000000 00000014205 12403265743 0026733 0 ustar 00root root 0000000 0000000
/*
* Repackaged from org.apache.lucene.util.OpenBitSet (Lucene).
* svn rev. 893130, http://svn.apache.org/repos/asf/lucene/java/trunk/
*
* Minor changes in class hierarchy, removed serialization.
*/
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.carrotsearch.hppc;
/**
* An iterator to iterate over set bits in an BitSet. This is faster than nextSetBit() for
* iterating over the complete set of bits, especially when the density of the bits set is
* high.
*/
public class BitSetIterator {
// The General Idea: instead of having an array per byte that has
// the offsets of the next set bit, that array could be
// packed inside a 32 bit integer (8 4 bit numbers). That
// should be faster than accessing an array for each index, and
// the total array size is kept smaller (256*sizeof(int))=1K
final static int[] bitlist={
0x0, 0x1, 0x2, 0x21, 0x3, 0x31, 0x32, 0x321, 0x4, 0x41, 0x42, 0x421, 0x43,
0x431, 0x432, 0x4321, 0x5, 0x51, 0x52, 0x521, 0x53, 0x531, 0x532, 0x5321,
0x54, 0x541, 0x542, 0x5421, 0x543, 0x5431, 0x5432, 0x54321, 0x6, 0x61, 0x62,
0x621, 0x63, 0x631, 0x632, 0x6321, 0x64, 0x641, 0x642, 0x6421, 0x643,
0x6431, 0x6432, 0x64321, 0x65, 0x651, 0x652, 0x6521, 0x653, 0x6531, 0x6532,
0x65321, 0x654, 0x6541, 0x6542, 0x65421, 0x6543, 0x65431, 0x65432, 0x654321,
0x7, 0x71, 0x72, 0x721, 0x73, 0x731, 0x732, 0x7321, 0x74, 0x741, 0x742,
0x7421, 0x743, 0x7431, 0x7432, 0x74321, 0x75, 0x751, 0x752, 0x7521, 0x753,
0x7531, 0x7532, 0x75321, 0x754, 0x7541, 0x7542, 0x75421, 0x7543, 0x75431,
0x75432, 0x754321, 0x76, 0x761, 0x762, 0x7621, 0x763, 0x7631, 0x7632,
0x76321, 0x764, 0x7641, 0x7642, 0x76421, 0x7643, 0x76431, 0x76432, 0x764321,
0x765, 0x7651, 0x7652, 0x76521, 0x7653, 0x76531, 0x76532, 0x765321, 0x7654,
0x76541, 0x76542, 0x765421, 0x76543, 0x765431, 0x765432, 0x7654321, 0x8,
0x81, 0x82, 0x821, 0x83, 0x831, 0x832, 0x8321, 0x84, 0x841, 0x842, 0x8421,
0x843, 0x8431, 0x8432, 0x84321, 0x85, 0x851, 0x852, 0x8521, 0x853, 0x8531,
0x8532, 0x85321, 0x854, 0x8541, 0x8542, 0x85421, 0x8543, 0x85431, 0x85432,
0x854321, 0x86, 0x861, 0x862, 0x8621, 0x863, 0x8631, 0x8632, 0x86321, 0x864,
0x8641, 0x8642, 0x86421, 0x8643, 0x86431, 0x86432, 0x864321, 0x865, 0x8651,
0x8652, 0x86521, 0x8653, 0x86531, 0x86532, 0x865321, 0x8654, 0x86541,
0x86542, 0x865421, 0x86543, 0x865431, 0x865432, 0x8654321, 0x87, 0x871,
0x872, 0x8721, 0x873, 0x8731, 0x8732, 0x87321, 0x874, 0x8741, 0x8742,
0x87421, 0x8743, 0x87431, 0x87432, 0x874321, 0x875, 0x8751, 0x8752, 0x87521,
0x8753, 0x87531, 0x87532, 0x875321, 0x8754, 0x87541, 0x87542, 0x875421,
0x87543, 0x875431, 0x875432, 0x8754321, 0x876, 0x8761, 0x8762, 0x87621,
0x8763, 0x87631, 0x87632, 0x876321, 0x8764, 0x87641, 0x87642, 0x876421,
0x87643, 0x876431, 0x876432, 0x8764321, 0x8765, 0x87651, 0x87652, 0x876521,
0x87653, 0x876531, 0x876532, 0x8765321, 0x87654, 0x876541, 0x876542,
0x8765421, 0x876543, 0x8765431, 0x8765432, 0x87654321
};
/***** the python code that generated bitlist
def bits2int(val):
arr=0
for shift in range(8,0,-1):
if val & 0x80:
arr = (arr << 4) | shift
val = val << 1
return arr
def int_table():
tbl = [ hex(bits2int(val)).strip('L') for val in range(256) ]
return ','.join(tbl)
******/
// hmmm, what about an iterator that finds zeros though,
// or a reverse iterator... should they be separate classes
// for efficiency, or have a common root interface? (or
// maybe both? could ask for a SetBitsIterator, etc...
private final long[] arr;
private final int words;
private int i=-1;
private long word;
private int wordShift;
private int indexArray;
public BitSetIterator(BitSet obs) {
this(obs.bits, obs.wlen);
}
public BitSetIterator(long[] bits, int numWords) {
arr = bits;
words = numWords;
}
// 64 bit shifts
private void shift() {
if ((int)word ==0) {wordShift +=32; word = word >>>32; }
if ((word & 0x0000FFFF) == 0) { wordShift +=16; word >>>=16; }
if ((word & 0x000000FF) == 0) { wordShift +=8; word >>>=8; }
indexArray = bitlist[(int)word & 0xff];
}
/***** alternate shift implementations
// 32 bit shifts, but a long shift needed at the end
private void shift2() {
int y = (int)word;
if (y==0) {wordShift +=32; y = (int)(word >>>32); }
if ((y & 0x0000FFFF) == 0) { wordShift +=16; y>>>=16; }
if ((y & 0x000000FF) == 0) { wordShift +=8; y>>>=8; }
indexArray = bitlist[y & 0xff];
word >>>= (wordShift +1);
}
private void shift3() {
int lower = (int)word;
int lowByte = lower & 0xff;
if (lowByte != 0) {
indexArray=bitlist[lowByte];
return;
}
shift();
}
******/
public final static int NO_MORE = -1;
public int nextSetBit() {
if (indexArray == 0) {
if (word != 0) {
word >>>= 8;
wordShift += 8;
}
while (word == 0) {
if (++i >= words) {
return NO_MORE;
}
word = arr[i];
wordShift = -1; // loop invariant code motion should move this
}
// after the first time, should I go with a linear search, or
// stick with the binary search in shift?
shift();
}
int bitIndex = (indexArray & 0x0f) + wordShift;
indexArray >>>= 4;
// should i<<6 be cached as a separate variable?
// it would only save one cycle in the best circumstances.
return (i<<6) + bitIndex;
}
}
hppc-0.6.1/hppc-core/src/main/java/com/carrotsearch/hppc/BitUtil.java 0000664 0000000 0000000 00000007300 12403265743 0025401 0 ustar 00root root 0000000 0000000
/*
* Repackaged from org.apache.lucene.util.OpenBitSet (Lucene).
* svn rev. 1479633, https://svn.apache.org/repos/asf/lucene/dev/trunk
*
* Minor changes in class hierarchy, removed serialization.
*/
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.carrotsearch.hppc;
/**
* A variety of high efficiency bit twiddling routines.
*/
final class BitUtil {
private BitUtil() {} // no instance
// The pop methods used to rely on bit-manipulation tricks for speed but it
// turns out that it is faster to use the Long.bitCount method (which is an
// intrinsic since Java 6u18) in a naive loop, see LUCENE-2221
/** Returns the number of set bits in an array of longs. */
public static long pop_array(long[] arr, int wordOffset, int numWords) {
long popCount = 0;
for (int i = wordOffset, end = wordOffset + numWords; i < end; ++i) {
popCount += Long.bitCount(arr[i]);
}
return popCount;
}
/** Returns the popcount or cardinality of the two sets after an intersection.
* Neither array is modified. */
public static long pop_intersect(long[] arr1, long[] arr2, int wordOffset, int numWords) {
long popCount = 0;
for (int i = wordOffset, end = wordOffset + numWords; i < end; ++i) {
popCount += Long.bitCount(arr1[i] & arr2[i]);
}
return popCount;
}
/** Returns the popcount or cardinality of the union of two sets.
* Neither array is modified. */
public static long pop_union(long[] arr1, long[] arr2, int wordOffset, int numWords) {
long popCount = 0;
for (int i = wordOffset, end = wordOffset + numWords; i < end; ++i) {
popCount += Long.bitCount(arr1[i] | arr2[i]);
}
return popCount;
}
/** Returns the popcount or cardinality of A & ~B.
* Neither array is modified. */
public static long pop_andnot(long[] arr1, long[] arr2, int wordOffset, int numWords) {
long popCount = 0;
for (int i = wordOffset, end = wordOffset + numWords; i < end; ++i) {
popCount += Long.bitCount(arr1[i] & ~arr2[i]);
}
return popCount;
}
/** Returns the popcount or cardinality of A ^ B
* Neither array is modified. */
public static long pop_xor(long[] arr1, long[] arr2, int wordOffset, int numWords) {
long popCount = 0;
for (int i = wordOffset, end = wordOffset + numWords; i < end; ++i) {
popCount += Long.bitCount(arr1[i] ^ arr2[i]);
}
return popCount;
}
/** returns the next highest power of two, or the current value if it's already a power of two or zero*/
public static int nextHighestPowerOfTwo(int v) {
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;
return v;
}
/** returns the next highest power of two, or the current value if it's already a power of two or zero*/
public static long nextHighestPowerOfTwo(long v) {
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v |= v >> 32;
v++;
return v;
}
}
hppc-0.6.1/hppc-core/src/main/java/com/carrotsearch/hppc/BoundedProportionalArraySizingStrategy.java0000664 0000000 0000000 00000006211 12403265743 0033724 0 ustar 00root root 0000000 0000000 package com.carrotsearch.hppc;
import java.util.ArrayList;
/**
* Array resizing proportional to the current buffer size, optionally kept within the
* given minimum and maximum growth limits. Java's {@link ArrayList} uses:
*
* minGrow = 1
* maxGrow = Integer.MAX_VALUE (unbounded)
* growRatio = 1.5f
*
*/
public final class BoundedProportionalArraySizingStrategy
implements ArraySizingStrategy
{
/**
* Used by {@link ArrayList} internally to account for reference sizes.
*/
public static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE;
/** Minimum grow count. */
public final static int DEFAULT_MIN_GROW_COUNT = 10;
/** Maximum grow count (unbounded). */
public final static int DEFAULT_MAX_GROW_COUNT = MAX_ARRAY_SIZE;
/** Default resize is by half the current buffer's size. */
public final static float DEFAULT_GROW_RATIO = 1.5f;
/** Minimum number of elements to grow, if capacity exceeded. */
public final int minGrowCount;
/** Maximum number of elements to grow, if capacity exceeded. */
public final int maxGrowCount;
/**
* The current buffer length is multiplied by this ratio to get the
* first estimate for the new size. To double the size of the current
* buffer, for example, set to 2
.
*/
public final float growRatio;
/**
* Create the default sizing strategy.
*/
public BoundedProportionalArraySizingStrategy()
{
this(DEFAULT_MIN_GROW_COUNT, DEFAULT_MAX_GROW_COUNT, DEFAULT_GROW_RATIO);
}
/**
* Create the sizing strategy with custom policies.
*/
public BoundedProportionalArraySizingStrategy(int minGrow, int maxGrow, float ratio)
{
assert minGrow >= 1 : "Min grow must be >= 1.";
assert maxGrow >= minGrow : "Max grow must be >= min grow.";
assert ratio >= 1f : "Growth ratio must be >= 1 (was " + ratio + ").";
this.minGrowCount = minGrow;
this.maxGrowCount = maxGrow;
this.growRatio = ratio - 1.0f;
}
/**
* Grow according to {@link #growRatio}, {@link #minGrowCount} and {@link #maxGrowCount}.
*/
public int grow(int currentBufferLength, int elementsCount, int expectedAdditions)
{
long growBy = (long) ((long) currentBufferLength * growRatio);
growBy = Math.max(growBy, minGrowCount);
growBy = Math.min(growBy, maxGrowCount);
long growTo = Math.min(MAX_ARRAY_SIZE, growBy + currentBufferLength);
long newSize = Math.max((long) elementsCount + expectedAdditions, growTo);
if (newSize > MAX_ARRAY_SIZE) {
throw new AssertionError(
"Cannot resize beyond " + MAX_ARRAY_SIZE +
" (" + (elementsCount + expectedAdditions) + ")");
}
return (int) newSize;
}
/**
* No specific requirements in case of this strategy - the argument is returned.
*/
public int round(int capacity)
{
assert capacity >= 0 : "Capacity must be a positive number.";
return capacity;
}
}
hppc-0.6.1/hppc-core/src/main/java/com/carrotsearch/hppc/EmptyArrays.java 0000664 0000000 0000000 00000001166 12403265743 0026311 0 ustar 00root root 0000000 0000000 package com.carrotsearch.hppc;
/**
* Empty arrays.
*/
public final class EmptyArrays
{
public final static byte [] EMPTY_BYTE_ARRAY = new byte [0];
public final static short [] EMPTY_SHORT_ARRAY = new short [0];
public final static char [] EMPTY_CHAR_ARRAY = new char [0];
public final static int [] EMPTY_INT_ARRAY = new int [0];
public final static float [] EMPTY_FLOAT_ARRAY = new float [0];
public final static double [] EMPTY_DOUBLE_ARRAY = new double [0];
public final static Object [] EMPTY_OBJECT_ARRAY = new Object [0];
private EmptyArrays()
{
// no instances.
}
}
hppc-0.6.1/hppc-core/src/main/java/com/carrotsearch/hppc/IntDoubleLinkedSet.java 0000664 0000000 0000000 00000031622 12403265743 0027521 0 ustar 00root root 0000000 0000000 package com.carrotsearch.hppc;
import java.util.Arrays;
import java.util.Iterator;
import com.carrotsearch.hppc.cursors.IntCursor;
import com.carrotsearch.hppc.predicates.IntPredicate;
import com.carrotsearch.hppc.procedures.IntProcedure;
/**
* A double-linked set of int
values. This data structure is characterized by
* constant-time lookup, insertions, deletions and removal of all set elements (unlike a
* {@link BitSet} which takes time proportional to the maximum element's length).
*
* The implementation in based on
*
* Preston Briggs and Linda Torczon's paper "An Efficient Representation for Sparse Sets"
*/
public class IntDoubleLinkedSet implements IntLookupContainer, IntSet, Cloneable
{
/**
* Default capacity if no other capacity is given in the constructor.
*/
public final static int DEFAULT_CAPACITY = 5;
/**
* Dense array of set elements.
*/
public int [] dense = EmptyArrays.EMPTY_INT_ARRAY;
/**
* Sparse, element value-indexed array pointing back at {@link #dense}.
*/
public int [] sparse = EmptyArrays.EMPTY_INT_ARRAY;
/**
* Current number of elements stored in the set ({@link #dense}).
*/
public int elementsCount;
/**
* Buffer resizing strategy.
*/
protected final ArraySizingStrategy resizer;
/**
* Create with default sizing strategy and initial dense capacity of
* {@value #DEFAULT_CAPACITY} elements and initial sparse capacity of zero (first insert
* will cause reallocation).
*
* @see BoundedProportionalArraySizingStrategy
*/
public IntDoubleLinkedSet()
{
this(DEFAULT_CAPACITY, 0);
}
/**
* Create with default sizing strategy and the given initial capacity.
*
* @see BoundedProportionalArraySizingStrategy
*/
public IntDoubleLinkedSet(int denseCapacity, int sparseCapacity)
{
this(denseCapacity, sparseCapacity, new BoundedProportionalArraySizingStrategy());
}
/**
* Create with a custom dense array resizing strategy.
*/
public IntDoubleLinkedSet(int denseCapacity, int sparseCapacity, ArraySizingStrategy resizer)
{
assert denseCapacity >= 0 : "denseCapacity must be >= 0: " + denseCapacity;
assert sparseCapacity >= 0 : "sparseCapacity must be >= 0: " + sparseCapacity;
assert resizer != null;
this.resizer = resizer;
ensureDenseCapacity(resizer.round(denseCapacity));
ensureSparseCapacity(sparseCapacity);
}
/**
* Creates a set from elements of another container.
*/
public IntDoubleLinkedSet(IntContainer container)
{
this(container.size(), 1 + maxElement(container));
for (IntCursor cursor : container)
{
addNoChecks(cursor.value);
}
}
/**
* Ensures the internal dense buffer has enough free slots to store
* expectedAdditions
.
*/
protected void ensureDenseCapacity(int expectedAdditions)
{
final int bufferLen = (dense == null ? 0 : dense.length);
final int elementsCount = size();
if (elementsCount > bufferLen - expectedAdditions)
{
final int newSize = resizer.grow(bufferLen, elementsCount, expectedAdditions);
assert newSize >= elementsCount + expectedAdditions : "Resizer failed to" +
" return sensible new size: " + newSize + " <= "
+ (elementsCount + expectedAdditions);
final int [] newBuffer = new int [newSize];
if (bufferLen > 0)
{
System.arraycopy(dense, 0, newBuffer, 0, elementsCount);
}
this.dense = newBuffer;
}
}
/**
* Ensures the internal sparse buffer has enough free slots to store
* index of value
.
*/
protected void ensureSparseCapacity(int value)
{
assert value >= 0 : "value must be >= 0: " + value;
if (value >= sparse.length)
{
final int [] newBuffer = new int [value + 1];
if (sparse.length > 0)
{
System.arraycopy(sparse, 0, newBuffer, 0, sparse.length);
}
this.sparse = newBuffer;
}
}
@Override
public int size()
{
return elementsCount;
}
@Override
public int [] toArray()
{
int [] result = new int [size()];
System.arraycopy(dense, 0, result, 0, size());
return result;
}
@Override
public boolean isEmpty()
{
return size() == 0;
}
@Override
public void clear()
{
this.elementsCount = 0;
}
@Override
public boolean contains(int value)
{
int index;
return value >= 0
&& value < sparse.length
&& (index = sparse[value]) < elementsCount
&& dense[index] == value;
}
@Override
public boolean add(int value)
{
assert value >= 0 : "Double linked set supports values >= 0 only.";
final boolean containsAlready = contains(value);
if (!containsAlready)
{
// TODO: check if a fixed-size set is (much) faster without these checks?
ensureDenseCapacity(1);
ensureSparseCapacity(value);
sparse[value] = elementsCount;
dense[elementsCount++] = value;
}
return !containsAlready;
}
/**
* A faster version of {@link #add(int)} that does check or attempt to expand the
* internal buffers. Assertions are still present.
*/
private void addNoChecks(int value)
{
assert value >= 0 : "Double linked set supports values >= 0 only.";
final boolean containsAlready = contains(value);
if (!containsAlready)
{
assert size() + 1 < dense.length : "Dense array too small.";
assert value < sparse.length : "Value too large for sparse.";
sparse[value] = elementsCount;
dense[elementsCount++] = value;
}
}
/**
* Adds two elements to the set.
*/
public int add(int e1, int e2)
{
int count = 0;
if (add(e1)) count++;
if (add(e2)) count++;
return count;
}
/**
* Vararg-signature method for adding elements to this set.
* This method is handy, but costly if used in tight loops (anonymous
* array passing)
*
* @return Returns the number of elements that were added to the set
* (were not present in the set).
*/
public int add(int... elements)
{
int count = 0;
for (int e : elements)
if (add(e)) count++;
return count;
}
/**
* Adds all elements from a given container to this set.
*
* @return Returns the number of elements actually added as a result of this
* call (not previously present in the set).
*/
public int addAll(IntContainer container)
{
return addAll((Iterable) container);
}
/**
* Adds all elements from a given iterable to this set.
*
* @return Returns the number of elements actually added as a result of this
* call (not previously present in the set).
*/
public int addAll(Iterable extends IntCursor> iterable)
{
int count = 0;
for (IntCursor cursor : iterable)
{
if (add(cursor.value)) count++;
}
return count;
}
/*
*
*/
@Override
public int removeAllOccurrences(int value)
{
if (value >= 0 && value < sparse.length)
{
final int slot = sparse[value];
final int n = elementsCount - 1;
if (slot <= n && dense[slot] == value)
{
// Swap the last value with the removed value.
final int lastValue = dense[n];
elementsCount--;
dense[slot] = lastValue;
sparse[lastValue] = slot;
return 1;
}
}
return 0;
}
/**
* An alias for the (preferred) {@link #removeAllOccurrences}.
*/
public boolean remove(int key)
{
return removeAllOccurrences(key) == 1;
}
@Override
public Iterator iterator()
{
return new IntArrayList.ValueIterator(dense, size());
}
@Override
public T forEach(T procedure)
{
final int max = size();
final int [] dense = this.dense;
for (int i = 0; i < max; i++)
{
procedure.apply(dense[i]);
}
return procedure;
}
@Override
public T forEach(T predicate)
{
final int max = size();
final int [] dense = this.dense;
for (int i = 0; i < max; i++)
{
if (predicate.apply(dense[i]))
break;
}
return predicate;
}
@Override
public int removeAll(IntLookupContainer c)
{
int max = size(), removed = 0;
final int [] dense = this.dense;
for (int i = 0; i < max;)
{
if (c.contains(dense[i])) {
// Swap the last value with the removed value.
final int lastValue = dense[--max];
dense[i] = lastValue;
sparse[lastValue] = i;
removed++;
} else {
i++;
}
}
this.elementsCount = max;
return removed;
}
@Override
public int removeAll(IntPredicate predicate)
{
int max = size(), removed = 0;
final int [] dense = this.dense;
for (int i = 0; i < max;)
{
if (predicate.apply(dense[i])) {
// Swap the last value with the removed value.
final int lastValue = dense[--max];
dense[i] = lastValue;
sparse[lastValue] = i;
removed++;
} else {
i++;
}
}
this.elementsCount = max;
return removed;
}
@Override
public int retainAll(IntLookupContainer c)
{
int max = size(), removed = 0;
final int [] dense = this.dense;
for (int i = 0; i < max;)
{
if (!c.contains(dense[i])) {
// Swap the last value with the removed value.
final int lastValue = dense[--max];
dense[i] = lastValue;
sparse[lastValue] = i;
removed++;
} else {
i++;
}
}
this.elementsCount = max;
return removed;
}
@Override
public int retainAll(final IntPredicate predicate)
{
return removeAll(new IntPredicate()
{
public boolean apply(int value)
{
return !predicate.apply(value);
};
});
}
/**
* Create a set from a variable number of arguments or an array of int
.
* The elements are copied from the argument to the internal buffer.
*/
public static IntDoubleLinkedSet from(int... elements)
{
final IntDoubleLinkedSet set =
new IntDoubleLinkedSet(elements.length, 1 + maxElement(elements));
for (int i : elements)
set.addNoChecks(i);
return set;
}
/**
* Create a set from elements of another container.
*/
public static IntDoubleLinkedSet from(IntContainer container)
{
return new IntDoubleLinkedSet(container);
}
/**
* Static constructor-like method similar to other (generic) collections.
*/
public static IntDoubleLinkedSet newInstance()
{
return new IntDoubleLinkedSet();
}
/**
* Return the value of the maximum element (or zero) in a given container.
*/
private static int maxElement(IntContainer container)
{
int max = 0;
for (IntCursor c : container)
max = Math.max(max, c.value);
return max;
}
/**
* Return the value of the maximum element (or zero) in a given container.
*/
private static int maxElement(int... elements)
{
int max = 0;
for (int c : elements)
max = Math.max(max, c);
return max;
}
/**
* Clone this object.
*/
@Override
public IntDoubleLinkedSet clone()
{
try
{
IntDoubleLinkedSet cloned = (IntDoubleLinkedSet) super.clone();
cloned.dense = dense.clone();
cloned.sparse = sparse.clone();
return cloned;
}
catch (CloneNotSupportedException e)
{
throw new RuntimeException(e);
}
}
/*
*
*/
@Override
public String toString()
{
return Arrays.toString(this.toArray());
}
}
hppc-0.6.1/hppc-core/src/main/java/com/carrotsearch/hppc/Internals.java 0000664 0000000 0000000 00000003416 12403265743 0025770 0 ustar 00root root 0000000 0000000 package com.carrotsearch.hppc;
import com.carrotsearch.hppc.hash.MurmurHash3;
/**
* Internal utilities.
*/
final class Internals
{
static int rehash(Object o, int p) { return o == null ? 0 : MurmurHash3.hash(o.hashCode() ^ p); }
static int rehash(byte v, int p) { return MurmurHash3.hash(v ^ p); }
static int rehash(short v, int p) { return MurmurHash3.hash(v ^ p); }
static int rehash(int v, int p) { return MurmurHash3.hash(v ^ p); }
static int rehash(long v, int p) { return (int) MurmurHash3.hash(v ^ p); }
static int rehash(char v, int p) { return MurmurHash3.hash(v ^ p); }
static int rehash(float v, int p) { return MurmurHash3.hash(Float.floatToIntBits(v) ^ p); }
static int rehash(double v, int p) { return (int) MurmurHash3.hash(Double.doubleToLongBits(v) ^ p); }
static int rehash(Object o) { return o == null ? 0 : MurmurHash3.hash(o.hashCode()); }
static int rehash(byte v) { return MurmurHash3.hash(v); }
static int rehash(short v) { return MurmurHash3.hash(v); }
static int rehash(int v) { return MurmurHash3.hash(v); }
static int rehash(long v) { return (int) MurmurHash3.hash(v); }
static int rehash(char v) { return MurmurHash3.hash(v); }
static int rehash(float v) { return MurmurHash3.hash(Float.floatToIntBits(v)); }
static int rehash(double v) { return (int) MurmurHash3.hash(Double.doubleToLongBits(v)); }
/**
* Create and return an array of template objects (Object
s in the generic
* version, corresponding key-primitive type in the generated version).
*
* @param arraySize The size of the array to return.
*/
@SuppressWarnings("unchecked")
static T newArray(int arraySize)
{
return (T) new Object [arraySize];
}
}
hppc-0.6.1/hppc-core/src/main/java/com/carrotsearch/hppc/XorShiftRandom.java 0000664 0000000 0000000 00000001673 12403265743 0026743 0 ustar 00root root 0000000 0000000 package com.carrotsearch.hppc;
import java.util.Random;
/**
* XorShift pseudo random number generator. This class is not thread-safe and should be
* used from a single thread only.
*
* @see "http://en.wikipedia.org/wiki/Xorshift"
* @see "http://www.jstatsoft.org/v08/i14/paper"
* @see "http://www.javamex.com/tutorials/random_numbers/xorshift.shtml"
*/
@SuppressWarnings("serial")
public class XorShiftRandom extends Random
{
private long x;
public XorShiftRandom()
{
this(System.nanoTime());
}
public XorShiftRandom(long seed)
{
this.setSeed(seed);
}
@Override
public long nextLong()
{
x ^= (x << 21);
x ^= (x >>> 35);
x ^= (x << 4);
return x;
}
@Override
protected int next(int bits)
{
return (int) (nextLong() & ((1L << bits) - 1));
}
@Override
public void setSeed(long seed)
{
this.x = seed;
}
}
hppc-0.6.1/hppc-core/src/main/java/com/carrotsearch/hppc/cursors/ 0000775 0000000 0000000 00000000000 12403265743 0024662 5 ustar 00root root 0000000 0000000 hppc-0.6.1/hppc-core/src/main/java/com/carrotsearch/hppc/cursors/package.html 0000664 0000000 0000000 00000000615 12403265743 0027145 0 ustar 00root root 0000000 0000000
High Performance Primitive Collections (HPPC): cursors
Cursors are primitive data holders used in iterators.