use of org.drools.core.util.index.AlphaRangeIndex in project drools by kiegroup.
the class AlphaNodeRangeIndexingTest method testMultipleProps.
@Test
public void testMultipleProps() {
final String drl = "package org.drools.compiler.test\n" + "import " + Person.class.getCanonicalName() + "\n" + "rule test1\n when\n" + " Person( age >= 18 )\n" + "then\n end\n" + "rule test2\n when\n" + " Person( age < 25 )\n" + "then\n end\n" + "rule test3\n when\n" + " Person( age > 8 )\n" + "then\n end\n" + "rule test4\n when\n" + " Person( age < 60 )\n" + "then\n end\n" + "rule test5\n when\n" + " Person( age > 12 )\n" + "then\n end\n" + "rule test6\n when\n" + " Person( age <= 4 )\n" + "then\n end\n" + "rule test7\n when\n" + " Person( name >= \"Ann\" )\n" + "then\n end\n" + "rule test8\n when\n" + " Person( name < \"Bob\" )\n" + "then\n end\n" + "rule test9\n when\n" + " Person( name > \"Kent\" )\n" + "then\n end\n" + "rule test10\n when\n" + " Person( name < \"Steve\" )\n" + "then\n end\n" + "rule test11\n when\n" + " Person( name > \"John\" )\n" + "then\n end\n" + "rule test12\n when\n" + " Person( name <= \"Paul\" )\n" + "then\n end\n";
final KieBase kbase = createKieBaseWithRangeIndexThresholdValue(drl, 3);
final KieSession ksession = kbase.newKieSession();
final ObjectTypeNode otn = KieUtil.getObjectTypeNode(kbase, Person.class);
assertNotNull(otn);
ObjectSinkPropagator objectSinkPropagator = otn.getObjectSinkPropagator();
if (this.kieBaseTestConfiguration.useAlphaNetworkCompiler()) {
objectSinkPropagator = ((CompiledNetwork) objectSinkPropagator).getOriginalSinkPropagator();
}
CompositeObjectSinkAdapter sinkAdapter = (CompositeObjectSinkAdapter) objectSinkPropagator;
ObjectSink[] sinks = sinkAdapter.getSinks();
assertEquals(12, sinks.length);
assertEquals(12, sinkAdapter.size());
assertNull(sinkAdapter.getRangeIndexableSinks());
Collection<AlphaRangeIndex> values = sinkAdapter.getRangeIndexMap().values();
assertEquals(2, values.size());
for (AlphaRangeIndex alphaRangeIndex : values) {
// a tree for "age" has 6 nodes. a tree for "name" has 6 nodes
assertEquals(6, alphaRangeIndex.size());
}
ksession.insert(new Person("John", 18));
int fired = ksession.fireAllRules();
assertEquals(8, fired);
ksession.insert(new Person("Paul", 60));
fired = ksession.fireAllRules();
assertEquals(8, fired);
}
use of org.drools.core.util.index.AlphaRangeIndex in project drools by kiegroup.
the class ObjectTypeNodeParser method traverseRangeIndexedAlphaNodes.
private void traverseRangeIndexedAlphaNodes(Map<CompositeObjectSinkAdapter.FieldIndex, AlphaRangeIndex> rangeIndexMap, NetworkHandler handler) {
if (rangeIndexMap == null) {
return;
}
Collection<Entry<FieldIndex, AlphaRangeIndex>> entrySet = rangeIndexMap.entrySet();
for (Entry<FieldIndex, AlphaRangeIndex> entry : entrySet) {
AlphaRangeIndex alphaRangeIndex = entry.getValue();
handler.startRangeIndex(alphaRangeIndex);
Collection<AlphaNode> alphaNodes = alphaRangeIndex.getAllValues();
for (AlphaNode alphaNode : alphaNodes) {
handler.startRangeIndexedAlphaNode(alphaNode);
traversePropagator(alphaNode.getObjectSinkPropagator(), handler);
handler.endRangeIndexedAlphaNode(alphaNode);
}
handler.endRangeIndex(alphaRangeIndex);
}
}
use of org.drools.core.util.index.AlphaRangeIndex in project drools by kiegroup.
the class CompositeObjectSinkAdapter method removeObjectSink.
public ObjectSinkPropagator removeObjectSink(final ObjectSink sink) {
// dirty it, so it'll rebuild on next get
this.sinks = null;
if (this.sinksMap != null) {
this.sinksMap.remove(sink);
}
if (sink.getType() == NodeTypeEnums.AlphaNode) {
final AlphaNode alphaNode = (AlphaNode) sink;
final AlphaNodeFieldConstraint fieldConstraint = alphaNode.getConstraint();
if (fieldConstraint instanceof IndexableConstraint) {
final IndexableConstraint indexableConstraint = (IndexableConstraint) fieldConstraint;
final FieldValue value = indexableConstraint.getField();
// hash index
if (isHashable(indexableConstraint)) {
final InternalReadAccessor fieldAccessor = indexableConstraint.getFieldExtractor();
final int index = fieldAccessor.getIndex();
final FieldIndex fieldIndex = unregisterFieldIndex(index);
if (fieldIndex.isHashed()) {
HashKey hashKey = new HashKey(index, value, fieldAccessor);
this.hashedSinkMap.remove(hashKey);
if (fieldIndex.getCount() <= this.alphaNodeHashingThreshold - 1) {
// we have less than three so unhash
unHashSinks(fieldIndex);
}
} else {
this.hashableSinks.remove(alphaNode);
}
if (this.hashableSinks != null && this.hashableSinks.isEmpty()) {
this.hashableSinks = null;
}
return size() == 1 ? new SingleObjectSinkAdapter(getSinks()[0]) : this;
}
// range index
if (isRangeIndexable(alphaNode)) {
final InternalReadAccessor fieldAccessor = indexableConstraint.getFieldExtractor();
final int index = fieldAccessor.getIndex();
final FieldIndex fieldIndex = unregisterFieldIndexForRange(index);
if (fieldIndex.isRangeIndexed()) {
AlphaRangeIndex alphaRangeIndex = this.rangeIndexMap.get(fieldIndex);
alphaRangeIndex.remove(alphaNode);
if (fieldIndex.getCount() <= this.alphaNodeRangeIndexThreshold - 1) {
// we have less than THRESHOLD so unindex
unRangeIndexSinks(fieldIndex, alphaRangeIndex);
}
} else {
this.rangeIndexableSinks.remove(alphaNode);
}
if (this.rangeIndexableSinks != null && this.rangeIndexableSinks.isEmpty()) {
this.rangeIndexableSinks = null;
}
return size() == 1 ? new SingleObjectSinkAdapter(getSinks()[0]) : this;
}
}
}
this.otherSinks.remove((ObjectSinkNode) sink);
if (this.otherSinks.isEmpty()) {
this.otherSinks = null;
}
return size() == 1 ? new SingleObjectSinkAdapter(getSinks()[0]) : this;
}
use of org.drools.core.util.index.AlphaRangeIndex in project drools by kiegroup.
the class CompositeObjectSinkAdapter method rangeIndexSinks.
/**
* Pick sinks from rangeIndexableSinks (which were stored until index threshold is exceeded) and put them into rangeIndex.
*/
void rangeIndexSinks(final FieldIndex fieldIndex) {
if (rangeIndexMap == null) {
rangeIndexMap = new HashMap<>();
}
AlphaRangeIndex alphaRangeIndex = rangeIndexMap.computeIfAbsent(fieldIndex, AlphaRangeIndex::new);
final int index = fieldIndex.getIndex();
if (rangeIndexableSinks != null) {
Iterator<AlphaNode> sinkIterator = this.rangeIndexableSinks.iterator();
while (sinkIterator.hasNext()) {
final AlphaNode alphaNode = sinkIterator.next();
final AlphaNodeFieldConstraint fieldConstraint = alphaNode.getConstraint();
final IndexableConstraint indexableConstraint = (IndexableConstraint) fieldConstraint;
if (index == indexableConstraint.getFieldExtractor().getIndex()) {
alphaRangeIndex.add(alphaNode);
// remove the alpha from the possible candidates of range indexable sinks since it is now range indexed
sinkIterator.remove();
}
}
if (rangeIndexableSinks.isEmpty()) {
rangeIndexableSinks = null;
}
}
fieldIndex.setRangeIndexed(true);
}
use of org.drools.core.util.index.AlphaRangeIndex in project drools by kiegroup.
the class CompositeObjectSinkAdapter method reIndexNodes.
public void reIndexNodes() {
sinksMap = new HashMap<>();
if (this.otherSinks != null) {
for (ObjectSinkNode sink : this.otherSinks) {
sinksMap.put(sink, sink);
}
}
if (this.hashableSinks != null) {
for (ObjectSinkNode sink : this.hashableSinks) {
sinksMap.put(sink, sink);
}
}
if (this.rangeIndexableSinks != null) {
for (ObjectSinkNode sink : this.rangeIndexableSinks) {
sinksMap.put(sink, sink);
}
}
if (this.hashedSinkMap != null) {
for (ObjectSink sink : this.hashedSinkMap.values()) {
sinksMap.put(sink, sink);
}
}
if (this.rangeIndexMap != null) {
Collection<AlphaRangeIndex> alphaRangeIndexes = rangeIndexMap.values();
for (AlphaRangeIndex alphaRangeIndex : alphaRangeIndexes) {
Collection<AlphaNode> alphaNodes = alphaRangeIndex.getAllValues();
alphaNodes.forEach(sink -> sinksMap.put(sink, sink));
}
}
}
Aggregations