From 984e8d9c76cedb188f2fb5c84d1a7a1632d81b31 Mon Sep 17 00:00:00 2001 From: David North Date: Thu, 3 Sep 2015 15:58:00 +0000 Subject: [PATCH] Make D* functions thread safe, thanks to Patrick Zimmermann for the patch. https://bz.apache.org/bugzilla/show_bug.cgi?id=58039 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1701055 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/ss/formula/eval/FunctionEval.java | 4 +-- .../apache/poi/ss/formula/functions/DGet.java | 10 ++------ .../apache/poi/ss/formula/functions/DMin.java | 6 ++--- .../poi/ss/formula/functions/DStarRunner.java | 25 ++++++++++++++----- .../ss/formula/functions/IDStarAlgorithm.java | 5 ---- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/java/org/apache/poi/ss/formula/eval/FunctionEval.java b/src/java/org/apache/poi/ss/formula/eval/FunctionEval.java index cf88b37a62..c64afbd55f 100644 --- a/src/java/org/apache/poi/ss/formula/eval/FunctionEval.java +++ b/src/java/org/apache/poi/ss/formula/eval/FunctionEval.java @@ -98,7 +98,7 @@ public final class FunctionEval { retval[38] = BooleanFunction.NOT; retval[39] = NumericFunction.MOD; - retval[43] = new DStarRunner(new DMin()); + retval[43] = new DStarRunner(DStarRunner.DStarAlgorithmEnum.DMIN); retval[46] = AggregateFunction.VAR; retval[48] = TextFunction.TEXT; @@ -191,7 +191,7 @@ public final class FunctionEval { retval[233] = NumericFunction.ACOSH; retval[234] = NumericFunction.ATANH; - retval[235] = new DStarRunner(new DGet()); + retval[235] = new DStarRunner(DStarRunner.DStarAlgorithmEnum.DGET); retval[FunctionID.EXTERNAL_FUNC] = null; // ExternalFunction is a FreeREfFunction diff --git a/src/java/org/apache/poi/ss/formula/functions/DGet.java b/src/java/org/apache/poi/ss/formula/functions/DGet.java index 273c4eaacb..91a9934b50 100644 --- a/src/java/org/apache/poi/ss/formula/functions/DGet.java +++ b/src/java/org/apache/poi/ss/formula/functions/DGet.java @@ -23,18 +23,11 @@ import org.apache.poi.ss.formula.eval.ValueEval; /** * Implementation of the DGet function: * Finds the value of a column in an area with given conditions. - * - * TODO: - * - wildcards ? and * in string conditions - * - functions as conditions */ public final class DGet implements IDStarAlgorithm { private ValueEval result; - - public void reset() { - result = null; - } + @Override public boolean processMatch(ValueEval eval) { if(result == null) // First match, just set the value. { @@ -49,6 +42,7 @@ public final class DGet implements IDStarAlgorithm { return true; } + @Override public ValueEval getResult() { if(result == null) { return ErrorEval.VALUE_INVALID; diff --git a/src/java/org/apache/poi/ss/formula/functions/DMin.java b/src/java/org/apache/poi/ss/formula/functions/DMin.java index 6f996c55f2..61b75768c7 100644 --- a/src/java/org/apache/poi/ss/formula/functions/DMin.java +++ b/src/java/org/apache/poi/ss/formula/functions/DMin.java @@ -32,10 +32,7 @@ import org.apache.poi.ss.formula.eval.ValueEval; public final class DMin implements IDStarAlgorithm { private ValueEval minimumValue; - public void reset() { - minimumValue = null; - } - + @Override public boolean processMatch(ValueEval eval) { if(eval instanceof NumericValueEval) { if(minimumValue == null) { // First match, just set the value. @@ -52,6 +49,7 @@ public final class DMin implements IDStarAlgorithm { return true; } + @Override public ValueEval getResult() { if(minimumValue == null) { return NumberEval.ZERO; diff --git a/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java b/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java index fbf074cdb1..c5fffbda3a 100644 --- a/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java +++ b/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java @@ -32,12 +32,21 @@ import org.apache.poi.ss.util.NumberComparer; * This class performs a D* calculation. It takes an {@link IDStarAlgorithm} object and * uses it for calculating the result value. Iterating a database and checking the * entries against the set of conditions is done here. + * + * TODO: + * - wildcards ? and * in string conditions + * - functions as conditions */ public final class DStarRunner implements Function3Arg { - private IDStarAlgorithm algorithm; + public enum DStarAlgorithmEnum { + DGET, + DMIN, + // DMAX, // DMAX is not yet implemented + } + private final DStarAlgorithmEnum algoType; - public DStarRunner(IDStarAlgorithm algorithm) { - this.algorithm = algorithm; + public DStarRunner(DStarAlgorithmEnum algorithm) { + this.algoType = algorithm; } public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { @@ -69,10 +78,14 @@ public final class DStarRunner implements Function3Arg { return ErrorEval.VALUE_INVALID; } - // Reset algorithm. - algorithm.reset(); + // Create an algorithm runner. + IDStarAlgorithm algorithm = null; + switch(algoType) { + case DGET: algorithm = new DGet(); break; + case DMIN: algorithm = new DMin(); break; + } - // Iterate over all db entries. + // Iterate over all DB entries. for(int row = 1; row < db.getHeight(); ++row) { boolean matches = true; try { diff --git a/src/java/org/apache/poi/ss/formula/functions/IDStarAlgorithm.java b/src/java/org/apache/poi/ss/formula/functions/IDStarAlgorithm.java index b23dd7f6bd..111964a4c4 100644 --- a/src/java/org/apache/poi/ss/formula/functions/IDStarAlgorithm.java +++ b/src/java/org/apache/poi/ss/formula/functions/IDStarAlgorithm.java @@ -24,11 +24,6 @@ import org.apache.poi.ss.formula.eval.ValueEval; * Each implementing class should correspond to one of the D* functions. */ public interface IDStarAlgorithm { - /** - * Reset the state of this algorithm. - * This is called before each run through a database. - */ - void reset(); /** * Process a match that is found during a run through a database. * @param eval ValueEval of the cell in the matching row. References will already be resolved.