Skip to content

Commit

Permalink
Merge ad986f2 into 4a0cf04
Browse files Browse the repository at this point in the history
  • Loading branch information
khitrin committed Jul 7, 2018
2 parents 4a0cf04 + ad986f2 commit 2f475e2
Show file tree
Hide file tree
Showing 9 changed files with 525 additions and 6 deletions.
16 changes: 13 additions & 3 deletions roaringbitmap/src/main/java/org/roaringbitmap/ArrayContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,12 @@ public PeekableShortIterator getShortIterator() {
return new ArrayContainerShortIterator(this);
}

@Override
public PeekableShortRankIterator getShortRankIterator() {
// for ArrayContainer there is no additional work, pos is known in advance
return new ArrayContainerShortIterator(this);
}

@Override
public ContainerBatchIterator getBatchIterator() {
return new ArrayBatchIterator(this);
Expand Down Expand Up @@ -1295,7 +1301,7 @@ protected Container lazyor(ArrayContainer value2) {
}


final class ArrayContainerShortIterator implements PeekableShortIterator {
final class ArrayContainerShortIterator implements PeekableShortRankIterator {
int pos;
ArrayContainer parent;

Expand All @@ -1310,11 +1316,15 @@ public void advanceIfNeeded(short minval) {
pos = Util.advanceUntil(parent.content, pos - 1, parent.cardinality, minval);
}

@Override
public short peekNextRank() {
return (short) (pos + 1);
}

@Override
public PeekableShortIterator clone() {
public PeekableShortRankIterator clone() {
try {
return (PeekableShortIterator) super.clone();
return (PeekableShortRankIterator) super.clone();
} catch (CloneNotSupportedException e) {
return null;// will not happen
}
Expand Down
60 changes: 58 additions & 2 deletions roaringbitmap/src/main/java/org/roaringbitmap/BitmapContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import java.util.Arrays;
import java.util.Iterator;

import static java.lang.Long.numberOfLeadingZeros;
import static java.lang.Long.bitCount;
import static java.lang.Long.numberOfTrailingZeros;


Expand Down Expand Up @@ -505,6 +505,11 @@ public PeekableShortIterator getShortIterator() {
return new BitmapContainerShortIterator(this.bitmap);
}

@Override
public PeekableShortRankIterator getShortRankIterator() {
return new BitmapContainerShortRankIterator(this.bitmap);
}

@Override
public ContainerBatchIterator getBatchIterator() {
return new BitmapBatchIterator(this);
Expand Down Expand Up @@ -1371,7 +1376,7 @@ public int last() {
}


final class BitmapContainerShortIterator implements PeekableShortIterator {
class BitmapContainerShortIterator implements PeekableShortIterator {

long w;
int x;
Expand Down Expand Up @@ -1459,6 +1464,57 @@ public short peekNext() {
}
}

final class BitmapContainerShortRankIterator extends BitmapContainerShortIterator
implements PeekableShortRankIterator {
short nextRank = 1;

public BitmapContainerShortRankIterator(long[] p) {
super(p);
}

@Override
public short peekNextRank() {
return nextRank;
}

@Override
public short next() {
++nextRank;
return super.next();
}

@Override
public void advanceIfNeeded(short minval) {
if (Util.toIntUnsigned(minval) >= (x + 1) * 64) {

int nextX = Util.toIntUnsigned(minval) / 64;
nextRank += bitCount(w);
for(x = x + 1; x < nextX; ++x) {
w = bitmap[x];
nextRank += bitCount(w);
}

x = nextX;
w = bitmap[x];

while (w == 0) {
++x;
if (x == bitmap.length) {
return;
}
w = bitmap[x];
}
}
while (hasNext() && (Util.toIntUnsigned(peekNext()) < Util.toIntUnsigned(minval))) {
next(); // could be optimized
}
}

@Override
public PeekableShortRankIterator clone() {
return (PeekableShortRankIterator) super.clone();
}
}

final class ReverseBitmapContainerShortIterator implements ShortIterator {

Expand Down
7 changes: 7 additions & 0 deletions roaringbitmap/src/main/java/org/roaringbitmap/Container.java
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,13 @@ public String getContainerName() {
*/
public abstract PeekableShortIterator getShortIterator();

/**
* Iterator to visit the short values in container and pre-compute ranks
*
* @return iterator
*/
public abstract PeekableShortRankIterator getShortRankIterator();

/**
* Gets an iterator to visit the contents of the container in batches
* @return iterator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,4 +252,93 @@ public int select(int j) {

return value;
}

/**
* Get a special iterator that allows .peekNextRank efficiently
*
* @return iterator with fast rank access
*/
public PeekableIntRankIterator getIntRankIterator() {
preComputeCardinalities();
return new FastRoaringIntRankIterator();
}

private class FastRoaringIntRankIterator implements PeekableIntRankIterator {
private int hs = 0;

private PeekableShortRankIterator iter;

private int pos = 0;

private FastRoaringIntRankIterator() {
nextContainer();
}

@Override
public int peekNextRank() {
int iterRank = Util.toIntUnsigned(iter.peekNextRank());
if (pos > 0) {
return FastRankRoaringBitmap.this.highToCumulatedCardinality[pos - 1] + iterRank;
} else {
return iterRank;
}
}

@Override
public PeekableIntRankIterator clone() {
try {
FastRoaringIntRankIterator x =
(FastRoaringIntRankIterator) super.clone();
if (this.iter != null) {
x.iter = this.iter.clone();
}
return x;
} catch (CloneNotSupportedException e) {
return null;// will not happen
}
}

@Override
public boolean hasNext() {
return pos < FastRankRoaringBitmap.this.highLowContainer.size();
}

@Override
public int next() {
final int x = iter.nextAsInt() | hs;
if (!iter.hasNext()) {
++pos;
nextContainer();
}
return x;
}

private void nextContainer() {
if (pos < FastRankRoaringBitmap.this.highLowContainer.size()) {
iter = FastRankRoaringBitmap.this.highLowContainer.getContainerAtIndex(pos)
.getShortRankIterator();
hs = FastRankRoaringBitmap.this.highLowContainer.getKeyAtIndex(pos) << 16;
}
}

@Override
public void advanceIfNeeded(int minval) {
while (hasNext() && ((hs >>> 16) < (minval >>> 16))) {
++pos;
nextContainer();
}
if (hasNext() && ((hs >>> 16) == (minval >>> 16))) {
iter.advanceIfNeeded(Util.lowbits(minval));
if (!iter.hasNext()) {
++pos;
nextContainer();
}
}
}

@Override
public int peekNext() {
return Util.toIntUnsigned(iter.peekNext()) | hs;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.roaringbitmap;

/**
* PeekableIntIterator that calculates the next value rank during iteration
*/
public interface PeekableIntRankIterator extends PeekableIntIterator {
/**
* Look at rank of the next value without advancing
*
* @return rank of next value
*/
int peekNextRank();

@Override
PeekableIntRankIterator clone();
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.roaringbitmap;

/**
* PeekableShortIterator that calculates the next value rank during iteration
*/
public interface PeekableShortRankIterator extends PeekableShortIterator {

/**
* peek in-container rank of the next value
* @return rank of the next value
*/
short peekNextRank();

@Override
PeekableShortRankIterator clone();
}
62 changes: 61 additions & 1 deletion roaringbitmap/src/main/java/org/roaringbitmap/RunContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -1058,6 +1058,11 @@ public PeekableShortIterator getShortIterator() {
return new RunContainerShortIterator(this);
}

@Override
public PeekableShortRankIterator getShortRankIterator() {
return new RunContainerShortRankIterator(this);
}

@Override
public ContainerBatchIterator getBatchIterator() {
return new RunBatchIterator(this);
Expand Down Expand Up @@ -2568,7 +2573,7 @@ public int last() {
}


final class RunContainerShortIterator implements PeekableShortIterator {
class RunContainerShortIterator implements PeekableShortIterator {
int pos;
int le = 0;
int maxlength;
Expand Down Expand Up @@ -2668,6 +2673,61 @@ public short peekNext() {

}

class RunContainerShortRankIterator extends RunContainerShortIterator
implements PeekableShortRankIterator {

short nextRank = 1;

public RunContainerShortRankIterator(RunContainer p) {
super(p);
}

@Override
public short next() {
++nextRank;
return super.next();
}

@Override
public int nextAsInt() {
++nextRank;
return super.nextAsInt();
}

@Override
public void advanceIfNeeded(short minval) {
while (base + maxlength < toIntUnsigned(minval)) {
nextRank += maxlength - le + 1;

pos++;
le = 0;
if (pos < parent.nbrruns) {
maxlength = toIntUnsigned(parent.getLength(pos));
base = toIntUnsigned(parent.getValue(pos));
} else {
return;
}
}

if (base > toIntUnsigned(minval)) {
return;
}
int nextLe = toIntUnsigned(minval) - base;

nextRank += nextLe - le;
le = nextLe;
}

@Override
public short peekNextRank() {
return nextRank;
}

@Override
public RunContainerShortRankIterator clone() {
return (RunContainerShortRankIterator) super.clone();
}
}


final class ReverseRunContainerShortIterator implements ShortIterator {
Expand Down
Loading

0 comments on commit 2f475e2

Please sign in to comment.