Commit 4d0c2412 authored by konovalovsergey's avatar konovalovsergey

LengthCache deleted because few formulas used cache

parent 48b8edcd
...@@ -3562,7 +3562,7 @@ function parserFormula( formula, parent, _ws ) { ...@@ -3562,7 +3562,7 @@ function parserFormula( formula, parent, _ws ) {
this.operand_str = null; this.operand_str = null;
this.parenthesesNotEnough = false; this.parenthesesNotEnough = false;
this.f = []; this.f = [];
this.reRowCol = new RegExp( "^(ROW|ROWS|COLUMN|COLUMNS)$", "gi" ); this.reRowCol = /^(ROW|ROWS|COLUMN|COLUMNS)$/gi
this.regSpace = /\$/g; this.regSpace = /\$/g;
this.countRef = 0; this.countRef = 0;
...@@ -4758,7 +4758,7 @@ parserFormula.prototype.buildDependencies = function() { ...@@ -4758,7 +4758,7 @@ parserFormula.prototype.buildDependencies = function() {
continue; continue;
} }
if ((ref instanceof cRef || ref instanceof cRef3D || ref instanceof cArea || ref instanceof cArea3D) && if ((cElementType.cell === ref.type || cElementType.cell3D === ref.type || cElementType.cellsRange === ref.type || cElementType.cellsRange3D === ref.type) &&
ref.isValid() && this.outStack[i + 1] && this.outStack[i + 1] instanceof cBaseFunction && ref.isValid() && this.outStack[i + 1] && this.outStack[i + 1] instanceof cBaseFunction &&
this.reRowCol.test(this.outStack[i + 1].name)) { this.reRowCol.test(this.outStack[i + 1].name)) {
this.reRowCol.lastIndex = 0; this.reRowCol.lastIndex = 0;
...@@ -4767,10 +4767,10 @@ parserFormula.prototype.buildDependencies = function() { ...@@ -4767,10 +4767,10 @@ parserFormula.prototype.buildDependencies = function() {
if (ref.type == cElementType.name || ref.type == cElementType.name3D) { if (ref.type == cElementType.name || ref.type == cElementType.name3D) {
this.wb.dependencyFormulas.startListeningDefName(ref.value, this); this.wb.dependencyFormulas.startListeningDefName(ref.value, this);
} else if ((ref instanceof cRef || ref instanceof cRef3D || ref instanceof cArea) && ref.isValid()) { } else if ((cElementType.cell === ref.type || cElementType.cell3D === ref.type || cElementType.cellsRange === ref.type) && ref.isValid()) {
var bbox = AscCommonExcel.g_oRangeCache.getActiveRange(ref._cells.replace(this.regSpace, "")); var bbox = AscCommonExcel.g_oRangeCache.getActiveRange(ref._cells.replace(this.regSpace, ""));
this.wb.dependencyFormulas.startListeningRange(ref.getWsId(), bbox, this); this.wb.dependencyFormulas.startListeningRange(ref.getWsId(), bbox, this);
} else if (ref instanceof cArea3D && ref.isValid()) { } else if (cElementType.cellsRange3D === ref.type && ref.isValid()) {
wsR = ref.wsRange(); wsR = ref.wsRange();
for (var j = 0; j < wsR.length; j++) { for (var j = 0; j < wsR.length; j++) {
var bbox = AscCommonExcel.g_oRangeCache.getActiveRange(ref._cells.replace(this.regSpace, "")); var bbox = AscCommonExcel.g_oRangeCache.getActiveRange(ref._cells.replace(this.regSpace, ""));
...@@ -4795,7 +4795,7 @@ parserFormula.prototype.buildDependencies = function() { ...@@ -4795,7 +4795,7 @@ parserFormula.prototype.buildDependencies = function() {
continue; continue;
} }
if ((ref instanceof cRef || ref instanceof cRef3D || ref instanceof cArea || ref instanceof cArea3D) && if ((cElementType.cell === ref.type || cElementType.cell3D === ref.type || cElementType.cellsRange === ref.type || cElementType.cellsRange3D === ref.type) &&
ref.isValid() && this.outStack[i + 1] && this.outStack[i + 1] instanceof cBaseFunction && ref.isValid() && this.outStack[i + 1] && this.outStack[i + 1] instanceof cBaseFunction &&
this.reRowCol.test(this.outStack[i + 1].name)) { this.reRowCol.test(this.outStack[i + 1].name)) {
this.reRowCol.lastIndex = 0; this.reRowCol.lastIndex = 0;
...@@ -4804,10 +4804,10 @@ parserFormula.prototype.buildDependencies = function() { ...@@ -4804,10 +4804,10 @@ parserFormula.prototype.buildDependencies = function() {
if (ref.type == cElementType.name || ref.type == cElementType.name3D) { if (ref.type == cElementType.name || ref.type == cElementType.name3D) {
this.wb.dependencyFormulas.endListeningDefName(ref.value, this); this.wb.dependencyFormulas.endListeningDefName(ref.value, this);
} else if ((ref instanceof cRef || ref instanceof cRef3D || ref instanceof cArea) && ref.isValid()) { } else if ((cElementType.cell === ref.type || cElementType.cell3D === ref.type || cElementType.cellsRange === ref.type) && ref.isValid()) {
var bbox = AscCommonExcel.g_oRangeCache.getActiveRange(ref._cells.replace(this.regSpace, "")); var bbox = AscCommonExcel.g_oRangeCache.getActiveRange(ref._cells.replace(this.regSpace, ""));
this.wb.dependencyFormulas.endListeningRange(ref.getWsId(), bbox, this); this.wb.dependencyFormulas.endListeningRange(ref.getWsId(), bbox, this);
} else if (ref instanceof cArea3D && ref.isValid()) { } else if (cElementType.cellsRange3D === ref.type && ref.isValid()) {
wsR = ref.wsRange(); wsR = ref.wsRange();
for (var j = 0; j < wsR.length; j++) { for (var j = 0; j < wsR.length; j++) {
var bbox = AscCommonExcel.g_oRangeCache.getActiveRange(ref._cells.replace(this.regSpace, "")); var bbox = AscCommonExcel.g_oRangeCache.getActiveRange(ref._cells.replace(this.regSpace, ""));
......
...@@ -788,14 +788,14 @@ function getRangeType(oBBox){ ...@@ -788,14 +788,14 @@ function getRangeType(oBBox){
for (var sheetId in this.buildCell) { for (var sheetId in this.buildCell) {
var ws = this.wb.getWorksheetById(sheetId); var ws = this.wb.getWorksheetById(sheetId);
if (ws) { if (ws) {
var _rec = {};
var unparsedSheet = this.buildCell[sheetId]; var unparsedSheet = this.buildCell[sheetId];
for (var cellIndex in unparsedSheet) { for (var cellIndex in unparsedSheet) {
getFromCellIndex(cellIndex); getFromCellIndex(cellIndex);
var cellId = g_oCellAddressUtils.getCellId(g_FCI.row, g_FCI.col); var cell = ws._getCellNoEmpty(g_FCI.row, g_FCI.col);
_rec[cellId] = cellId; if (cell) {
cell._BuildDependencies(true, true);
}
} }
ws._BuildDependencies(_rec, true);
} }
} }
for (var defNameId in this.buildDefName) { for (var defNameId in this.buildDefName) {
...@@ -839,7 +839,7 @@ function getRangeType(oBBox){ ...@@ -839,7 +839,7 @@ function getRangeType(oBBox){
} }
console.timeEnd('calculate'); console.timeEnd('calculate');
console.time('cleanCellCache'); console.time('cleanCellCache');
for (i in this.cleanCellCache) { for (var i in this.cleanCellCache) {
this.wb.handlers.trigger("cleanCellCache", i, {0: this.cleanCellCache[i]}, this.wb.handlers.trigger("cleanCellCache", i, {0: this.cleanCellCache[i]},
AscCommonExcel.c_oAscCanChangeColWidth.none); AscCommonExcel.c_oAscCanChangeColWidth.none);
} }
...@@ -1306,23 +1306,15 @@ Workbook.prototype.init=function(bNoBuildDep){ ...@@ -1306,23 +1306,15 @@ Workbook.prototype.init=function(bNoBuildDep){
self.dependencyFormulas.delTableName( name ); self.dependencyFormulas.delTableName( name );
} }
} ); } );
var cwf = {};
for(var i = 0, length = this.aWorksheets.length; i < length; ++i) for(var i = 0, length = this.aWorksheets.length; i < length; ++i)
{ {
var ws = this.aWorksheets[i]; var ws = this.aWorksheets[i];
ws.initPostOpen(this.wsHandlers, cwf); ws.initPostOpen(this.wsHandlers, bNoBuildDep);
} }
if(!bNoBuildDep){ if(!bNoBuildDep){
/*
buildDependency необходимо запускать для построения графа зависимостей между ячейками.
Сортировка графа производится при необходимости пересчета формул:
при открытии документа если есть ячейки помеченные как пересчитываемые или есть ячейки без значения.
*/
this.buildDependency(cwf);
this.dependencyFormulas.calcTree(); this.dependencyFormulas.calcTree();
} }
}; };
Workbook.prototype.rebuildColors=function(){ Workbook.prototype.rebuildColors=function(){
AscCommonExcel.g_oColorManager.rebuildColors(); AscCommonExcel.g_oColorManager.rebuildColors();
...@@ -1756,11 +1748,6 @@ Workbook.prototype.getUniqueDefinedNameFrom=function(name, bCopy){ ...@@ -1756,11 +1748,6 @@ Workbook.prototype.getUniqueDefinedNameFrom=function(name, bCopy){
} }
return dnNewName; return dnNewName;
}; };
Workbook.prototype.buildDependency = function(cwf){
for(var i in cwf){
this.getWorksheetById(i)._BuildDependencies(cwf[i]);
}
};
Workbook.prototype._SerializeHistoryBase64 = function (oMemory, item, aPointChangesBase64) { Workbook.prototype._SerializeHistoryBase64 = function (oMemory, item, aPointChangesBase64) {
if (!item.LocalChange) { if (!item.LocalChange) {
var nPosStart = oMemory.GetCurPosition(); var nPosStart = oMemory.GetCurPosition();
...@@ -2291,82 +2278,62 @@ Woorksheet.prototype.copyDrawingObjects=function(oNewWs, wsFrom) ...@@ -2291,82 +2278,62 @@ Woorksheet.prototype.copyDrawingObjects=function(oNewWs, wsFrom)
drawingObjects.updateChartReferences2(parserHelp.getEscapeSheetName(wsFrom.sName), parserHelp.getEscapeSheetName(oNewWs.sName)); drawingObjects.updateChartReferences2(parserHelp.getEscapeSheetName(wsFrom.sName), parserHelp.getEscapeSheetName(oNewWs.sName));
} }
}; };
Woorksheet.prototype.initPostOpen = function (handlers, opt_cwfWb) { Woorksheet.prototype.initPostOpen = function (handlers, bNoBuildDep) {
var cwf = {};
if(opt_cwfWb){
opt_cwfWb[this.getId()] = cwf;
}
if (this.aFormulaExt) { if (this.aFormulaExt) {
var formulaShared = {}; var formulaShared = {};
for (var i = 0; i < this.aFormulaExt.length; ++i) { for (var i = 0; i < this.aFormulaExt.length; ++i) {
var elem = this.aFormulaExt[i]; var elem = this.aFormulaExt[i];
var notifyData = {type: AscCommon.c_oNotifyType.Dirty}; var oCell = elem.cell;
var oCell = elem.cell; var oFormulaExt = elem.ext;
var sCellId = g_oCellAddressUtils.getCellId(oCell.nRow, oCell.nCol); var isShared = oFormulaExt.t === Asc.ECellFormulaType.cellformulatypeShared && null !== oFormulaExt.si;
var oFormulaExt = elem.ext; if (isShared) {
var isShared = oFormulaExt.t === Asc.ECellFormulaType.cellformulatypeShared && null !== oFormulaExt.si; if (null !== oFormulaExt.ref) {
if (isShared) { if (oFormulaExt.v.length <= AscCommon.c_oAscMaxFormulaLength) {
if (null !== oFormulaExt.ref) { oCell.formulaParsed = new parserFormula(oFormulaExt.v, oCell, this);
if (oFormulaExt.v.length <= AscCommon.c_oAscMaxFormulaLength) { oCell.formulaParsed.ca = oFormulaExt.ca;
oCell.formulaParsed = new parserFormula(oFormulaExt.v, oCell, this); oCell.formulaParsed.parse();
oCell.formulaParsed.ca = oFormulaExt.ca; formulaShared[oFormulaExt.si] = {
oCell.formulaParsed.parse(); fVal: oCell.formulaParsed,
oCell.formulaParsed.buildDependencies(); fRef: AscCommonExcel.g_oRangeCache.getAscRange(oFormulaExt.ref)
formulaShared[oFormulaExt.si] = { };
fVal: oCell.formulaParsed, fRef: AscCommonExcel.g_oRangeCache.getAscRange(oFormulaExt.ref) if (!bNoBuildDep) {
}; oCell._BuildDependencies(false);
if (oCell.formulaParsed && (oFormulaExt.ca || !oCell.oValue.getValueWithoutFormat())) { }
this.workbook.dependencyFormulas.addToChangedCell(oCell); }
} } else {
} var fs = formulaShared[oFormulaExt.si];
} else { if (fs && fs.fRef.contains(oCell.nCol, oCell.nRow)) {
var fs = formulaShared[oFormulaExt.si]; if (fs.fVal.isParsed) {
if (fs && fs.fRef.contains(oCell.nCol, oCell.nRow)) { var off = oCell.getOffset3(fs.fRef.c1 + 1, fs.fRef.r1 + 1);
if (fs.fVal.isParsed) {
var off = oCell.getOffset3(fs.fRef.c1 + 1, fs.fRef.r1 + 1); oCell.formulaParsed = fs.fVal.clone(null, oCell, this);
oCell.formulaParsed.ca = oFormulaExt.ca;
oCell.formulaParsed = fs.fVal.clone(null, oCell, this); oCell.formulaParsed.changeOffset(off);
oCell.formulaParsed.ca = oFormulaExt.ca; oCell.formulaParsed.Formula = oCell.formulaParsed.assemble();
oCell.formulaParsed.changeOffset(off); oFormulaExt.v = oCell.formulaParsed.Formula;
oCell.formulaParsed.buildDependencies(); if (!bNoBuildDep) {
oCell.formulaParsed.Formula = oCell.formulaParsed.assemble(); oCell._BuildDependencies(false);
oFormulaExt.v = oCell.formulaParsed.Formula; }
if (oCell.formulaParsed && (oFormulaExt.ca || !oCell.oValue.getValueWithoutFormat())) { }
this.workbook.dependencyFormulas.addToChangedCell(oCell); }
} }
} }
} if (oFormulaExt.v) {
} if (oFormulaExt.v.length <= AscCommon.c_oAscMaxFormulaLength) {
} if (!oCell.formulaParsed) {
if (oFormulaExt.v) { oCell.formulaParsed = new parserFormula(oFormulaExt.v, oCell, this);
if (oFormulaExt.v.length <= AscCommon.c_oAscMaxFormulaLength) { oCell.formulaParsed.ca = oFormulaExt.ca;
if (!oCell.formulaParsed) { if (!bNoBuildDep) {
oCell.formulaParsed = new parserFormula(oFormulaExt.v, oCell, this); oCell._BuildDependencies(true);
oCell.formulaParsed.ca = oFormulaExt.ca; }
} }
} else {
} else { this.workbook.openErrors.push(oCell.getName());
this.workbook.openErrors.push(oCell.getName()); }
} }
} }
this.aFormulaExt = null;
// Если ячейка содержит в себе формулу, то добавляем ее в список ячеек с формулами. (Shared-формулу мы уже распарсили) }
if (isShared) {
;//cwf[sCellId] = null;
} else {
if (oCell.formulaParsed) {
cwf[sCellId] = sCellId;
}
}
// Строится список ячеек, которые необходимо пересчитать при открытии. Это ячейки имеющие атрибут f.ca или значение в которых неопределено.
// if (oCell.sFormula && (oFormulaExt.ca || !oCell.oValue.getValueWithoutFormat())) {
// this.workbook.needRecalc.nodes[getVertexId(this.Id, sCellId)] = [this.Id, sCellId];
// this.workbook.needRecalc.length++;
// }
}
this.aFormulaExt = null;
}
if (!this.PagePrintOptions) { if (!this.PagePrintOptions) {
// Даже если не было, создадим // Даже если не было, создадим
...@@ -4016,111 +3983,22 @@ Woorksheet.prototype._shiftCellsBottom=function(oBBox, displayNameFormatTable){ ...@@ -4016,111 +3983,22 @@ Woorksheet.prototype._shiftCellsBottom=function(oBBox, displayNameFormatTable){
Woorksheet.prototype._setIndex=function(ind){ Woorksheet.prototype._setIndex=function(ind){
this.index = ind; this.index = ind;
}; };
Woorksheet.prototype._BuildDependencies=function(cellRange, dirty){ Woorksheet.prototype._BuildDependencies=function(cellRange){
/* /*
Построение графа зависимостей. Построение графа зависимостей.
*/ */
var c, ca, oLengthCache = {}; var c, ca;
for(var i in cellRange){ for (var i in cellRange) {
if (null === cellRange[i]) { if (null === cellRange[i]) {
cellRange[i] = i; cellRange[i] = i;
continue; continue;
} }
ca = g_oCellAddressUtils.getCellAddress(i); ca = g_oCellAddressUtils.getCellAddress(i);
c = this._getCellNoEmpty(ca.getRow0(),ca.getCol0()); c = this._getCellNoEmpty(ca.getRow0(), ca.getCol0());
if( c && c.formulaParsed ){ if (c) {
var elem = oLengthCache[c.formulaParsed.Formula.length]; c._BuildDependencies(true);
if(null == elem)
{
elem = [];
oLengthCache[c.formulaParsed.Formula.length] = elem;
}
elem.push(c);
}
}
for(var i in oLengthCache)
{
var temp = oLengthCache[i];
var aCache = [];
for(var j = 0, length2 = temp.length; j < length2; j++)
{
var c = temp[j],
cellId = g_oCellAddressUtils.getCellId(c.nRow, c.nCol ),
aRefs = [],
cache = inCache(aCache, c.formulaParsed.Formula, aRefs ),
bInCache = false;
if(cache)
{
bInCache = true;
var oNewFormula = cache.formulaParsed.clone(c.formulaParsed.Formula, c, this);
var RefPos = cache.formulaParsed.RefPos;
for(var k = 0, length3 = RefPos.length; k < length3; k++)
{
var pos = RefPos[k];
var elem = oNewFormula.outStack[pos.index];
if(elem)
{
//todo случай ,если ref число или именованный диапазон
var ref = aRefs[k];
var range = AscCommonExcel.g_oRangeCache.getAscRange(ref);
if(null != range)
{
var oNewElem;
if(range.isOneCell())
{
if(elem instanceof cRef3D)
oNewElem = new cRef3D(ref, elem.ws.getName(), elem._wb);
else if(elem instanceof cArea3D)
{
var wsFrom = elem._wb.getWorksheetById( elem.wsFrom ).getName();
var wsTo = elem._wb.getWorksheetById( elem.wsTo ).getName();
oNewElem = new cArea3D(ref, wsFrom, wsTo, elem._wb);
}
else if(-1 != ref.indexOf(":"))//случай "A1:A1"
oNewElem = new AscCommonExcel.cArea(ref, elem.ws);
else
oNewElem = new AscCommonExcel.cRef(ref, elem.ws);
}
else
{
if(elem instanceof cRef3D)
oNewElem = new cArea3D(ref, elem.ws.getName(), elem.ws.getName(), elem._wb);
else if(elem instanceof cArea3D)
{
var wsFrom = elem._wb.getWorksheetById( elem.wsFrom ).getName();
var wsTo = elem._wb.getWorksheetById( elem.wsTo ).getName();
oNewElem = new cArea3D(ref, wsFrom, wsTo, elem._wb);
}
else
oNewElem = new AscCommonExcel.cArea(ref, elem.ws);
}
if ( ref.indexOf( "$" ) > -1 )
oNewElem.isAbsolute = true; // ToDo - пересмотреть этот параметр (есть в Range информация о абсолютной ссылке)
oNewFormula.outStack[pos.index] = oNewElem;
}
else
bInCache = false;
}
}
if(bInCache)
{
c.formulaParsed = oNewFormula;
c.formulaParsed.buildDependencies();
}
}
if(!bInCache)
{
c.formulaParsed.parse();
c.formulaParsed.buildDependencies();
//error не добавляем в кеш у них не распознались RefPos, их бессмысленно сравнивать.Это только добавит торозов
if(0 == c.formulaParsed.error.length)
aCache.push(c);
}
if (c.formulaParsed && (dirty || c.formulaParsed.ca || !c.oValue.getValueWithoutFormat())) {
this.workbook.dependencyFormulas.addToChangedCell(c);
}
} }
} }
}; };
...@@ -4178,63 +4056,6 @@ Woorksheet.prototype.getTableNameColumnByIndex = function(tableName, columnIndex ...@@ -4178,63 +4056,6 @@ Woorksheet.prototype.getTableNameColumnByIndex = function(tableName, columnIndex
} }
return res; return res;
}; };
function inCache(aCache, sFormula, aRefs)
{
var oRes = null;
for(var i = 0, length = aCache.length; i < length; i++)
{
var cache = aCache[i];
if(null != cache.formulaParsed){
var sCurFormula = cache.formulaParsed.Formula;
var RefPos = cache.formulaParsed.RefPos;
//todo свое сравнение для error
if(0 == cache.formulaParsed.error.length && inCacheStrcmp(sCurFormula, sFormula, RefPos, aRefs)){
oRes = cache;
break;
}
}
}
return oRes;
}
function inCacheStrcmp(str1, str2, RefPos, aRefs)
{
var bRes = true;
var nStartIndex = 0;
for(var i = 0, length = RefPos.length; i < length; i++)
{
var mask = RefPos[i];
for(var j = nStartIndex; j < mask.start; j++)
{
if(str1[j] != str2[j])
{
bRes = false;
break;
}
}
nStartIndex = mask.end;
}
if(bRes)
{
for(var i = nStartIndex; i < str1.length; i++)
{
if(str1[i] != str2[i])
{
bRes = false;
break;
}
}
}
if(bRes)
{
for(var i = 0, length = RefPos.length; i < length; i++)
{
var mask = RefPos[i];
aRefs.push(str2.substring(mask.start, mask.end));
}
}
return bRes;
}
Woorksheet.prototype.renameDependencyNodes = function(offset, oBBox, rec, noDelete){ Woorksheet.prototype.renameDependencyNodes = function(offset, oBBox, rec, noDelete){
this.workbook.dependencyFormulas.shift(this.Id, oBBox, offset); this.workbook.dependencyFormulas.shift(this.Id, oBBox, offset);
}; };
...@@ -5014,6 +4835,17 @@ Cell.prototype.setValueData = function(Val){ ...@@ -5014,6 +4835,17 @@ Cell.prototype.setValueData = function(Val){
this.formulaParsed.ca = res.ca; this.formulaParsed.ca = res.ca;
} }
}; };
Cell.prototype._BuildDependencies = function(parse, opt_dirty) {
if (this.formulaParsed) {
if (parse) {
this.formulaParsed.parse();
}
this.formulaParsed.buildDependencies();
if (opt_dirty || this.formulaParsed.ca || !this.oValue.getValueWithoutFormat()) {
this.ws.workbook.dependencyFormulas.addToChangedCell(this);
}
}
};
//------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------
/** /**
......
...@@ -3156,8 +3156,9 @@ CCellValue.prototype = ...@@ -3156,8 +3156,9 @@ CCellValue.prototype =
} }
if(null == aRes) if(null == aRes)
aRes = this._getValue2Result(cell, sText, aText); aRes = this._getValue2Result(cell, sText, aText);
if( cell.sFormula ){ var formula = cell.getFormula();
aRes[0].sFormula = cell.sFormula; if( formula ){
aRes[0].sFormula = formula;
aRes[0].sId = cell.getName(); aRes[0].sId = cell.getName();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment