Details
-
Feature Request
-
Resolution: Won't Do
-
Major
-
None
-
None
-
None
-
2020 Week 52-03 (from Dec 21)
-
NEW
-
NEW
Description
- Replace the AccumulateFunction interface with the AccumulateFunction2 interface:
- All core runtime code uses the AccumulateFunction2 interface.
- Deprecate AccumulateFunction and use a bridge class at DRL compilation time so old implementations still work because they are bridged into the new interface
- Changes of the AccumulateFunction2:
- Methods no longer throw checked exceptions (no "throws Exception"), so drools doesn't have to catch them. This might improve performance.
- Remove "Serializable context". The class itself contains the state.
- Remove method createContext()
- Replace method init(Serializeble) with constructor call (no-args normally)
- Remove parameter Serializable from accumulate(value), reserve(value) and getResult() methods
- Instead of making 1 AccFunction instance and n context instances, make n AccFunction instances. This uses less memory.
- This might improve performance (data locality).
- It should Serializable, but doesn't have to Externalizable. Removes methods writeExternal() and readExternal() in the user implementation.
- Interface ReversableAccumulateFunction2 extends AccumulateFunction2
- Only ReversableAccumulateFunction2 has method reverse(value)
- Remove method supportsReverse(): the custom accumulate is reverseable if it also implements this interface
- Opportunities
- construction parameters. For example: fixed average for standard deviation (very useful for OptaPlanner)
- Multi-argument accumulates, for example in DRL: `$total : standardDeviation($groupBy, $weight)`
Notice how clean the user implementation would become.
// NEW public class SumAccumulateFunction implements ReversableAccumulateFunction2<Integer, Integer> { public int total; public SumAccumulateFunction() { total = 0; } public void accumulate(Integer value) { total += value; } public void reverse(Integer value) { total -= value; } public Integer getResult() { return total; } }
Compare that with the old way:
// OLD public class SumAccumulateFunction implements AccumulateFunction { public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { } public void writeExternal(ObjectOutput out) throws IOException { } protected static class SumData implements Externalizable { public double total = 0; public SumData() {} public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { total = in.readDouble(); } public void writeExternal(ObjectOutput out) throws IOException { out.writeDouble(total); } } public Serializable createContext() { return new SumData(); } public void init(Serializable context) { SumData data = (SumData) context; data.total = 0; } public void accumulate(Serializable context, Object value) { SumData data = (SumData) context; data.total += ((Number) value).doubleValue(); } public void reverse(Serializable context, Object value) { SumData data = (SumData) context; data.total -= ((Number) value).doubleValue(); } public Object getResult(Serializable context) { return ((SumData) context).total; } public boolean supportsReverse() { return true; } public Class<?> getResultType() { return Double.class; } }
Some other cases:
Different result type than value type:
public class AverageAccumulateFunction implements ReversableAccumulateFunction2<Integer, Double> { public int total; public int count; public AverageAccumulateFunction() { total = 0; count = 0; } public void accumulate(Integer value) { total += value; count++; } public void reverse(Integer value) { total -= value; count--; } public Double getResult() { return (double) total / count; } }
Construction parameter:
public class StdDeviationAccumulateFunction implements ReversableAccumulateFunction2<Integer, Double> { public final double average; public double variance; public StdDeviationAccumulateFunction(double average) { this.average = average; variance = 0; } public void accumulate(double value) { variance += (value - average)²; // TODO } public void reverse(double value) { variance -= (value - average)²; // TODO } public Double getResult() { return Math.sqrt(variance); } }
TODO multi-argument accumulate:
...
Attachments
Issue Links
- incorporates
-
DROOLS-1421 Support multi-argument accumulate functions
- Closed