Skip to content

Commit bea55d4

Browse files
authored
Avoid intermediate arrays for other container types (#716)
1 parent 0905e73 commit bea55d4

File tree

6 files changed

+48
-6
lines changed

6 files changed

+48
-6
lines changed

RoaringBitmap/src/main/java/org/roaringbitmap/ArrayContainer.java

+8
Original file line numberDiff line numberDiff line change
@@ -1129,6 +1129,14 @@ public BitmapContainer toBitmapContainer() {
11291129
return bc;
11301130
}
11311131

1132+
@Override
1133+
public void copyBitmapTo(long[] dest, int position) {
1134+
for (int k = 0; k < cardinality; ++k) {
1135+
final char x = content[k];
1136+
dest[position + x/64] |= 1L << x;
1137+
}
1138+
}
1139+
11321140
@Override
11331141
public int nextValue(char fromValue) {
11341142
int index = Util.advanceUntil(content, -1, cardinality, fromValue);

RoaringBitmap/src/main/java/org/roaringbitmap/BitSetUtil.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,14 @@ public static long[] toLongArray(RoaringBitmap bitmap) {
8585
for (int i = 0; i <= numContainers; i++) {
8686
char key = Util.lowbits(i);
8787
if (key == pointer.key()) {
88-
BitmapContainer container = pointer.getContainer().toBitmapContainer();
88+
Container container = pointer.getContainer();
8989
int remaining = wordsInUse - position;
9090
int length = Math.min(BLOCK_LENGTH, remaining);
91-
container.copyBitmapTo(words, position, length);
91+
if (container instanceof BitmapContainer) {
92+
((BitmapContainer)container).copyBitmapTo(words, position, length);
93+
} else {
94+
container.copyBitmapTo(words, position);
95+
}
9296
position += length;
9397
pointer.advance();
9498
if (pointer.getContainer() == null) {

RoaringBitmap/src/main/java/org/roaringbitmap/BitmapContainer.java

+9-4
Original file line numberDiff line numberDiff line change
@@ -1665,6 +1665,15 @@ public BitmapContainer toBitmapContainer() {
16651665
return this;
16661666
}
16671667

1668+
@Override
1669+
public void copyBitmapTo(long[] words, int position) {
1670+
System.arraycopy(bitmap, 0, words, position, bitmap.length);
1671+
}
1672+
1673+
public void copyBitmapTo(long[] words, int position, int length) {
1674+
System.arraycopy(bitmap, 0, words, position, length);
1675+
}
1676+
16681677
@Override
16691678
public int nextValue(char fromValue) {
16701679
return nextSetBit((fromValue));
@@ -1706,10 +1715,6 @@ public int last() {
17061715
// sizeof(long) * #words from start - number of bits after the last bit set
17071716
return (i + 1) * 64 - Long.numberOfLeadingZeros(bitmap[i]) - 1;
17081717
}
1709-
1710-
public void copyBitmapTo(long[] words, int position, int length) {
1711-
System.arraycopy(bitmap, 0, words, position, length);
1712-
}
17131718
}
17141719

17151720

RoaringBitmap/src/main/java/org/roaringbitmap/Container.java

+11
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,17 @@ public Container xor(Container x) {
986986
*/
987987
public abstract BitmapContainer toBitmapContainer();
988988

989+
/**
990+
* Copy the current container to a destination {@code long[]}. Equivalent to calling
991+
* {@link #toBitmapContainer()} and copying the result to the given position. The destination
992+
* array should be sized to accomodate the maximum number of words required to represent
993+
* the container bitmap.
994+
*
995+
* @param dest the destination array
996+
* @param position the position to copy to
997+
*/
998+
public abstract void copyBitmapTo(long[] dest, int position);
999+
9891000
/**
9901001
* Gets the first value greater than or equal to the lower bound, or -1 if no such value exists.
9911002
* @param fromValue the lower bound (inclusive)

RoaringBitmap/src/main/java/org/roaringbitmap/RunContainer.java

+10
Original file line numberDiff line numberDiff line change
@@ -2659,6 +2659,16 @@ public BitmapContainer toBitmapContainer() {
26592659
return answer;
26602660
}
26612661

2662+
@Override
2663+
public void copyBitmapTo(long[] dest, int position) {
2664+
int offset = position * Long.SIZE;
2665+
for (int rlepos = 0; rlepos < this.nbrruns; ++rlepos) {
2666+
int start = offset + this.getValue(rlepos);
2667+
int end = start + this.getLength(rlepos) + 1;
2668+
Util.setBitmapRange(dest, start, end);
2669+
}
2670+
}
2671+
26622672
@Override
26632673
public int nextValue(char fromValue) {
26642674
int index = unsignedInterleavedBinarySearch(valueslength, 0, nbrruns, fromValue);

RoaringBitmap/src/test/java/org/roaringbitmap/TestBitSetUtil.java

+4
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ private void assertEqualBitsets(final BitSet bitset, final RoaringBitmap bitmap)
3131
assertEquals(bitset, BitSetUtil.bitsetOf(bitmap), "bitsetOf doesn't match");
3232
assertEquals(bitset, BitSetUtil.bitsetOfWithoutCopy(bitmap), "bitsetOfWithoutCopy doesn't match");
3333
assertEquals(bitset, BitSet.valueOf(BitSetUtil.toByteArray(bitmap)), "toByteArray doesn't match");
34+
35+
RoaringBitmap runBitmap = bitmap.clone();
36+
runBitmap.runOptimize();
37+
assertEquals(bitset, BitSetUtil.bitsetOf(runBitmap), "bitsetOf doesn't match for run optimized bitmap");
3438
}
3539

3640
@Test

0 commit comments

Comments
 (0)