Skip to content

Commit

Permalink
[DROOLS-5910] Enable range index for JoinNode (apache#3343)
Browse files Browse the repository at this point in the history
* [DROOLS-5910] Enable range index for JoinNode
- fixed TupleRBTree.range()
- fixed code smell
- enhanced indexedBy, betaIndexedBy

* - leave the equality index unchanged

* - Adding BetaRangeIndexOption

* - a little comment

* - add KieBaseModel marshalling for BetaRangeIndexOption
  • Loading branch information
tkobayas committed Jan 28, 2021
1 parent ec76d24 commit d0ecb0a
Show file tree
Hide file tree
Showing 42 changed files with 1,105 additions and 100 deletions.
Expand Up @@ -29,6 +29,7 @@
import org.kie.api.builder.model.KieSessionModel.KieSessionType;
import org.kie.api.builder.model.ListenerModel;
import org.kie.api.builder.model.WorkItemHandlerModel;
import org.kie.api.conf.BetaRangeIndexOption;
import org.kie.api.conf.DeclarativeAgendaOption;
import org.kie.api.conf.EqualityBehaviorOption;
import org.kie.api.conf.EventProcessingOption;
Expand Down Expand Up @@ -63,6 +64,7 @@ public void testMarshallingUnmarshalling() {
.setDeclarativeAgenda( DeclarativeAgendaOption.ENABLED )
.setSequential( SequentialOption.YES )
.setSessionsPool( SessionsPoolOption.get(3) )
.setBetaRangeIndexOption(BetaRangeIndexOption.ENABLED)
.addInclude("OtherKBase")
.addPackage("org.kie.pkg1")
.addPackage("org.kie.pkg2");
Expand Down Expand Up @@ -115,6 +117,7 @@ public void testMarshallingUnmarshalling() {
assertEquals(DeclarativeAgendaOption.ENABLED, kieBaseModelXML.getDeclarativeAgenda());
assertEquals(SequentialOption.YES, kieBaseModelXML.getSequential());
assertEquals(SessionsPoolOption.get(3), kieBaseModelXML.getSessionsPool());
assertEquals(BetaRangeIndexOption.ENABLED, kieBaseModelXML.getBetaRangeIndexOption());
assertFalse(kieBaseModelXML.isDefault());
assertEquals("org.kie.pkg1", kieBaseModelXML.getPackages().get(0));
assertEquals("org.kie.pkg2", kieBaseModelXML.getPackages().get(1));
Expand Down
Expand Up @@ -36,6 +36,7 @@
import org.kie.api.builder.model.KieModuleModel;
import org.kie.api.builder.model.KieSessionModel;
import org.kie.api.builder.model.RuleTemplateModel;
import org.kie.api.conf.BetaRangeIndexOption;
import org.kie.api.conf.DeclarativeAgendaOption;
import org.kie.api.conf.EqualityBehaviorOption;
import org.kie.api.conf.EventProcessingOption;
Expand Down Expand Up @@ -69,6 +70,8 @@ public class KieBaseModelImpl

private SessionsPoolOption sessionsPool = SessionsPoolOption.NO;

private BetaRangeIndexOption betaRangeIndexOption = BetaRangeIndexOption.DISABLED;

private Map<String, KieSessionModel> kSessions = new HashMap<String, KieSessionModel>();

private KieModuleModel kModule;
Expand Down Expand Up @@ -279,6 +282,17 @@ public KieBaseModel setDeclarativeAgenda(DeclarativeAgendaOption declarativeAgen
return this;
}

@Override
public BetaRangeIndexOption getBetaRangeIndexOption() {
return betaRangeIndexOption;
}

@Override
public KieBaseModel setBetaRangeIndexOption(BetaRangeIndexOption betaRangeIndexOption) {
this.betaRangeIndexOption = betaRangeIndexOption;
return this;
}

@Override
public SequentialOption getSequential() {
return sequential;
Expand Down Expand Up @@ -367,6 +381,9 @@ public void marshal(Object value,
if ( kBase.getSessionsPool() != null ) {
writer.addAttribute( "sessionsPool", "" + kBase.getSessionsPool().getSize() );
}
if ( kBase.getBetaRangeIndexOption() != null ) {
writer.addAttribute( "betaRangeIndex", kBase.getBetaRangeIndexOption().toString().toLowerCase() );
}

if ( kBase.getScope() != null ) {
writer.addAttribute( "scope", kBase.getScope() );
Expand Down Expand Up @@ -448,6 +465,11 @@ public Object unmarshal(HierarchicalStreamReader reader,
kBase.setSessionsPool( SessionsPoolOption.get( Integer.parseInt( sessionsPool ) ) );
}

String betaRangeIndex = reader.getAttribute( "betaRangeIndex" );
if ( betaRangeIndex != null ) {
kBase.setBetaRangeIndexOption( BetaRangeIndexOption.determineBetaRangeIndex( betaRangeIndex ) );
}

String scope = reader.getAttribute( "scope" );
if ( scope != null ) {
kBase.setScope( scope.trim() );
Expand Down
Expand Up @@ -35,6 +35,7 @@
import org.drools.core.util.StringUtils;
import org.drools.reflective.classloader.ProjectClassLoader;
import org.kie.api.KieBaseConfiguration;
import org.kie.api.conf.BetaRangeIndexOption;
import org.kie.api.conf.DeclarativeAgendaOption;
import org.kie.api.conf.EqualityBehaviorOption;
import org.kie.api.conf.EventProcessingOption;
Expand Down Expand Up @@ -96,6 +97,7 @@
* drools.shareBetaNodes = &lt;true|false&gt;
* drools.alphaNodeHashingThreshold = &lt;1...n&gt;
* drools.alphaNodeRangeIndexThreshold = &lt;1...n&gt;
* drools.betaNodeRangeIndexEnabled = &lt;true|false&gt;
* drools.sessionPool = &lt;1...n&gt;
* drools.compositeKeyDepth = &lt;1..3&gt;
* drools.indexLeftBetaMemory = &lt;true/false&gt;
Expand Down Expand Up @@ -140,6 +142,7 @@ public class RuleBaseConfiguration
private int jittingThreshold;
private int alphaNodeHashingThreshold;
private int alphaNodeRangeIndexThreshold;
private boolean betaNodeRangeIndexEnabled;
private int compositeKeyDepth;
private boolean indexLeftBetaMemory;
private boolean indexRightBetaMemory;
Expand Down Expand Up @@ -198,6 +201,7 @@ public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(jittingThreshold);
out.writeInt(alphaNodeHashingThreshold);
out.writeInt(alphaNodeRangeIndexThreshold);
out.writeBoolean(betaNodeRangeIndexEnabled);
out.writeInt(compositeKeyDepth);
out.writeBoolean(indexLeftBetaMemory);
out.writeBoolean(indexRightBetaMemory);
Expand Down Expand Up @@ -231,6 +235,7 @@ public void readExternal(ObjectInput in) throws IOException,
jittingThreshold = in.readInt();
alphaNodeHashingThreshold = in.readInt();
alphaNodeRangeIndexThreshold = in.readInt();
betaNodeRangeIndexEnabled = in.readBoolean();
compositeKeyDepth = in.readInt();
indexLeftBetaMemory = in.readBoolean();
indexRightBetaMemory = in.readBoolean();
Expand Down Expand Up @@ -313,6 +318,8 @@ public void setProperty(String name,
setAlphaNodeHashingThreshold( StringUtils.isEmpty( value ) ? 3 : Integer.parseInt(value));
} else if ( name.equals( AlphaRangeIndexThresholdOption.PROPERTY_NAME ) ) {
setAlphaNodeRangeIndexThreshold( StringUtils.isEmpty( value ) ? AlphaRangeIndexThresholdOption.DEFAULT_VALUE : Integer.parseInt(value));
} else if ( name.equals( BetaRangeIndexOption.PROPERTY_NAME ) ) {
setBetaNodeRangeIndexEnabled( StringUtils.isEmpty( value ) ? false : Boolean.valueOf(value));
} else if ( name.equals( SessionsPoolOption.PROPERTY_NAME ) ) {
setSessionPoolSize( StringUtils.isEmpty( value ) ? -1 : Integer.parseInt(value));
} else if ( name.equals( CompositeKeyDepthOption.PROPERTY_NAME ) ) {
Expand Down Expand Up @@ -370,6 +377,8 @@ public String getProperty(String name) {
return Integer.toString( getAlphaNodeHashingThreshold() );
} else if ( name.equals( AlphaRangeIndexThresholdOption.PROPERTY_NAME ) ) {
return Integer.toString( getAlphaNodeRangeIndexThreshold() );
} else if ( name.equals( BetaRangeIndexOption.PROPERTY_NAME ) ) {
return Boolean.toString( isBetaNodeRangeIndexEnabled() );
} else if ( name.equals( SessionsPoolOption.PROPERTY_NAME ) ) {
return Integer.toString( getSessionPoolSize() );
} else if ( name.equals( CompositeKeyDepthOption.PROPERTY_NAME ) ) {
Expand Down Expand Up @@ -452,6 +461,8 @@ private void init(Properties properties) {

setAlphaNodeRangeIndexThreshold(Integer.parseInt(this.chainedProperties.getProperty(AlphaRangeIndexThresholdOption.PROPERTY_NAME, "" + AlphaRangeIndexThresholdOption.DEFAULT_VALUE)));

setBetaNodeRangeIndexEnabled(Boolean.valueOf(this.chainedProperties.getProperty(BetaRangeIndexOption.PROPERTY_NAME, "false")));

setSessionPoolSize(Integer.parseInt(this.chainedProperties.getProperty( SessionsPoolOption.PROPERTY_NAME, "-1")));

setCompositeKeyDepth(Integer.parseInt(this.chainedProperties.getProperty(CompositeKeyDepthOption.PROPERTY_NAME, "3")));
Expand Down Expand Up @@ -611,6 +622,15 @@ public void setAlphaNodeRangeIndexThreshold(final int alphaNodeRangeIndexThresho
this.alphaNodeRangeIndexThreshold = alphaNodeRangeIndexThreshold;
}

public boolean isBetaNodeRangeIndexEnabled() {
return this.betaNodeRangeIndexEnabled;
}

public void setBetaNodeRangeIndexEnabled(final boolean betaNodeRangeIndexEnabled) {
checkCanChange();
this.betaNodeRangeIndexEnabled = betaNodeRangeIndexEnabled;
}

public int getSessionPoolSize() {
return this.sessionPoolSize;
}
Expand Down Expand Up @@ -1141,6 +1161,8 @@ public <T extends SingleValueKieBaseOption> T getOption(Class<T> option) {
return (T) AlphaThresholdOption.get(alphaNodeHashingThreshold);
} else if (AlphaRangeIndexThresholdOption.class.equals(option)) {
return (T) AlphaRangeIndexThresholdOption.get(alphaNodeRangeIndexThreshold);
} else if (BetaRangeIndexOption.class.equals(option)) {
return (T) (this.betaNodeRangeIndexEnabled ? BetaRangeIndexOption.ENABLED : BetaRangeIndexOption.DISABLED);
} else if ( SessionsPoolOption.class.equals(option)) {
return (T) SessionsPoolOption.get(sessionPoolSize);
} else if (CompositeKeyDepthOption.class.equals(option)) {
Expand Down Expand Up @@ -1200,6 +1222,8 @@ public <T extends KieBaseOption> void setOption(T option) {
setAlphaNodeHashingThreshold( ( (AlphaThresholdOption) option ).getThreshold());
} else if (option instanceof AlphaRangeIndexThresholdOption) {
setAlphaNodeRangeIndexThreshold( ( (AlphaRangeIndexThresholdOption) option ).getThreshold());
} else if (option instanceof BetaRangeIndexOption) {
setBetaNodeRangeIndexEnabled( ( (BetaRangeIndexOption) option ).isBetaRangeIndexEnabled());
} else if (option instanceof SessionsPoolOption ) {
setSessionPoolSize( ( ( SessionsPoolOption ) option ).getSize());
} else if (option instanceof CompositeKeyDepthOption) {
Expand Down
26 changes: 26 additions & 0 deletions drools-core/src/main/java/org/drools/core/base/CoercionUtil.java
Expand Up @@ -163,4 +163,30 @@ public static Number coerceToNumber(String value, Class<?> toClass) {
}
return ret;
}

public static Number coerceToNumber(Number value, Class<?> toClass) {
Number ret = null;
if (value != null) {
if (toClass.equals(BigDecimal.class)) {
ret = MathUtils.getBigDecimal(value);
} else if (toClass.equals(BigInteger.class)) {
ret = MathUtils.getBigInteger(value);
} else if (toClass.equals(Double.class)) {
ret = value.doubleValue();
} else if (toClass.equals(Float.class)) {
ret = value.floatValue();
} else if (toClass.equals(Long.class)) {
ret = value.longValue();
} else if (toClass.equals(Integer.class)) {
ret = value.intValue();
} else if (toClass.equals(Short.class)) {
ret = value.shortValue();
} else if (toClass.equals(Byte.class)) {
ret = value.byteValue();
} else {
throw new ClassCastException("Not possible to coerce [" + value + "] from class " + value.getClass() + " to class " + toClass);
}
}
return ret;
}
}
Expand Up @@ -67,7 +67,7 @@ BetaMemory createBetaMemory(final RuleBaseConfiguration config,
BitMask getListenedPropertyMask(Class modifiedClass, List<String> settableProperties);

void init(BuildContext context, short betaNodeType);
void initIndexes(int depth, short betaNodeType);
void initIndexes(int depth, short betaNodeType, RuleBaseConfiguration config);

BetaConstraints cloneIfInUse();

Expand Down
Expand Up @@ -97,18 +97,18 @@ public void init(BuildContext context, short betaNodeType) {
indexed = 0;
} else {
int depth = config.getCompositeKeyDepth();
if ( !compositeAllowed( constraints, betaNodeType ) ) {
if ( !compositeAllowed( constraints, betaNodeType, config ) ) {
// UnificationRestrictions cannot be allowed in composite indexes
// We also ensure that if there is a mixture that standard restriction is first
depth = 1;
}
initIndexes( depth, betaNodeType );
initIndexes( depth, betaNodeType, config );
}
}

public void initIndexes(int depth, short betaNodeType) {
public void initIndexes(int depth, short betaNodeType, RuleBaseConfiguration config) {
indexed = 0;
boolean[] indexable = isIndexableForNode(indexPrecedenceOption, betaNodeType, depth, constraints);
boolean[] indexable = isIndexableForNode(indexPrecedenceOption, betaNodeType, depth, constraints, config);
for (boolean i : indexable) {
if (i) {
indexed++;
Expand Down
Expand Up @@ -59,8 +59,8 @@ public void init(BuildContext context, short betaNodeType) {
constraints.init(context, betaNodeType);
}

public void initIndexes(int depth, short betaNodeType) {
constraints.initIndexes(depth, betaNodeType);
public void initIndexes(int depth, short betaNodeType, RuleBaseConfiguration config) {
constraints.initIndexes(depth, betaNodeType, config);
}

public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
Expand Down
Expand Up @@ -156,7 +156,7 @@ public BitMask getListenedPropertyMask(Class modifiedClass, List<String> settabl
}

public void init(BuildContext context, short betaNodeType) { }
public void initIndexes(int depth, short betaNodeType) { }
public void initIndexes(int depth, short betaNodeType, RuleBaseConfiguration config) { }

public boolean isLeftUpdateOptimizationAllowed() {
return true;
Expand Down
Expand Up @@ -74,17 +74,17 @@ public final void init(BuildContext context, short betaNodeType) {
indexed = new boolean[constraints.length];
} else {
int depth = config.getCompositeKeyDepth();
if ( !compositeAllowed( constraints, betaNodeType ) ) {
if ( !compositeAllowed( constraints, betaNodeType, config ) ) {
// UnificationRestrictions cannot be allowed in composite indexes
// We also ensure that if there is a mixture that standard restriction is first
depth = 1;
}
initIndexes( depth, betaNodeType );
initIndexes( depth, betaNodeType, config );
}
}

public final void initIndexes(int depth, short betaNodeType) {
indexed = isIndexableForNode(indexPrecedenceOption, betaNodeType, depth, constraints);
public final void initIndexes(int depth, short betaNodeType, RuleBaseConfiguration config) {
indexed = isIndexableForNode(indexPrecedenceOption, betaNodeType, depth, constraints, config);
}

public final boolean isIndexed() {
Expand Down
Expand Up @@ -65,8 +65,8 @@ public void init(BuildContext context, short betaNodeType) {
constraints.init(context, betaNodeType);
}

public void initIndexes(int depth, short betaNodeType) {
constraints.initIndexes(depth, betaNodeType);
public void initIndexes(int depth, short betaNodeType, RuleBaseConfiguration config) {
constraints.initIndexes(depth, betaNodeType, config);
}

public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
Expand Down
Expand Up @@ -74,12 +74,12 @@ public void init(BuildContext context, short betaNodeType) {
if ((disableIndex) || (!config.isIndexLeftBetaMemory() && !config.isIndexRightBetaMemory())) {
this.indexed = false;
} else {
initIndexes(config.getCompositeKeyDepth(), betaNodeType);
initIndexes(config.getCompositeKeyDepth(), betaNodeType, config);
}
}

public void initIndexes(int depth, short betaNodeType) {
indexed = depth >= 1 && IndexUtil.isIndexableForNode(betaNodeType, constraint);
public void initIndexes(int depth, short betaNodeType, RuleBaseConfiguration config) {
indexed = depth >= 1 && IndexUtil.isIndexableForNode(betaNodeType, constraint, config);
}

public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
Expand Down
Expand Up @@ -58,8 +58,8 @@ public void init(BuildContext context, short betaNodeType) {
constraints.init(context, betaNodeType);
}

public void initIndexes(int depth, short betaNodeType) {
constraints.initIndexes(depth, betaNodeType);
public void initIndexes(int depth, short betaNodeType, RuleBaseConfiguration config) {
constraints.initIndexes(depth, betaNodeType, config);
}

public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
Expand Down
Expand Up @@ -63,8 +63,8 @@ public void init(BuildContext context, short betaNodeType) {
constraints.init(context, betaNodeType);
}

public void initIndexes(int depth, short betaNodeType) {
constraints.initIndexes(depth, betaNodeType);
public void initIndexes(int depth, short betaNodeType, RuleBaseConfiguration config) {
constraints.initIndexes(depth, betaNodeType, config);
}

public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
Expand Down
Expand Up @@ -249,7 +249,7 @@ public void writeExternal(ObjectOutput out) throws IOException {
BetaNodeFieldConstraint[] betaCconstraints = this.constraints.getConstraints();
if ( betaCconstraints.length > 0 ) {
BetaNodeFieldConstraint c = betaCconstraints[0];
if ( IndexUtil.isIndexable(c, getType()) && ((IndexableConstraint) c).isUnification() ) {
if ( IndexUtil.isIndexable(c, getType(), RuleBaseConfiguration.getDefaultInstance()) && ((IndexableConstraint) c).isUnification() ) {
setConstraints( this.constraints.getOriginalConstraint() );
}
}
Expand All @@ -272,7 +272,7 @@ private void setUnificationJoin() {
BetaNodeFieldConstraint[] betaCconstraints = this.constraints.getConstraints();
if ( betaCconstraints.length > 0 ) {
BetaNodeFieldConstraint c = betaCconstraints[0];
if ( IndexUtil.isIndexable(c, getType()) && ((IndexableConstraint) c).isUnification() ) {
if ( IndexUtil.isIndexable(c, getType(), RuleBaseConfiguration.getDefaultInstance()) && ((IndexableConstraint) c).isUnification() ) {
if ( this.constraints instanceof SingleBetaConstraints ) {
setConstraints( new SingleNonIndexSkipBetaConstraints( (SingleBetaConstraints) this.constraints ) );
} else if ( this.constraints instanceof DoubleBetaConstraints ) {
Expand Down
Expand Up @@ -17,6 +17,7 @@

import org.drools.core.util.AbstractHashTable.FieldIndex;
import org.drools.core.util.index.IndexUtil;
import org.drools.core.RuleBaseConfiguration;
import org.drools.core.spi.Constraint;
import org.drools.core.spi.FieldValue;
import org.drools.core.spi.InternalReadAccessor;
Expand All @@ -25,7 +26,7 @@ public interface IndexableConstraint extends Constraint {

boolean isUnification();

boolean isIndexable(short nodeType);
boolean isIndexable(short nodeType, RuleBaseConfiguration config);

IndexUtil.ConstraintType getConstraintType();

Expand All @@ -36,4 +37,6 @@ public interface IndexableConstraint extends Constraint {
InternalReadAccessor getFieldExtractor();

default void unsetUnification() { }

Declaration getIndexingDeclaration();
}

0 comments on commit d0ecb0a

Please sign in to comment.