Fix empty results on ExtractionFilter.

* Now returns empty results rather than erroring out
* Added unit tests for multiples case
This commit is contained in:
Charles Allen 2015-02-10 09:54:04 -08:00
parent 1418cbb0e9
commit b9cb311a52
2 changed files with 156 additions and 5 deletions

View File

@ -19,6 +19,7 @@ package io.druid.segment.filter;
import com.google.common.collect.Lists;
import com.metamx.collections.bitmap.ImmutableBitmap;
import com.metamx.collections.bitmap.WrappedConciseBitmap;
import io.druid.query.extraction.DimExtractionFn;
import io.druid.query.filter.BitmapIndexSelector;
import io.druid.query.filter.Filter;
@ -52,11 +53,12 @@ public class ExtractionFilter implements Filter
{
final Indexed<String> allDimVals = selector.getDimensionValues(dimension);
final List<Filter> filters = Lists.newArrayList();
for (int i = 0; i < allDimVals.size(); i++) {
String dimVal = allDimVals.get(i);
if (value.equals(fn.apply(dimVal))) {
filters.add(new SelectorFilter(dimension, dimVal));
if (allDimVals != null) {
for (int i = 0; i < allDimVals.size(); i++) {
String dimVal = allDimVals.get(i);
if (value.equals(fn.apply(dimVal))) {
filters.add(new SelectorFilter(dimension, dimVal));
}
}
}
@ -66,6 +68,10 @@ public class ExtractionFilter implements Filter
@Override
public ImmutableBitmap getBitmapIndex(BitmapIndexSelector selector)
{
final List<Filter> filters = makeFilters(selector);
if (filters.isEmpty()) {
return new WrappedConciseBitmap();
}
return new OrFilter(makeFilters(selector)).getBitmapIndex(selector);
}

View File

@ -0,0 +1,145 @@
/*
* Druid - a distributed column store.
* Copyright 2012 - 2015 Metamarkets Group Inc.
*
* Licensed 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 io.druid.segment.filter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.metamx.collections.bitmap.BitmapFactory;
import com.metamx.collections.bitmap.ConciseBitmapFactory;
import com.metamx.collections.bitmap.ImmutableBitmap;
import com.metamx.collections.bitmap.WrappedConciseBitmap;
import com.metamx.collections.spatial.ImmutableRTree;
import io.druid.query.extraction.DimExtractionFn;
import io.druid.query.filter.BitmapIndexSelector;
import io.druid.query.filter.Filter;
import io.druid.segment.data.ArrayIndexed;
import io.druid.segment.data.Indexed;
import it.uniroma3.mat.extendedset.intset.ConciseSet;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Collection;
import java.util.Map;
/**
*
*/
public class ExtractionDimFilterTest
{
private static final Map<String, String[]> DIM_VALS = ImmutableMap.<String, String[]>of(
"foo", new String[]{"foo1","foo2","foo3"},
"bar", new String[]{"bar1"},
"baz", new String[]{"foo1"}
);
private static final Map<String, String> EXTRACTION_VALUES = ImmutableMap.of(
"foo1","extractDimVal"
);
private static ImmutableBitmap foo1BitMap;
@BeforeClass
public static void setupStatic(){
final ConciseSet conciseSet = new ConciseSet();
conciseSet.add(1);
foo1BitMap = new WrappedConciseBitmap(conciseSet);
}
private static final BitmapIndexSelector BITMAP_INDEX_SELECTOR = new BitmapIndexSelector()
{
@Override
public Indexed<String> getDimensionValues(String dimension)
{
final String[] vals = DIM_VALS.get(dimension);
return vals == null ? null : new ArrayIndexed<String>(vals, String.class);
}
@Override
public int getNumRows()
{
return 1;
}
@Override
public BitmapFactory getBitmapFactory()
{
return new ConciseBitmapFactory();
}
@Override
public ImmutableBitmap getBitmapIndex(String dimension, String value)
{
return "foo1".equals(value) ? foo1BitMap : null;
}
@Override
public ImmutableRTree getSpatialIndex(String dimension)
{
return null;
}
};
private static final DimExtractionFn DIM_EXTRACTION_FN = new DimExtractionFn()
{
@Override
public byte[] getCacheKey()
{
return new byte[0];
}
@Override
public String apply(String dimValue)
{
final String retval = EXTRACTION_VALUES.get(dimValue);
return retval == null ? dimValue : retval;
}
@Override
public boolean preservesOrdering()
{
return false;
}
};
@Test
public void testEmpty(){
ExtractionFilter extractionFilter = new ExtractionFilter(
"foo", "NFDJUKFNDSJFNS", DIM_EXTRACTION_FN
);
ImmutableBitmap immutableBitmap = extractionFilter.getBitmapIndex(BITMAP_INDEX_SELECTOR);
Assert.assertEquals(0, immutableBitmap.size());
}
@Test
public void testNull(){
ExtractionFilter extractionFilter = new ExtractionFilter(
"FDHJSFFHDS", "extractDimVal", DIM_EXTRACTION_FN
);
ImmutableBitmap immutableBitmap = extractionFilter.getBitmapIndex(BITMAP_INDEX_SELECTOR);
Assert.assertEquals(0, immutableBitmap.size());
}
@Test
public void testNormal(){
ExtractionFilter extractionFilter = new ExtractionFilter(
"foo", "extractDimVal", DIM_EXTRACTION_FN
);
ImmutableBitmap immutableBitmap = extractionFilter.getBitmapIndex(BITMAP_INDEX_SELECTOR);
Assert.assertEquals(1, immutableBitmap.size());
}
}