use of java.util.BitSet in project druid by druid-io.
the class ForwardingFilteredDimensionSelector method makeValueMatcher.
@Override
public ValueMatcher makeValueMatcher(Predicate<String> predicate) {
final BitSet valueIds = DimensionSelectorUtils.makePredicateMatchingSet(this, predicate);
final boolean matchNull = predicate.apply(null);
return new ValueMatcher() {
@Override
public boolean matches() {
final IndexedInts baseRow = selector.getRow();
final int baseRowSize = baseRow.size();
boolean nullRow = true;
for (int i = 0; i < baseRowSize; ++i) {
int forwardedValue = forwardMapping.get(baseRow.get(i));
if (forwardedValue >= 0) {
if (valueIds.get(forwardedValue)) {
return true;
}
nullRow = false;
}
}
// null should match empty rows in multi-value columns
return nullRow && matchNull;
}
};
}
use of java.util.BitSet in project druid by druid-io.
the class DimensionSelectorUtils method makePredicateMatchingSet.
public static BitSet makePredicateMatchingSet(DimensionSelector selector, Predicate<String> predicate) {
if (!selector.nameLookupPossibleInAdvance()) {
throw new IAE("selector.nameLookupPossibleInAdvance() should return true");
}
int cardinality = selector.getValueCardinality();
BitSet valueIds = new BitSet(cardinality);
for (int i = 0; i < cardinality; i++) {
if (predicate.apply(selector.lookupName(i))) {
valueIds.set(i);
}
}
return valueIds;
}
use of java.util.BitSet in project druid by druid-io.
the class StringDimensionIndexer method makeDimensionSelector.
@Override
public DimensionSelector makeDimensionSelector(final DimensionSpec spec, final IncrementalIndexStorageAdapter.EntryHolder currEntry, final IncrementalIndex.DimensionDesc desc) {
final ExtractionFn extractionFn = spec.getExtractionFn();
final int dimIndex = desc.getIndex();
final int maxId = getCardinality();
class IndexerDimensionSelector implements DimensionSelector, IdLookup {
@Override
public IndexedInts getRow() {
final Object[] dims = currEntry.getKey().getDims();
int[] indices;
if (dimIndex < dims.length) {
indices = (int[]) dims[dimIndex];
} else {
indices = null;
}
int[] row = null;
int rowSize = 0;
if (indices == null || indices.length == 0) {
final int nullId = getEncodedValue(null, false);
if (nullId > -1) {
if (nullId < maxId) {
row = new int[] { nullId };
rowSize = 1;
} else {
// Choose to use ArrayBasedIndexedInts later, instead of EmptyIndexedInts, for monomorphism
row = IntArrays.EMPTY_ARRAY;
rowSize = 0;
}
}
}
if (row == null && indices != null && indices.length > 0) {
row = new int[indices.length];
for (int id : indices) {
if (id < maxId) {
row[rowSize++] = id;
}
}
}
return ArrayBasedIndexedInts.of(row, rowSize);
}
@Override
public ValueMatcher makeValueMatcher(final String value) {
if (extractionFn == null) {
final int valueId = lookupId(value);
if (valueId >= 0 || value == null) {
return new ValueMatcher() {
@Override
public boolean matches() {
Object[] dims = currEntry.getKey().getDims();
if (dimIndex >= dims.length) {
return value == null;
}
int[] dimsInt = (int[]) dims[dimIndex];
if (dimsInt == null || dimsInt.length == 0) {
return value == null;
}
for (int id : dimsInt) {
if (id == valueId) {
return true;
}
}
return false;
}
};
} else {
return BooleanValueMatcher.of(false);
}
} else {
// Employ precomputed BitSet optimization
return makeValueMatcher(Predicates.equalTo(value));
}
}
@Override
public ValueMatcher makeValueMatcher(final Predicate<String> predicate) {
final BitSet predicateMatchingValueIds = DimensionSelectorUtils.makePredicateMatchingSet(this, predicate);
final boolean matchNull = predicate.apply(null);
return new ValueMatcher() {
@Override
public boolean matches() {
Object[] dims = currEntry.getKey().getDims();
if (dimIndex >= dims.length) {
return matchNull;
}
int[] dimsInt = (int[]) dims[dimIndex];
if (dimsInt == null || dimsInt.length == 0) {
return matchNull;
}
for (int id : dimsInt) {
if (predicateMatchingValueIds.get(id)) {
return true;
}
}
return false;
}
};
}
@Override
public int getValueCardinality() {
return maxId;
}
@Override
public String lookupName(int id) {
final String strValue = getActualValue(id, false);
return extractionFn == null ? strValue : extractionFn.apply(strValue);
}
@Override
public boolean nameLookupPossibleInAdvance() {
return true;
}
@Nullable
@Override
public IdLookup idLookup() {
return extractionFn == null ? this : null;
}
@Override
public int lookupId(String name) {
if (extractionFn != null) {
throw new UnsupportedOperationException("cannot perform lookup when applying an extraction function");
}
return getEncodedValue(name, false);
}
@Override
public void inspectRuntimeShape(RuntimeShapeInspector inspector) {
inspector.visit("currEntry", currEntry);
}
}
return new IndexerDimensionSelector();
}
use of java.util.BitSet in project druid by druid-io.
the class IndexIOTest method constructionFeeder.
@Parameterized.Parameters
public static Iterable<Object[]> constructionFeeder() {
final Map<String, Object> map = ImmutableMap.<String, Object>of();
final Map<String, Object> map00 = ImmutableMap.<String, Object>of("dim0", ImmutableList.<String>of("dim00", "dim01"));
final Map<String, Object> map10 = ImmutableMap.<String, Object>of("dim1", "dim10");
final Map<String, Object> map0null = new HashMap<>();
map0null.put("dim0", null);
final Map<String, Object> map1null = new HashMap<>();
map1null.put("dim1", null);
final Map<String, Object> mapAll = ImmutableMap.<String, Object>of("dim0", ImmutableList.<String>of("dim00", "dim01"), "dim1", "dim10");
final List<Map<String, Object>> maps = ImmutableList.of(map, map00, map10, map0null, map1null, mapAll);
return Iterables.<Object[]>concat(// First iterable tests permutations of the maps which are expected to be equal
Iterables.<Object[]>concat(new Iterable<Iterable<Object[]>>() {
@Override
public Iterator<Iterable<Object[]>> iterator() {
return new Iterator<Iterable<Object[]>>() {
long nextBitset = 1L;
@Override
public boolean hasNext() {
return nextBitset < (1L << maps.size());
}
@Override
public Iterable<Object[]> next() {
final BitSet bitset = BitSet.valueOf(new long[] { nextBitset++ });
final List<Map<String, Object>> myMaps = filterByBitset(maps, bitset);
return Collections2.transform(Collections2.permutations(myMaps), new Function<List<Map<String, Object>>, Object[]>() {
@Nullable
@Override
public Object[] apply(List<Map<String, Object>> input) {
return new Object[] { input, input, null };
}
});
}
@Override
public void remove() {
throw new UOE("Remove not suported");
}
};
}
}), // Second iterable tests combinations of the maps which may or may not be equal
Iterables.<Object[]>concat(new Iterable<Iterable<Object[]>>() {
@Override
public Iterator<Iterable<Object[]>> iterator() {
return new Iterator<Iterable<Object[]>>() {
long nextMap1Bits = 1L;
@Override
public boolean hasNext() {
return nextMap1Bits < (1L << maps.size());
}
@Override
public Iterable<Object[]> next() {
final BitSet bitset1 = BitSet.valueOf(new long[] { nextMap1Bits++ });
final List<Map<String, Object>> maplist1 = filterByBitset(maps, bitset1);
return new Iterable<Object[]>() {
@Override
public Iterator<Object[]> iterator() {
return new Iterator<Object[]>() {
long nextMap2Bits = 1L;
@Override
public boolean hasNext() {
return nextMap2Bits < (1L << maps.size());
}
@Override
public Object[] next() {
final List<Map<String, Object>> maplist2 = filterByBitset(maps, BitSet.valueOf(new long[] { nextMap2Bits++ }));
return new Object[] { maplist1, maplist2, filterNullValues(maplist1).equals(filterNullValues(maplist2)) ? null : SegmentValidationException.class };
}
@Override
public void remove() {
throw new UOE("remove not supported");
}
};
}
};
}
@Override
public void remove() {
throw new UOE("Remove not supported");
}
};
}
}));
}
use of java.util.BitSet in project elasticsearch by elastic.
the class Def method lookupMethod.
/**
* Looks up handle for a dynamic method call, with lambda replacement
* <p>
* A dynamic method call for variable {@code x} of type {@code def} looks like:
* {@code x.method(args...)}
* <p>
* This method traverses {@code recieverClass}'s class hierarchy (including interfaces)
* until it finds a matching whitelisted method. If one is not found, it throws an exception.
* Otherwise it returns a handle to the matching method.
* <p>
* @param lookup caller's lookup
* @param callSiteType callsite's type
* @param receiverClass Class of the object to invoke the method on.
* @param name Name of the method.
* @param args bootstrap args passed to callsite
* @return pointer to matching method to invoke. never returns null.
* @throws IllegalArgumentException if no matching whitelisted method was found.
* @throws Throwable if a method reference cannot be converted to an functional interface
*/
static MethodHandle lookupMethod(Lookup lookup, MethodType callSiteType, Class<?> receiverClass, String name, Object[] args) throws Throwable {
String recipeString = (String) args[0];
int numArguments = callSiteType.parameterCount();
// simple case: no lambdas
if (recipeString.isEmpty()) {
return lookupMethodInternal(receiverClass, name, numArguments - 1).handle;
}
// convert recipe string to a bitset for convenience (the code below should be refactored...)
BitSet lambdaArgs = new BitSet();
for (int i = 0; i < recipeString.length(); i++) {
lambdaArgs.set(recipeString.charAt(i));
}
// otherwise: first we have to compute the "real" arity. This is because we have extra arguments:
// e.g. f(a, g(x), b, h(y), i()) looks like f(a, g, x, b, h, y, i).
int arity = callSiteType.parameterCount() - 1;
int upTo = 1;
for (int i = 1; i < numArguments; i++) {
if (lambdaArgs.get(i - 1)) {
String signature = (String) args[upTo++];
int numCaptures = Integer.parseInt(signature.substring(signature.indexOf(',') + 1));
arity -= numCaptures;
}
}
// lookup the method with the proper arity, then we know everything (e.g. interface types of parameters).
// based on these we can finally link any remaining lambdas that were deferred.
Method method = lookupMethodInternal(receiverClass, name, arity);
MethodHandle handle = method.handle;
int replaced = 0;
upTo = 1;
for (int i = 1; i < numArguments; i++) {
// its a functional reference, replace the argument with an impl
if (lambdaArgs.get(i - 1)) {
// decode signature of form 'type.call,2'
String signature = (String) args[upTo++];
int separator = signature.lastIndexOf('.');
int separator2 = signature.indexOf(',');
String type = signature.substring(1, separator);
String call = signature.substring(separator + 1, separator2);
int numCaptures = Integer.parseInt(signature.substring(separator2 + 1));
Class<?>[] captures = new Class<?>[numCaptures];
for (int capture = 0; capture < captures.length; capture++) {
captures[capture] = callSiteType.parameterType(i + 1 + capture);
}
MethodHandle filter;
Definition.Type interfaceType = method.arguments.get(i - 1 - replaced);
if (signature.charAt(0) == 'S') {
// the implementation is strongly typed, now that we know the interface type,
// we have everything.
filter = lookupReferenceInternal(lookup, interfaceType, type, call, captures);
} else if (signature.charAt(0) == 'D') {
// the interface type is now known, but we need to get the implementation.
// this is dynamically based on the receiver type (and cached separately, underneath
// this cache). It won't blow up since we never nest here (just references)
MethodType nestedType = MethodType.methodType(interfaceType.clazz, captures);
CallSite nested = DefBootstrap.bootstrap(lookup, call, nestedType, 0, DefBootstrap.REFERENCE, interfaceType.name);
filter = nested.dynamicInvoker();
} else {
throw new AssertionError();
}
// the filter now ignores the signature (placeholder) on the stack
filter = MethodHandles.dropArguments(filter, 0, String.class);
handle = MethodHandles.collectArguments(handle, i, filter);
i += numCaptures;
replaced += numCaptures;
}
}
return handle;
}
Aggregations