use of org.roaringbitmap.BitmapDataProvider in project RoaringBitmap by RoaringBitmap.
the class Roaring64NavigableMap method rankLongNoCache.
// https://github.com/RoaringBitmap/CRoaring/blob/master/cpp/roaring64map.hh
private long rankLongNoCache(int high, int low) {
long result = 0L;
BitmapDataProvider lastBitmap = highToBitmap.get(high);
if (lastBitmap == null) {
// There is no value with same high: the rank is a sum of cardinalities
for (Entry<Integer, BitmapDataProvider> bitmap : highToBitmap.entrySet()) {
if (bitmap.getKey().intValue() > high) {
break;
} else {
result += bitmap.getValue().getLongCardinality();
}
}
} else {
for (BitmapDataProvider bitmap : highToBitmap.values()) {
if (bitmap == lastBitmap) {
result += bitmap.rankLong(low);
break;
} else {
result += bitmap.getLongCardinality();
}
}
}
return result;
}
use of org.roaringbitmap.BitmapDataProvider in project RoaringBitmap by RoaringBitmap.
the class TestRoaring64NavigableMap method checkCardinalities.
protected void checkCardinalities(Roaring64NavigableMap bitmap) {
NavigableMap<Integer, BitmapDataProvider> highToBitmap = bitmap.getHighToBitmap();
int lowestHighNotValid = bitmap.getLowestInvalidHigh();
NavigableMap<Integer, BitmapDataProvider> expectedToBeCorrect = highToBitmap.headMap(lowestHighNotValid, false);
long[] expectedCardinalities = new long[expectedToBeCorrect.size()];
Iterator<BitmapDataProvider> it = expectedToBeCorrect.values().iterator();
int index = 0;
while (it.hasNext()) {
BitmapDataProvider next = it.next();
if (index == 0) {
expectedCardinalities[0] = next.getLongCardinality();
} else {
expectedCardinalities[index] = expectedCardinalities[index - 1] + next.getLongCardinality();
}
index++;
}
Assert.assertArrayEquals(expectedCardinalities, Arrays.copyOf(bitmap.getSortedCumulatedCardinality(), expectedCardinalities.length));
}
use of org.roaringbitmap.BitmapDataProvider in project RoaringBitmap by RoaringBitmap.
the class Roaring64NavigableMap method andNot.
/**
* In-place bitwise ANDNOT (difference) operation. The current bitmap is modified.
*
* @param x2 other bitmap
*/
public void andNot(final Roaring64NavigableMap x2) {
boolean firstBucket = true;
Iterator<Entry<Integer, BitmapDataProvider>> thisIterator = highToBitmap.entrySet().iterator();
while (thisIterator.hasNext()) {
Entry<Integer, BitmapDataProvider> e1 = thisIterator.next();
// Keep object to prevent auto-boxing
Integer high = e1.getKey();
BitmapDataProvider lowBitmap2 = x2.highToBitmap.get(high);
if (lowBitmap2 != null) {
BitmapDataProvider lowBitmap1 = e1.getValue();
if (lowBitmap2 instanceof RoaringBitmap && lowBitmap1 instanceof RoaringBitmap) {
((RoaringBitmap) lowBitmap1).andNot((RoaringBitmap) lowBitmap2);
} else if (lowBitmap2 instanceof MutableRoaringBitmap && lowBitmap1 instanceof MutableRoaringBitmap) {
((MutableRoaringBitmap) lowBitmap1).andNot((MutableRoaringBitmap) lowBitmap2);
} else {
throw new UnsupportedOperationException(".and is not between " + this.getClass() + " and " + lowBitmap1.getClass());
}
}
if (firstBucket) {
firstBucket = false;
// Invalidate the lowest high as lowest not valid
firstHighNotValid = Math.min(firstHighNotValid, high);
allValid = false;
}
}
}
use of org.roaringbitmap.BitmapDataProvider in project RoaringBitmap by RoaringBitmap.
the class Roaring64NavigableMap method xor.
/**
* In-place bitwise XOR (symmetric difference) operation. The current bitmap is modified.
*
* @param x2 other bitmap
*/
public void xor(final Roaring64NavigableMap x2) {
boolean firstBucket = true;
for (Entry<Integer, BitmapDataProvider> e2 : x2.highToBitmap.entrySet()) {
// Keep object to prevent auto-boxing
Integer high = e2.getKey();
BitmapDataProvider lowBitmap1 = this.highToBitmap.get(high);
BitmapDataProvider lowBitmap2 = e2.getValue();
// not on buffer
if ((lowBitmap1 == null || lowBitmap1 instanceof RoaringBitmap) && lowBitmap2 instanceof RoaringBitmap) {
if (lowBitmap1 == null) {
// Clone to prevent future modification of this modifying the input Bitmap
RoaringBitmap lowBitmap2Clone = ((RoaringBitmap) lowBitmap2).clone();
pushBitmapForHigh(high, lowBitmap2Clone);
} else {
((RoaringBitmap) lowBitmap1).xor((RoaringBitmap) lowBitmap2);
}
} else if ((lowBitmap1 == null || lowBitmap1 instanceof MutableRoaringBitmap) && lowBitmap2 instanceof MutableRoaringBitmap) {
if (lowBitmap1 == null) {
// Clone to prevent future modification of this modifying the input Bitmap
BitmapDataProvider lowBitmap2Clone = ((MutableRoaringBitmap) lowBitmap2).clone();
pushBitmapForHigh(high, lowBitmap2Clone);
} else {
((MutableRoaringBitmap) lowBitmap1).xor((MutableRoaringBitmap) lowBitmap2);
}
} else {
throw new UnsupportedOperationException(".or is not between " + this.getClass() + " and " + lowBitmap2.getClass());
}
if (firstBucket) {
firstBucket = false;
// Invalidate the lowest high as lowest not valid
firstHighNotValid = Math.min(firstHighNotValid, high);
allValid = false;
}
}
}
use of org.roaringbitmap.BitmapDataProvider in project RoaringBitmap by RoaringBitmap.
the class Roaring64NavigableMap method select.
/**
* Return the jth value stored in this bitmap.
*
* @param j index of the value
*
* @return the value
* @throws IllegalArgumentException if j is out of the bounds of the bitmap cardinality
*/
@Override
public long select(final long j) throws IllegalArgumentException {
if (!doCacheCardinalities) {
return selectNoCache(j);
}
// Ensure all cumulatives as we we have straightforward way to know in advance the high of the
// j-th value
int indexOk = ensureCumulatives(highestHigh());
if (highToBitmap.isEmpty()) {
return throwSelectInvalidIndex(j);
}
// Use normal binarySearch as cardinality does not depends on considering longs signed or
// unsigned
// We need sortedCumulatedCardinality not to contain duplicated, else binarySearch may return
// any of the duplicates: we need to ensure it holds no high associated to an empty bitmap
int position = Arrays.binarySearch(sortedCumulatedCardinality, 0, indexOk, j);
if (position >= 0) {
if (position == indexOk - 1) {
// .select has been called on this.getCardinality
return throwSelectInvalidIndex(j);
}
// There is a bucket leading to this cardinality: the j-th element is the first element of
// next bucket
int high = sortedHighs[position + 1];
BitmapDataProvider nextBitmap = highToBitmap.get(high);
return RoaringIntPacking.pack(high, nextBitmap.select(0));
} else {
// There is no bucket with this cardinality
int insertionPoint = -position - 1;
final long previousBucketCardinality;
if (insertionPoint == 0) {
previousBucketCardinality = 0L;
} else if (insertionPoint >= indexOk) {
return throwSelectInvalidIndex(j);
} else {
previousBucketCardinality = sortedCumulatedCardinality[insertionPoint - 1];
}
// We get a 'select' query for a single bitmap: should fit in an int
final int givenBitmapSelect = (int) (j - previousBucketCardinality);
int high = sortedHighs[insertionPoint];
BitmapDataProvider lowBitmap = highToBitmap.get(high);
int low = lowBitmap.select(givenBitmapSelect);
return RoaringIntPacking.pack(high, low);
}
}
Aggregations