mirror of https://github.com/apache/poi.git
bug 59814: clear evaluation workbook and evaluation sheet caches. Patch from Greg Woolsey.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1751836 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
59480f783f
commit
3ed02a3479
|
@ -45,4 +45,8 @@ final class HSSFEvaluationSheet implements EvaluationSheet {
|
|||
}
|
||||
return new HSSFEvaluationCell(cell, this);
|
||||
}
|
||||
|
||||
public void clearAllCachedResultValues() {
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,6 +64,10 @@ public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
|
|||
_iBook = book.getWorkbook();
|
||||
}
|
||||
|
||||
public void clearAllCachedResultValues() {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public HSSFName createName() {
|
||||
return _uBook.createName();
|
||||
|
|
|
@ -30,4 +30,12 @@ public interface EvaluationSheet {
|
|||
* @return <code>null</code> if there is no cell at the specified coordinates
|
||||
*/
|
||||
EvaluationCell getCell(int rowIndex, int columnIndex);
|
||||
|
||||
/**
|
||||
* Propagated from {@link EvaluationWorkbook#clearAllCachedResultValues()} to clear locally cached data.
|
||||
*
|
||||
* @see WorkbookEvaluator#clearAllCachedResultValues()
|
||||
* @see EvaluationWorkbook#clearAllCachedResultValues()
|
||||
*/
|
||||
public void clearAllCachedResultValues();
|
||||
}
|
||||
|
|
|
@ -73,6 +73,13 @@ public interface EvaluationWorkbook {
|
|||
String resolveNameXText(NameXPtg ptg);
|
||||
Ptg[] getFormulaTokens(EvaluationCell cell);
|
||||
UDFFinder getUDFFinder();
|
||||
|
||||
/**
|
||||
* Propagated from {@link WorkbookEvaluator#clearAllCachedResultValues()} to clear locally cached data.
|
||||
* Implementations must call the same method on all referenced {@link EvaluationSheet} instances, as well as clearing local caches.
|
||||
* @see WorkbookEvaluator#clearAllCachedResultValues()
|
||||
*/
|
||||
public void clearAllCachedResultValues();
|
||||
|
||||
class ExternalSheet {
|
||||
private final String _workbookName;
|
||||
|
|
|
@ -208,6 +208,7 @@ public final class WorkbookEvaluator {
|
|||
public void clearAllCachedResultValues() {
|
||||
_cache.clear();
|
||||
_sheetIndexesBySheet.clear();
|
||||
_workbook.clearAllCachedResultValues();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -101,6 +101,14 @@ final class ForkedEvaluationSheet implements EvaluationSheet {
|
|||
return mewb.getSheetIndex(_masterSheet);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* leave the map alone, if it needs resetting, reusing this class is probably a bad idea.
|
||||
* @see org.apache.poi.ss.formula.EvaluationSheet#clearAllCachedResultValues()
|
||||
*/
|
||||
public void clearAllCachedResultValues() {
|
||||
_masterSheet.clearAllCachedResultValues();
|
||||
}
|
||||
|
||||
private static final class RowColKey implements Comparable<RowColKey>{
|
||||
private final int _rowIndex;
|
||||
private final int _columnIndex;
|
||||
|
|
|
@ -136,4 +136,12 @@ final class ForkedEvaluationWorkbook implements EvaluationWorkbook {
|
|||
public UDFFinder getUDFFinder(){
|
||||
return _masterBook.getUDFFinder();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* leave the map alone, if it needs resetting, reusing this class is probably a bad idea.
|
||||
* @see org.apache.poi.ss.formula.EvaluationSheet#clearAllCachedResultValues()
|
||||
*/
|
||||
public void clearAllCachedResultValues() {
|
||||
_masterBook.clearAllCachedResultValues();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,4 +47,8 @@ final class SXSSFEvaluationSheet implements EvaluationSheet {
|
|||
}
|
||||
return new SXSSFEvaluationCell(cell, this);
|
||||
}
|
||||
|
||||
public void clearAllCachedResultValues() {
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,10 @@ public abstract class BaseXSSFEvaluationWorkbook implements FormulaRenderingWork
|
|||
_uBook = book;
|
||||
}
|
||||
|
||||
public void clearAllCachedResultValues() {
|
||||
_tableCache = null;
|
||||
}
|
||||
|
||||
private int convertFromExternalSheetIndex(int externSheetIndex) {
|
||||
return externSheetIndex;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,10 @@ final class XSSFEvaluationSheet implements EvaluationSheet {
|
|||
return _xs;
|
||||
}
|
||||
|
||||
public void clearAllCachedResultValues() {
|
||||
_cellCache = null;
|
||||
}
|
||||
|
||||
public EvaluationCell getCell(int rowIndex, int columnIndex) {
|
||||
// cache for performance: ~30% speedup due to caching
|
||||
if (_cellCache == null) {
|
||||
|
|
|
@ -40,6 +40,11 @@ public final class XSSFEvaluationWorkbook extends BaseXSSFEvaluationWorkbook {
|
|||
super(book);
|
||||
}
|
||||
|
||||
public void clearAllCachedResultValues() {
|
||||
super.clearAllCachedResultValues();
|
||||
_sheetCache = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSheetIndex(EvaluationSheet evalSheet) {
|
||||
XSSFSheet sheet = ((XSSFEvaluationSheet)evalSheet).getXSSFSheet();
|
||||
|
|
|
@ -18,17 +18,22 @@
|
|||
package org.apache.poi.ss.formula;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.CellType;
|
||||
import org.apache.poi.ss.usermodel.CellValue;
|
||||
import org.apache.poi.ss.usermodel.FormulaEvaluator;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Table;
|
||||
import org.apache.poi.ss.util.AreaReference;
|
||||
import org.apache.poi.ss.util.CellReference;
|
||||
import org.apache.poi.xssf.XSSFTestDataSamples;
|
||||
import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFTable;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -63,8 +68,40 @@ public class TestStructuredReferences {
|
|||
try {
|
||||
|
||||
final FormulaEvaluator eval = new XSSFFormulaEvaluator(wb);
|
||||
confirm(eval, wb.getSheet("Table").getRow(5).getCell(0), 49);
|
||||
confirm(eval, wb.getSheet("Formulas").getRow(0).getCell(0), 209);
|
||||
final XSSFSheet tableSheet = wb.getSheet("Table");
|
||||
final XSSFSheet formulaSheet = wb.getSheet("Formulas");
|
||||
|
||||
confirm(eval, tableSheet.getRow(5).getCell(0), 49);
|
||||
confirm(eval, formulaSheet.getRow(0).getCell(0), 209);
|
||||
confirm(eval, formulaSheet.getRow(1).getCell(0), "one");
|
||||
|
||||
// test changing a table value, to see if the caches are properly cleared
|
||||
// Issue 59814
|
||||
|
||||
// this test passes before the fix for 59814
|
||||
tableSheet.getRow(1).getCell(1).setCellValue("ONEA");
|
||||
confirm(eval, formulaSheet.getRow(1).getCell(0), "ONEA");
|
||||
|
||||
// test adding a row to a table, issue 59814
|
||||
Row newRow = tableSheet.getRow(7);
|
||||
if (newRow == null) newRow = tableSheet.createRow(7);
|
||||
newRow.createCell(0, CellType.FORMULA).setCellFormula("\\_Prime.1[[#This Row],[@Number]]*\\_Prime.1[[#This Row],[@Number]]");
|
||||
newRow.createCell(1, CellType.STRING).setCellValue("thirteen");
|
||||
newRow.createCell(2, CellType.NUMERIC).setCellValue(13);
|
||||
|
||||
// update Table
|
||||
final XSSFTable table = wb.getTable("\\_Prime.1");
|
||||
final AreaReference newArea = new AreaReference(table.getStartCellReference(), new CellReference(table.getEndRowIndex() + 1, table.getEndColIndex()));
|
||||
String newAreaStr = newArea.formatAsString();
|
||||
table.getCTTable().setRef(newAreaStr);
|
||||
table.getCTTable().getAutoFilter().setRef(newAreaStr);
|
||||
table.updateHeaders();
|
||||
table.updateReferences();
|
||||
|
||||
// these fail before the fix for 59814
|
||||
confirm(eval, tableSheet.getRow(7).getCell(0), 13*13);
|
||||
confirm(eval, formulaSheet.getRow(0).getCell(0), 209 + 13*13);
|
||||
|
||||
} finally {
|
||||
wb.close();
|
||||
}
|
||||
|
@ -78,4 +115,13 @@ public class TestStructuredReferences {
|
|||
}
|
||||
assertEquals(expectedResult, cv.getNumberValue(), 0.0);
|
||||
}
|
||||
|
||||
private static void confirm(FormulaEvaluator fe, Cell cell, String expectedResult) {
|
||||
fe.clearAllCachedResultValues();
|
||||
CellValue cv = fe.evaluate(cell);
|
||||
if (cv.getCellType() != CellType.STRING) {
|
||||
fail("expected String cell type but got " + cv.formatAsString());
|
||||
}
|
||||
assertEquals(expectedResult, cv.getStringValue());
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue