Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@

package io.druid.collections.bitmap;

import com.google.common.collect.Iterables;
import io.druid.extendedset.intset.ImmutableConciseSet;

import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Iterator;

import io.druid.extendedset.intset.ImmutableConciseSet;

/**
* As the name suggests, this class instantiates bitmaps of the types
* WrappedConciseBitmap and WrappedImmutableConciseBitmap.
Expand Down Expand Up @@ -109,6 +111,16 @@ public ImmutableBitmap mapImmutableBitmap(ByteBuffer b)
public ImmutableBitmap union(Iterable<ImmutableBitmap> b)
throws ClassCastException
{
if (b instanceof Collection) {
final Collection<ImmutableBitmap> bitmapList = (Collection<ImmutableBitmap>) b;
final int size = bitmapList.size();
if (size == 0) {
return makeEmptyImmutableBitmap();
} else if (size == 1) {
return Iterables.getOnlyElement(b);
}
}

return new WrappedImmutableConciseBitmap(ImmutableConciseSet.union(unwrap(b)));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@
package io.druid.collections.bitmap;

import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;
import org.roaringbitmap.RoaringBitmap;
import org.roaringbitmap.buffer.BufferFastAggregation;
import org.roaringbitmap.buffer.ImmutableRoaringBitmap;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Iterator;

/**
Expand Down Expand Up @@ -142,6 +144,16 @@ public ImmutableBitmap mapImmutableBitmap(ByteBuffer b)
@Override
public ImmutableBitmap union(Iterable<ImmutableBitmap> b)
{
if (b instanceof Collection) {
final Collection<ImmutableBitmap> bitmapList = (Collection<ImmutableBitmap>) b;
final int size = bitmapList.size();
if (size == 0) {
return makeEmptyImmutableBitmap();
} else if (size == 1) {
return Iterables.getOnlyElement(b);
}
}

return new WrappedImmutableRoaringBitmap(ImmutableRoaringBitmap.or(unwrap(b).iterator()));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,13 @@ public double estimateSelectivity(BitmapIndexSelector indexSelector)
return doesMatch(null) ? 1. : 0.;
}

return Filters.estimatePredicateSelectivity(
return Filters.estimateSelectivity(
bitmapIndex,
getBitmapIndexList(boundDimFilter, bitmapIndex),
indexSelector.getNumRows()
);
} else {
return Filters.estimatePredicateSelectivity(
return Filters.estimateSelectivity(
boundDimFilter.getDimension(),
indexSelector,
getPredicateFactory().makeStringPredicate()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public boolean supportsSelectivityEstimation(
@Override
public double estimateSelectivity(BitmapIndexSelector indexSelector)
{
return Filters.estimatePredicateSelectivity(
return Filters.estimateSelectivity(
dimension,
indexSelector,
predicateFactory.makeStringPredicate()
Expand Down
82 changes: 65 additions & 17 deletions processing/src/main/java/io/druid/segment/filter/Filters.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package io.druid.segment.filter;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
Expand Down Expand Up @@ -245,13 +244,33 @@ public void remove()
*
* @return bitmap of matching rows
*
* @see #estimatePredicateSelectivity(String, BitmapIndexSelector, Predicate)
* @see #estimateSelectivity(String, BitmapIndexSelector, Predicate)
*/
public static ImmutableBitmap matchPredicate(
final String dimension,
final BitmapIndexSelector selector,
final Predicate<String> predicate
)
{
return selector.getBitmapFactory().union(matchPredicateNoUnion(dimension, selector, predicate));
}

/**
* Return an iterable of bitmaps for all values matching a particular predicate. Unioning these bitmaps
* yields the same result that {@link #matchPredicate(String, BitmapIndexSelector, Predicate)} would have
* returned.
*
* @param dimension dimension to look at
* @param selector bitmap selector
* @param predicate predicate to use
*
* @return iterable of bitmaps of matching rows
*/
public static Iterable<ImmutableBitmap> matchPredicateNoUnion(
final String dimension,
final BitmapIndexSelector selector,
final Predicate<String> predicate
)
{
Preconditions.checkNotNull(dimension, "dimension");
Preconditions.checkNotNull(selector, "selector");
Expand All @@ -260,27 +279,26 @@ public static ImmutableBitmap matchPredicate(
// Missing dimension -> match all rows if the predicate matches null; match no rows otherwise
final Indexed<String> dimValues = selector.getDimensionValues(dimension);
if (dimValues == null || dimValues.size() == 0) {
return predicate.apply(null) ? allTrue(selector) : allFalse(selector);
return ImmutableList.of(predicate.apply(null) ? allTrue(selector) : allFalse(selector));
}

// Apply predicate to all dimension values and union the matching bitmaps
final BitmapIndex bitmapIndex = selector.getBitmapIndex(dimension);
return selector.getBitmapFactory()
.union(makePredicateQualifyingBitmapIterable(bitmapIndex, predicate, dimValues));
return makePredicateQualifyingBitmapIterable(bitmapIndex, predicate, dimValues);
}

/**
* Return an estimated selectivity for bitmaps of all values matching the given predicate.
*
* @param dimension dimension to look at
* @param indexSelector bitmap selector
* @param predicate predicate to use
* @param dimension dimension to look at
* @param indexSelector bitmap selector
* @param predicate predicate to use
*
* @return estimated selectivity
*
* @see #matchPredicate(String, BitmapIndexSelector, Predicate)
*/
static double estimatePredicateSelectivity(
public static double estimateSelectivity(
final String dimension,
final BitmapIndexSelector indexSelector,
final Predicate<String> predicate
Expand All @@ -298,23 +316,53 @@ static double estimatePredicateSelectivity(

// Apply predicate to all dimension values and union the matching bitmaps
final BitmapIndex bitmapIndex = indexSelector.getBitmapIndex(dimension);
return estimatePredicateSelectivity(
return estimateSelectivity(
bitmapIndex,
IntIteratorUtils.toIntList(makePredicateQualifyingIndexIterable(bitmapIndex, predicate, dimValues).iterator()),
indexSelector.getNumRows()
);
}

@VisibleForTesting
static double estimatePredicateSelectivity(
BitmapIndex bitmapIndex,
IntList bitmapIndexes,
long totalNumRows
/**
* Return an estimated selectivity for bitmaps for the dimension values given by dimValueIndexes.
*
* @param bitmapIndex bitmap index
* @param bitmaps bitmaps to extract, by index
* @param totalNumRows number of rows in the column associated with this bitmap index
*
* @return estimated selectivity
*/
public static double estimateSelectivity(
final BitmapIndex bitmapIndex,
final IntList bitmaps,
final long totalNumRows
)
{
long numMatchedRows = 0;
for (int i = 0; i < bitmaps.size(); i++) {
final ImmutableBitmap bitmap = bitmapIndex.getBitmap(bitmaps.get(i));
numMatchedRows += bitmap.size();
}

return Math.min(1., (double) numMatchedRows / totalNumRows);
}

/**
* Return an estimated selectivity for bitmaps given by an iterator.
*
* @param bitmaps iterator of bitmaps
* @param totalNumRows number of rows in the column associated with this bitmap index
*
* @return estimated selectivity
*/
public static double estimateSelectivity(
final Iterator<ImmutableBitmap> bitmaps,
final long totalNumRows
)
{
long numMatchedRows = 0;
for (int i = 0; i < bitmapIndexes.size(); i++) {
final ImmutableBitmap bitmap = bitmapIndex.getBitmap(bitmapIndexes.get(i));
while (bitmaps.hasNext()) {
final ImmutableBitmap bitmap = bitmaps.next();
numMatchedRows += bitmap.size();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,13 @@ public double estimateSelectivity(BitmapIndexSelector indexSelector)
{
if (extractionFn == null) {
final BitmapIndex bitmapIndex = indexSelector.getBitmapIndex(dimension);
return Filters.estimatePredicateSelectivity(
return Filters.estimateSelectivity(
bitmapIndex,
IntIteratorUtils.toIntList(getBitmapIndexIterable(bitmapIndex).iterator()),
indexSelector.getNumRows()
);
} else {
return Filters.estimatePredicateSelectivity(
return Filters.estimateSelectivity(
dimension,
indexSelector,
getPredicateFactory().makeStringPredicate()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public double estimateSelectivity(BitmapIndexSelector indexSelector)
{
final Context cx = Context.enter();
try {
return Filters.estimatePredicateSelectivity(dimension, indexSelector, makeStringPredicate(cx));
return Filters.estimateSelectivity(dimension, indexSelector, makeStringPredicate(cx));
}
finally {
Context.exit();
Expand Down
Loading