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
This commit is contained in:
David North 2015-09-03 15:58:00 +00:00
parent 6e89e04bb7
commit 7d1947ad3a
5 changed files with 25 additions and 25 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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 {

View File

@ -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.