[Libreoffice-commits] core.git: Branch 'feature/calc-group-interpreter-4' - 4 commits - sc/inc sc/qa sc/source
Kohei Yoshida
kohei.yoshida at collabora.com
Mon Oct 28 07:38:27 PDT 2013
sc/inc/column.hxx | 2
sc/inc/document.hxx | 7
sc/inc/formulagroup.hxx | 41 ++
sc/inc/table.hxx | 3
sc/qa/unit/ucalc_formula.cxx | 89 +++++
sc/source/core/data/column2.cxx | 546 +++++++++++++----------------------
sc/source/core/data/documen2.cxx | 3
sc/source/core/data/documen7.cxx | 5
sc/source/core/data/document.cxx | 15
sc/source/core/data/formulacell.cxx | 12
sc/source/core/data/table1.cxx | 5
sc/source/core/tool/formulagroup.cxx | 87 +++++
12 files changed, 452 insertions(+), 363 deletions(-)
New commits:
commit 20d7d56703148fa9fde35df33e440efe5d48f9e6
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Mon Oct 28 10:37:28 2013 -0400
Cache column data arrays to avoid duplicating data arrays.
Each array's start position is always row 0, to keep the array element
indices in sync with row positions.
Change-Id: I4781fd8c24111bd991216293ad362eef283767bd
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index ca0374e..44ddf38 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -480,7 +480,7 @@ public:
formula::FormulaTokenRef ResolveStaticReference( SCROW nRow );
bool ResolveStaticReference( ScMatrix& rMat, SCCOL nMatCol, SCROW nRow1, SCROW nRow2 );
void FillMatrix( ScMatrix& rMat, size_t nMatCol, SCROW nRow1, SCROW nRow2 ) const;
- formula::VectorRefArray FetchVectorRefArray( sc::FormulaGroupContext& rCxt, SCROW nRow1, SCROW nRow2 );
+ formula::VectorRefArray FetchVectorRefArray( SCROW nRow1, SCROW nRow2 );
void SetFormulaResults( SCROW nRow, const double* pResults, size_t nLen );
void SetFormulaResults( SCROW nRow, const formula::FormulaTokenRef* pResults, size_t nLen );
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 752984d..62f4814 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -68,6 +68,7 @@ struct ColumnBlockPosition;
struct RefUpdateContext;
class EditTextIterator;
struct NoteEntry;
+struct FormulaGroupContext;
}
@@ -254,6 +255,7 @@ private:
rtl::Reference<ScPoolHelper> xPoolHelper;
boost::scoped_ptr<svl::SharedStringPool> mpCellStringPool;
+ boost::scoped_ptr<sc::FormulaGroupContext> mpFormulaGroupCxt;
SfxUndoManager* mpUndoManager;
ScFieldEditEngine* pEditEngine; // uses pEditPool from xPoolHelper
@@ -862,6 +864,8 @@ public:
svl::SharedString GetSharedString( const ScAddress& rPos ) const;
+ sc::FormulaGroupContext& GetFormulaGroupContext();
+
SC_DLLPUBLIC void GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab, OUString& rString );
sal_uInt16 GetStringForFormula( const ScAddress& rPos, OUString& rString );
SC_DLLPUBLIC double GetValue( const ScAddress& rPos ) const;
@@ -2018,8 +2022,7 @@ public:
formula::FormulaTokenRef ResolveStaticReference( const ScAddress& rPos );
formula::FormulaTokenRef ResolveStaticReference( const ScRange& rRange );
- formula::VectorRefArray FetchVectorRefArray(
- sc::FormulaGroupContext& rCxt, const ScAddress& rPos, SCROW nLength );
+ formula::VectorRefArray FetchVectorRefArray( const ScAddress& rPos, SCROW nLength );
SvtBroadcaster* GetBroadcaster( const ScAddress& rPos );
const SvtBroadcaster* GetBroadcaster( const ScAddress& rPos ) const;
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 3c7aa0e..394847f 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -854,8 +854,7 @@ public:
ScFormulaVectorState GetFormulaVectorState( SCCOL nCol, SCROW nRow ) const;
formula::FormulaTokenRef ResolveStaticReference( SCCOL nCol, SCROW nRow );
formula::FormulaTokenRef ResolveStaticReference( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
- formula::VectorRefArray FetchVectorRefArray(
- sc::FormulaGroupContext& rCxt, SCCOL nCol, SCROW nRow1, SCROW nRow2 );
+ formula::VectorRefArray FetchVectorRefArray( SCCOL nCol, SCROW nRow1, SCROW nRow2 );
ScRefCellValue GetRefCellValue( SCCOL nCol, SCROW nRow );
diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index ab16141..e87878a 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -76,8 +76,7 @@ void Test::testFetchVectorRefArray()
m_pDoc->SetValue(ScAddress(0,2,0), 3);
m_pDoc->SetValue(ScAddress(0,3,0), 4);
- sc::FormulaGroupContext aCxt;
- formula::VectorRefArray aArray = m_pDoc->FetchVectorRefArray(aCxt, ScAddress(0,0,0), 4);
+ formula::VectorRefArray aArray = m_pDoc->FetchVectorRefArray(ScAddress(0,0,0), 4);
CPPUNIT_ASSERT_MESSAGE("Failed to fetch vector ref array.", aArray.isValid());
CPPUNIT_ASSERT_MESSAGE("Array is expected to be numeric cells only.", !aArray.mpStringArray);
CPPUNIT_ASSERT_EQUAL(1.0, aArray.mpNumericArray[0]);
@@ -85,7 +84,7 @@ void Test::testFetchVectorRefArray()
CPPUNIT_ASSERT_EQUAL(3.0, aArray.mpNumericArray[2]);
CPPUNIT_ASSERT_EQUAL(4.0, aArray.mpNumericArray[3]);
- aArray = m_pDoc->FetchVectorRefArray(aCxt, ScAddress(0,0,0), 5);
+ aArray = m_pDoc->FetchVectorRefArray(ScAddress(0,0,0), 5);
CPPUNIT_ASSERT_MESSAGE("Failed to fetch vector ref array.", aArray.isValid());
CPPUNIT_ASSERT_MESSAGE("Array is expected to be numeric cells only.", !aArray.mpStringArray);
CPPUNIT_ASSERT_EQUAL(1.0, aArray.mpNumericArray[0]);
@@ -102,7 +101,7 @@ void Test::testFetchVectorRefArray()
m_pDoc->SetString(ScAddress(1,1,0), "Bruce");
m_pDoc->SetString(ScAddress(1,2,0), "Charlie");
m_pDoc->SetString(ScAddress(1,3,0), "David");
- aArray = m_pDoc->FetchVectorRefArray(aCxt, ScAddress(1,0,0), 5);
+ aArray = m_pDoc->FetchVectorRefArray(ScAddress(1,0,0), 5);
CPPUNIT_ASSERT_MESSAGE("Failed to fetch vector ref array.", aArray.isValid());
CPPUNIT_ASSERT_MESSAGE("Array is expected to be string cells only.", !aArray.mpNumericArray);
CPPUNIT_ASSERT_MESSAGE("Unexpected string cell.", equals(aArray, 0, "Andy"));
@@ -119,7 +118,7 @@ void Test::testFetchVectorRefArray()
m_pDoc->SetString(ScAddress(2,5,0), "=SUM(C2:C4)");
m_pDoc->CalcAll();
- aArray = m_pDoc->FetchVectorRefArray(aCxt, ScAddress(2,0,0), 7);
+ aArray = m_pDoc->FetchVectorRefArray(ScAddress(2,0,0), 7);
CPPUNIT_ASSERT_MESSAGE("Failed to fetch vector ref array.", aArray.isValid());
CPPUNIT_ASSERT_MESSAGE("Array should have both numeric and string arrays.", aArray.mpNumericArray && aArray.mpStringArray);
CPPUNIT_ASSERT_MESSAGE("Unexpected string cell.", equals(aArray, 0, "Header"));
@@ -140,7 +139,7 @@ void Test::testFetchVectorRefArray()
m_pDoc->SetString(ScAddress(3,7,0), "=CONCATENATE(\"A\";\"B\";\"C\")");
m_pDoc->CalcAll();
- aArray = m_pDoc->FetchVectorRefArray(aCxt, ScAddress(3,0,0), 8);
+ aArray = m_pDoc->FetchVectorRefArray(ScAddress(3,0,0), 8);
CPPUNIT_ASSERT_MESSAGE("Failed to fetch vector ref array.", aArray.isValid());
CPPUNIT_ASSERT_MESSAGE("Array should have both numeric and string arrays.", aArray.mpNumericArray && aArray.mpStringArray);
CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 0, 10));
@@ -162,7 +161,7 @@ void Test::testFetchVectorRefArray()
m_pDoc->SetValue(ScAddress(4,9,0), 123);
// This array fits within a single formula block.
- aArray = m_pDoc->FetchVectorRefArray(aCxt, ScAddress(4,0,0), 5);
+ aArray = m_pDoc->FetchVectorRefArray(ScAddress(4,0,0), 5);
CPPUNIT_ASSERT_MESSAGE("Failed to fetch vector ref array.", aArray.isValid());
CPPUNIT_ASSERT_MESSAGE("Array should be purely numeric.", aArray.mpNumericArray && !aArray.mpStringArray);
CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 0, 1));
@@ -172,7 +171,7 @@ void Test::testFetchVectorRefArray()
CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 4, 5));
// This array spans over multiple blocks.
- aArray = m_pDoc->FetchVectorRefArray(aCxt, ScAddress(4,0,0), 11);
+ aArray = m_pDoc->FetchVectorRefArray(ScAddress(4,0,0), 11);
CPPUNIT_ASSERT_MESSAGE("Failed to fetch vector ref array.", aArray.isValid());
CPPUNIT_ASSERT_MESSAGE("Array should have both numeric and string arrays.", aArray.mpNumericArray && aArray.mpStringArray);
CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 0, 1));
@@ -188,7 +187,7 @@ void Test::testFetchVectorRefArray()
CPPUNIT_ASSERT_MESSAGE("This should be empty.", isEmpty(aArray, 10));
// Hit the cache but at a different start row.
- aArray = m_pDoc->FetchVectorRefArray(aCxt, ScAddress(4,2,0), 3);
+ aArray = m_pDoc->FetchVectorRefArray(ScAddress(4,2,0), 3);
CPPUNIT_ASSERT_MESSAGE("Failed to fetch vector ref array.", aArray.isValid());
CPPUNIT_ASSERT_MESSAGE("Array should at least have a numeric array.", aArray.mpNumericArray);
CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 0, 3));
@@ -201,7 +200,7 @@ void Test::testFetchVectorRefArray()
m_pDoc->SetString(ScAddress(5,4,0), "=2*8");
m_pDoc->CalcAll();
- aArray = m_pDoc->FetchVectorRefArray(aCxt, ScAddress(5,2,0), 4);
+ aArray = m_pDoc->FetchVectorRefArray(ScAddress(5,2,0), 4);
CPPUNIT_ASSERT_MESSAGE("Failed to fetch vector ref array.", aArray.isValid());
CPPUNIT_ASSERT_MESSAGE("Array should at least have a numeric array.", aArray.mpNumericArray);
CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 0, 1.1));
@@ -209,14 +208,14 @@ void Test::testFetchVectorRefArray()
CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 2, 16));
CPPUNIT_ASSERT_MESSAGE("This should be empty.", isEmpty(aArray, 3));
- aArray = m_pDoc->FetchVectorRefArray(aCxt, ScAddress(5,0,0), 3);
+ aArray = m_pDoc->FetchVectorRefArray(ScAddress(5,0,0), 3);
CPPUNIT_ASSERT_MESSAGE("Failed to fetch vector ref array.", aArray.isValid());
CPPUNIT_ASSERT_MESSAGE("Array should at least have a numeric array.", aArray.mpNumericArray);
CPPUNIT_ASSERT_MESSAGE("This should be empty.", isEmpty(aArray, 0));
CPPUNIT_ASSERT_MESSAGE("This should be empty.", isEmpty(aArray, 1));
CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 2, 1.1));
- aArray = m_pDoc->FetchVectorRefArray(aCxt, ScAddress(5,0,0), 10);
+ aArray = m_pDoc->FetchVectorRefArray(ScAddress(5,0,0), 10);
CPPUNIT_ASSERT_MESSAGE("Failed to fetch vector ref array.", aArray.isValid());
CPPUNIT_ASSERT_MESSAGE("Array should at least have a numeric array.", aArray.mpNumericArray);
CPPUNIT_ASSERT_MESSAGE("This should be empty.", isEmpty(aArray, 0));
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index b44cf97..aff16d5 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2616,12 +2616,13 @@ copyFirstFormulaBlock(
}
-formula::VectorRefArray ScColumn::FetchVectorRefArray( sc::FormulaGroupContext& rCxt, SCROW nRow1, SCROW nRow2 )
+formula::VectorRefArray ScColumn::FetchVectorRefArray( SCROW nRow1, SCROW nRow2 )
{
if (nRow1 > nRow2)
return formula::VectorRefArray();
// See if the requested range is already cached.
+ sc::FormulaGroupContext& rCxt = pDocument->GetFormulaGroupContext();
sc::FormulaGroupContext::ColArray* pColArray = rCxt.getCachedColArray(nTab, nCol, nRow2+1);
if (pColArray)
{
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 982d977..930c8d1 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -90,6 +90,7 @@
#include "clipcontext.hxx"
#include "refupdatecontext.hxx"
#include "scopetools.hxx"
+#include "formulagroup.hxx"
using namespace com::sun::star;
@@ -121,6 +122,7 @@ private:
ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
mpCellStringPool(new svl::SharedStringPool(ScGlobal::pCharClass)),
+ mpFormulaGroupCxt(NULL),
mpUndoManager( NULL ),
pEditEngine( NULL ),
pNoteEngine( NULL ),
@@ -442,6 +444,7 @@ ScDocument::~ScDocument()
delete pPreviewFont;
OSL_POSTCOND( !pAutoNameCache, "AutoNameCache still set in dtor" );
+ mpFormulaGroupCxt.reset();
mpCellStringPool.reset();
}
diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx
index 56ce8d1..7dd9821 100644
--- a/sc/source/core/data/documen7.cxx
+++ b/sc/source/core/data/documen7.cxx
@@ -36,6 +36,7 @@
#include "sheetevents.hxx"
#include "tokenarray.hxx"
#include "listenercontext.hxx"
+#include "formulagroup.hxx"
#include <tools/shl.hxx>
@@ -296,6 +297,8 @@ void ScDocument::CalcFormulaTree( bool bOnlyForced, bool bProgressBar, bool bSet
// never ever recurse into this, might end up lost in infinity
if ( IsCalculatingFormulaTree() )
return ;
+
+ mpFormulaGroupCxt.reset();
bCalculatingFormulaTree = true;
SetForcedFormulaPending( false );
@@ -394,6 +397,8 @@ void ScDocument::CalcFormulaTree( bool bOnlyForced, bool bProgressBar, bool bSet
bAutoCalc = bOldAutoCalc;
EnableIdle(bOldIdleEnabled);
bCalculatingFormulaTree = false;
+
+ mpFormulaGroupCxt.reset();
}
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index ccf7d32..74e5135 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -94,6 +94,7 @@
#include "listenercontext.hxx"
#include "scopetools.hxx"
#include "refupdatecontext.hxx"
+#include "formulagroup.hxx"
#include "formula/vectortoken.hxx"
@@ -1675,14 +1676,13 @@ formula::FormulaTokenRef ScDocument::ResolveStaticReference( const ScRange& rRan
rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row());
}
-formula::VectorRefArray ScDocument::FetchVectorRefArray(
- sc::FormulaGroupContext& rCxt, const ScAddress& rPos, SCROW nLength )
+formula::VectorRefArray ScDocument::FetchVectorRefArray( const ScAddress& rPos, SCROW nLength )
{
SCTAB nTab = rPos.Tab();
if (!TableExists(nTab))
return formula::VectorRefArray();
- return maTabs[nTab]->FetchVectorRefArray(rCxt, rPos.Col(), rPos.Row(), rPos.Row()+nLength-1);
+ return maTabs[nTab]->FetchVectorRefArray(rPos.Col(), rPos.Row(), rPos.Row()+nLength-1);
}
bool ScDocument::CanFitBlock( const ScRange& rOld, const ScRange& rNew )
@@ -3223,6 +3223,14 @@ svl::SharedString ScDocument::GetSharedString( const ScAddress& rPos ) const
return maTabs[rPos.Tab()]->GetSharedString(rPos.Col(), rPos.Row());
}
+sc::FormulaGroupContext& ScDocument::GetFormulaGroupContext()
+{
+ if (!mpFormulaGroupCxt)
+ mpFormulaGroupCxt.reset(new sc::FormulaGroupContext);
+
+ return *mpFormulaGroupCxt;
+}
+
void ScDocument::GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab, OUString& rString )
{
if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
@@ -3603,6 +3611,7 @@ void ScDocument::CalcAll()
if (*it)
(*it)->CalcAll();
ClearFormulaTree();
+ mpFormulaGroupCxt.reset();
}
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 4d0284b..4f27592 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -3327,7 +3327,6 @@ namespace {
class GroupTokenConverter
{
- sc::FormulaGroupContext& mrCxt;
ScTokenArray& mrGroupTokens;
ScDocument& mrDoc;
ScFormulaCell& mrCell;
@@ -3389,8 +3388,8 @@ class GroupTokenConverter
return nRowLen;
}
public:
- GroupTokenConverter(sc::FormulaGroupContext& rCxt, ScTokenArray& rGroupTokens, ScDocument& rDoc, ScFormulaCell& rCell, const ScAddress& rPos) :
- mrCxt(rCxt), mrGroupTokens(rGroupTokens), mrDoc(rDoc), mrCell(rCell), mrPos(rPos) {}
+ GroupTokenConverter(ScTokenArray& rGroupTokens, ScDocument& rDoc, ScFormulaCell& rCell, const ScAddress& rPos) :
+ mrGroupTokens(rGroupTokens), mrDoc(rDoc), mrCell(rCell), mrPos(rPos) {}
bool convert(ScTokenArray& rCode)
{
@@ -3430,7 +3429,7 @@ public:
// returned array equals or greater than the requested
// length.
- formula::VectorRefArray aArray = mrDoc.FetchVectorRefArray(mrCxt, aRefPos, nLen);
+ formula::VectorRefArray aArray = mrDoc.FetchVectorRefArray(aRefPos, nLen);
if (!aArray.isValid())
return false;
@@ -3498,7 +3497,7 @@ public:
for (SCCOL i = aAbs.aStart.Col(); i <= aAbs.aEnd.Col(); ++i)
{
aRefPos.SetCol(i);
- formula::VectorRefArray aArray = mrDoc.FetchVectorRefArray(mrCxt, aRefPos, nArrayLength);
+ formula::VectorRefArray aArray = mrDoc.FetchVectorRefArray(aRefPos, nArrayLength);
if (!aArray.isValid())
return false;
@@ -3575,11 +3574,10 @@ bool ScFormulaCell::InterpretFormulaGroup()
if (mxGroup->mbInvariant && false)
return InterpretInvariantFormulaGroup();
- sc::FormulaGroupContext aCxt;
ScTokenArray aCode;
ScAddress aTopPos = aPos;
aTopPos.SetRow(mxGroup->mnStart);
- GroupTokenConverter aConverter(aCxt, aCode, *pDocument, *this, aTopPos);
+ GroupTokenConverter aConverter(aCode, *pDocument, *this, aTopPos);
if (!aConverter.convert(*pCode))
{
mxGroup->meCalcState = sc::GroupCalcDisabled;
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index 45762fa..ee1ed95 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -2175,8 +2175,7 @@ formula::FormulaTokenRef ScTable::ResolveStaticReference( SCCOL nCol1, SCROW nRo
return formula::FormulaTokenRef(new ScMatrixToken(pMat));
}
-formula::VectorRefArray ScTable::FetchVectorRefArray(
- sc::FormulaGroupContext& rCxt, SCCOL nCol, SCROW nRow1, SCROW nRow2 )
+formula::VectorRefArray ScTable::FetchVectorRefArray( SCCOL nCol, SCROW nRow1, SCROW nRow2 )
{
if (nRow2 < nRow1)
return formula::VectorRefArray();
@@ -2184,7 +2183,7 @@ formula::VectorRefArray ScTable::FetchVectorRefArray(
if (!ValidCol(nCol) || !ValidRow(nRow1) || !ValidRow(nRow2))
return formula::VectorRefArray();
- return aCol[nCol].FetchVectorRefArray(rCxt, nRow1, nRow2);
+ return aCol[nCol].FetchVectorRefArray(nRow1, nRow2);
}
ScRefCellValue ScTable::GetRefCellValue( SCCOL nCol, SCROW nRow )
commit ad5130342d8a9dde6b087067ccbd570c2d6c411b
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Fri Oct 25 23:45:14 2013 -0400
Remove duplicated code blocks.
Change-Id: If9d8f96af0a216609288ef11d83a622bb490fd98
diff --git a/sc/inc/formulagroup.hxx b/sc/inc/formulagroup.hxx
index c1eadbb..1691e8d 100644
--- a/sc/inc/formulagroup.hxx
+++ b/sc/inc/formulagroup.hxx
@@ -69,6 +69,9 @@ struct FormulaGroupContext : boost::noncopyable
ColArray* setCachedColArray(
SCTAB nTab, SCCOL nCol, NumArrayType* pNumArray, StrArrayType* pStrArray );
+
+ void ensureStrArray( ColArray& rColArray, size_t nArrayLen );
+ void ensureNumArray( ColArray& rColArray, size_t nArrayLen );
};
/**
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index daaff25..b44cf97 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2426,13 +2426,7 @@ bool appendToBlock(
{
sc::string_block::iterator itData, itDataEnd;
getBlockIterators<sc::string_block>(it, nLenRemain, itData, itDataEnd);
-
- if (!rColArray.mpStrArray)
- {
- rCxt.maStrArrays.push_back(
- new sc::FormulaGroupContext::StrArrayType(nArrayLen, NULL));
- rColArray.mpStrArray = &rCxt.maStrArrays.back();
- }
+ rCxt.ensureStrArray(rColArray, nArrayLen);
for (; itData != itDataEnd; ++itData, ++nPos)
(*rColArray.mpStrArray)[nPos] = itData->getDataIgnoreCase();
@@ -2442,13 +2436,7 @@ bool appendToBlock(
{
sc::edittext_block::iterator itData, itDataEnd;
getBlockIterators<sc::edittext_block>(it, nLenRemain, itData, itDataEnd);
-
- if (!rColArray.mpStrArray)
- {
- rCxt.maStrArrays.push_back(
- new sc::FormulaGroupContext::StrArrayType(nArrayLen, NULL));
- rColArray.mpStrArray = &rCxt.maStrArrays.back();
- }
+ rCxt.ensureStrArray(rColArray, nArrayLen);
for (; itData != itDataEnd; ++itData, ++nPos)
{
@@ -2479,24 +2467,12 @@ bool appendToBlock(
if (aRes.meType == sc::FormulaResultValue::String)
{
- if (!rColArray.mpStrArray)
- {
- rCxt.maStrArrays.push_back(
- new sc::FormulaGroupContext::StrArrayType(nArrayLen, NULL));
- rColArray.mpStrArray = &rCxt.maStrArrays.back();
- }
-
+ rCxt.ensureStrArray(rColArray, nArrayLen);
(*rColArray.mpStrArray)[nPos] = aRes.maString.getDataIgnoreCase();
}
else
{
- if (!rColArray.mpNumArray)
- {
- rCxt.maNumArrays.push_back(
- new sc::FormulaGroupContext::NumArrayType(nArrayLen, fNan));
- rColArray.mpNumArray = &rCxt.maNumArrays.back();
- }
-
+ rCxt.ensureNumArray(rColArray, nArrayLen);
(*rColArray.mpNumArray)[nPos] = aRes.mfValue;
}
}
@@ -2520,13 +2496,7 @@ bool appendToBlock(
{
sc::numeric_block::iterator itData, itDataEnd;
getBlockIterators<sc::numeric_block>(it, nLenRemain, itData, itDataEnd);
-
- if (!rColArray.mpNumArray)
- {
- rCxt.maNumArrays.push_back(
- new sc::FormulaGroupContext::NumArrayType(nArrayLen, fNan));
- rColArray.mpNumArray = &rCxt.maNumArrays.back();
- }
+ rCxt.ensureNumArray(rColArray, nArrayLen);
for (; itData != itDataEnd; ++itData, ++nPos)
(*rColArray.mpNumArray)[nPos] = *itData;
diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx
index 9482b1f..05f098f 100644
--- a/sc/source/core/tool/formulagroup.cxx
+++ b/sc/source/core/tool/formulagroup.cxx
@@ -103,6 +103,29 @@ FormulaGroupContext::ColArray* FormulaGroupContext::setCachedColArray(
return &rArray;
}
+void FormulaGroupContext::ensureStrArray( ColArray& rColArray, size_t nArrayLen )
+{
+ if (rColArray.mpStrArray)
+ return;
+
+ maStrArrays.push_back(
+ new sc::FormulaGroupContext::StrArrayType(nArrayLen, NULL));
+ rColArray.mpStrArray = &maStrArrays.back();
+}
+
+void FormulaGroupContext::ensureNumArray( ColArray& rColArray, size_t nArrayLen )
+{
+ if (rColArray.mpNumArray)
+ return;
+
+ double fNan;
+ rtl::math::setNan(&fNan);
+
+ maNumArrays.push_back(
+ new sc::FormulaGroupContext::NumArrayType(nArrayLen, fNan));
+ rColArray.mpNumArray = &maNumArrays.back();
+}
+
namespace {
/**
commit 7ecff76bfefad20ea9dee63b98752e447bb8e2c3
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Fri Oct 25 23:08:52 2013 -0400
Some cleanup to remove duplicated code.
Change-Id: I522d3259636f6ebb29c3f4da2155c9322a382903
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 22aca0a..daaff25 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2409,87 +2409,14 @@ void getBlockIterators(
}
}
-bool appendDouble(
- sc::FormulaGroupContext::NumArrayType& rArray, size_t nLen,
- sc::CellStoreType::iterator it, const sc::CellStoreType::iterator& itEnd )
-{
- size_t nLenRemain = nLen;
- double fNan;
- rtl::math::setNan(&fNan);
-
- for (; it != itEnd; ++it)
- {
- switch (it->type)
- {
- case sc::element_type_numeric:
- {
- sc::numeric_block::iterator itData, itDataEnd;
- getBlockIterators<sc::numeric_block>(it, nLenRemain, itData, itDataEnd);
-
- for (; itData != itDataEnd; ++itData)
- rArray.push_back(*itData);
- }
- break;
- case sc::element_type_formula:
- {
- sc::formula_block::iterator itData, itDataEnd;
- getBlockIterators<sc::formula_block>(it, nLenRemain, itData, itDataEnd);
-
- sal_uInt16 nErr;
- double fVal;
- for (; itData != itDataEnd; ++itData)
- {
- ScFormulaCell& rFC = **itData;
- if (!rFC.GetErrorOrValue(nErr, fVal) || nErr)
- {
- if (nErr == ScErrorCodes::errCircularReference)
- {
- // This cell needs to be recalculated on next visit.
- rFC.SetErrCode(0);
- rFC.SetDirtyVar();
- }
- return false;
- }
-
- rArray.push_back(fVal);
- }
- }
- break;
- case sc::element_type_empty:
- {
- // Fill it with NaN's.
- if (nLenRemain >= it->size)
- {
- rArray.resize(rArray.size() + it->size, fNan);
- nLenRemain -= it->size;
- }
- else
- {
- rArray.resize(rArray.size() + nLenRemain, fNan);
- nLenRemain = 0;
- }
- }
- break;
- case sc::element_type_string:
- case sc::element_type_edittext:
- default:
- return false;
- }
-
- if (!nLenRemain)
- return true;
- }
-
- return false;
-}
-
-bool appendToNumBlock(
+bool appendToBlock(
ScDocument* pDoc, sc::FormulaGroupContext& rCxt, sc::FormulaGroupContext::ColArray& rColArray,
size_t nPos, size_t nArrayLen, sc::CellStoreType::iterator it, const sc::CellStoreType::iterator& itEnd )
{
- sc::FormulaGroupContext::NumArrayType& rNumArray = *rColArray.mpNumArray;
svl::SharedStringPool& rPool = pDoc->GetSharedStringPool();
size_t nLenRemain = nArrayLen - nPos;
+ double fNan;
+ rtl::math::setNan(&fNan);
for (; it != itEnd; ++it)
{
@@ -2550,9 +2477,7 @@ bool appendToNumBlock(
return false;
}
- if (aRes.meType == sc::FormulaResultValue::Value)
- rNumArray[nPos] = aRes.mfValue;
- else
+ if (aRes.meType == sc::FormulaResultValue::String)
{
if (!rColArray.mpStrArray)
{
@@ -2563,100 +2488,6 @@ bool appendToNumBlock(
(*rColArray.mpStrArray)[nPos] = aRes.maString.getDataIgnoreCase();
}
- }
- }
- break;
- case sc::element_type_empty:
- {
- if (nLenRemain > it->size)
- {
- nPos += it->size;
- nLenRemain -= it->size;
- }
- else
- {
- nPos = nArrayLen;
- nLenRemain = 0;
- }
- }
- break;
- case sc::element_type_numeric:
- {
- sc::numeric_block::iterator itData, itDataEnd;
- getBlockIterators<sc::numeric_block>(it, nLenRemain, itData, itDataEnd);
-
- for (; itData != itDataEnd; ++itData, ++nPos)
- rNumArray[nPos] = *itData;
- }
- break;
- default:
- return false;
- }
-
- if (!nLenRemain)
- return true;
- }
-
- return false;
-}
-
-bool appendToStringBlock(
- ScDocument* pDoc, sc::FormulaGroupContext& rCxt, sc::FormulaGroupContext::ColArray& rColArray,
- size_t nPos, size_t nArrayLen, sc::CellStoreType::iterator it, const sc::CellStoreType::iterator& itEnd )
-{
- sc::FormulaGroupContext::StrArrayType& rStrArray = *rColArray.mpStrArray;
- svl::SharedStringPool& rPool = pDoc->GetSharedStringPool();
- size_t nLenRemain = nArrayLen - nPos;
- double fNan;
- rtl::math::setNan(&fNan);
-
- for (; it != itEnd; ++it)
- {
- switch (it->type)
- {
- case sc::element_type_string:
- {
- sc::string_block::iterator itData, itDataEnd;
- getBlockIterators<sc::string_block>(it, nLenRemain, itData, itDataEnd);
-
- for (; itData != itDataEnd; ++itData, ++nPos)
- rStrArray[nPos] = itData->getDataIgnoreCase();
- }
- break;
- case sc::element_type_edittext:
- {
- sc::edittext_block::iterator itData, itDataEnd;
- getBlockIterators<sc::edittext_block>(it, nLenRemain, itData, itDataEnd);
-
- for (; itData != itDataEnd; ++itData, ++nPos)
- {
- OUString aStr = ScEditUtil::GetString(**itData, pDoc);
- rStrArray[nPos] = rPool.intern(aStr).getDataIgnoreCase();
- }
- }
- break;
- case sc::element_type_formula:
- {
- sc::formula_block::iterator itData, itDataEnd;
- getBlockIterators<sc::formula_block>(it, nLenRemain, itData, itDataEnd);
-
- for (; itData != itDataEnd; ++itData, ++nPos)
- {
- ScFormulaCell& rFC = **itData;
- sc::FormulaResultValue aRes = rFC.GetResult();
- if (aRes.meType == sc::FormulaResultValue::Invalid || aRes.mnError)
- {
- if (aRes.mnError == ScErrorCodes::errCircularReference)
- {
- // This cell needs to be recalculated on next visit.
- rFC.SetErrCode(0);
- rFC.SetDirtyVar();
- }
- return false;
- }
-
- if (aRes.meType == sc::FormulaResultValue::String)
- rStrArray[nPos] = aRes.maString.getDataIgnoreCase();
else
{
if (!rColArray.mpNumArray)
@@ -2866,10 +2697,8 @@ formula::VectorRefArray ScColumn::FetchVectorRefArray( sc::FormulaGroupContext&
// Fill the remaining array with values from the following blocks.
size_t nPos = itBlk->size;
++itBlk;
- if (!appendToNumBlock(pDocument, rCxt, *pColArray, nPos, nRow2+1, itBlk, maCells.end()))
- {
+ if (!appendToBlock(pDocument, rCxt, *pColArray, nPos, nRow2+1, itBlk, maCells.end()))
return formula::VectorRefArray();
- }
if (pColArray->mpStrArray)
return formula::VectorRefArray(&(*pColArray->mpNumArray)[nRow1], &(*pColArray->mpStrArray)[nRow1]);
@@ -2899,7 +2728,7 @@ formula::VectorRefArray ScColumn::FetchVectorRefArray( sc::FormulaGroupContext&
// Fill the remaining array with values from the following blocks.
size_t nPos = itBlk->size;
++itBlk;
- if (!appendToStringBlock(pDocument, rCxt, *pColArray, nPos, nRow2+1, itBlk, maCells.end()))
+ if (!appendToBlock(pDocument, rCxt, *pColArray, nPos, nRow2+1, itBlk, maCells.end()))
return formula::VectorRefArray();
if (pColArray->mpNumArray)
@@ -2936,16 +2765,8 @@ formula::VectorRefArray ScColumn::FetchVectorRefArray( sc::FormulaGroupContext&
size_t nPos = itBlk->size;
++itBlk;
- if (pColArray->mpNumArray)
- {
- if (!appendToNumBlock(pDocument, rCxt, *pColArray, nPos, nRow2+1, itBlk, maCells.end()))
- return formula::VectorRefArray();
- }
- else
- {
- if (!appendToStringBlock(pDocument, rCxt, *pColArray, nPos, nRow2+1, itBlk, maCells.end()))
- return formula::VectorRefArray();
- }
+ if (!appendToBlock(pDocument, rCxt, *pColArray, nPos, nRow2+1, itBlk, maCells.end()))
+ return formula::VectorRefArray();
const double* pNum = NULL;
rtl_uString** pStr = NULL;
@@ -2973,7 +2794,7 @@ formula::VectorRefArray ScColumn::FetchVectorRefArray( sc::FormulaGroupContext&
// Fill the remaining array with values from the following blocks.
size_t nPos = itBlk->size;
++itBlk;
- if (!appendToNumBlock(pDocument, rCxt, *pColArray, nPos, nRow2+1, itBlk, maCells.end()))
+ if (!appendToBlock(pDocument, rCxt, *pColArray, nPos, nRow2+1, itBlk, maCells.end()))
return formula::VectorRefArray();
if (pColArray->mpStrArray)
commit 487777b8068cce4851f31773ea4622a7efb3b875
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Fri Oct 25 22:03:18 2013 -0400
Add cache of column data arrays to the group formula context.
Change-Id: I225491a1c6dd0b5aa2663331b30d177a7e62329b
diff --git a/sc/inc/formulagroup.hxx b/sc/inc/formulagroup.hxx
index ca240f7..c1eadbb 100644
--- a/sc/inc/formulagroup.hxx
+++ b/sc/inc/formulagroup.hxx
@@ -33,8 +33,42 @@ struct FormulaGroupContext : boost::noncopyable
typedef boost::ptr_vector<NumArrayType> NumArrayStoreType;
typedef boost::ptr_vector<StrArrayType> StrArrayStoreType;
- NumArrayStoreType maNumArrays;
- StrArrayStoreType maStrArrays;
+ struct ColKey
+ {
+ SCTAB mnTab;
+ SCCOL mnCol;
+
+ struct Hash
+ {
+ size_t operator() ( const ColKey& rKey ) const;
+ };
+
+ ColKey( SCTAB nTab, SCCOL nCol );
+
+ bool operator== ( const ColKey& r ) const;
+ bool operator!= ( const ColKey& r ) const;
+ };
+
+ struct ColArray
+ {
+ NumArrayType* mpNumArray;
+ StrArrayType* mpStrArray;
+ size_t mnSize;
+
+ ColArray( NumArrayType* pNumArray, StrArrayType* pStrArray );
+ };
+
+ typedef boost::unordered_map<ColKey, ColArray, ColKey::Hash> ColArraysType;
+
+ NumArrayStoreType maNumArrays; /// manage life cycle of numeric arrays.
+ StrArrayStoreType maStrArrays; /// manage life cycle of string arrays.
+
+ ColArraysType maColArrays; /// keep track of longest array for each column.
+
+ ColArray* getCachedColArray( SCTAB nTab, SCCOL nCol, size_t nSize );
+
+ ColArray* setCachedColArray(
+ SCTAB nTab, SCCOL nCol, NumArrayType* pNumArray, StrArrayType* pStrArray );
};
/**
diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index 034e0e3..ab16141 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -152,6 +152,84 @@ void Test::testFetchVectorRefArray()
CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 6, 13));
CPPUNIT_ASSERT_MESSAGE("Unexpected string cell.", equals(aArray, 7, "ABC"));
+ // Column E consists of formula cells whose results are all numeric.
+ for (SCROW i = 0; i <= 6; ++i)
+ m_pDoc->SetString(ScAddress(4,i,0), "=ROW()");
+ m_pDoc->CalcAll();
+
+ // Leave row 7 empty.
+ m_pDoc->SetString(ScAddress(4,8,0), "Andy");
+ m_pDoc->SetValue(ScAddress(4,9,0), 123);
+
+ // This array fits within a single formula block.
+ aArray = m_pDoc->FetchVectorRefArray(aCxt, ScAddress(4,0,0), 5);
+ CPPUNIT_ASSERT_MESSAGE("Failed to fetch vector ref array.", aArray.isValid());
+ CPPUNIT_ASSERT_MESSAGE("Array should be purely numeric.", aArray.mpNumericArray && !aArray.mpStringArray);
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 0, 1));
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 1, 2));
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 2, 3));
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 3, 4));
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 4, 5));
+
+ // This array spans over multiple blocks.
+ aArray = m_pDoc->FetchVectorRefArray(aCxt, ScAddress(4,0,0), 11);
+ CPPUNIT_ASSERT_MESSAGE("Failed to fetch vector ref array.", aArray.isValid());
+ CPPUNIT_ASSERT_MESSAGE("Array should have both numeric and string arrays.", aArray.mpNumericArray && aArray.mpStringArray);
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 0, 1));
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 1, 2));
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 2, 3));
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 3, 4));
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 4, 5));
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 5, 6));
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 6, 7));
+ CPPUNIT_ASSERT_MESSAGE("This should be empty.", isEmpty(aArray, 7));
+ CPPUNIT_ASSERT_MESSAGE("Unexpected string cell.", equals(aArray, 8, "Andy"));
+ CPPUNIT_ASSERT_MESSAGE("Unexpected string cell.", equals(aArray, 9, 123));
+ CPPUNIT_ASSERT_MESSAGE("This should be empty.", isEmpty(aArray, 10));
+
+ // Hit the cache but at a different start row.
+ aArray = m_pDoc->FetchVectorRefArray(aCxt, ScAddress(4,2,0), 3);
+ CPPUNIT_ASSERT_MESSAGE("Failed to fetch vector ref array.", aArray.isValid());
+ CPPUNIT_ASSERT_MESSAGE("Array should at least have a numeric array.", aArray.mpNumericArray);
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 0, 3));
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 1, 4));
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 2, 5));
+
+ // Column F begins with empty rows at the top.
+ m_pDoc->SetValue(ScAddress(5,2,0), 1.1);
+ m_pDoc->SetValue(ScAddress(5,3,0), 1.2);
+ m_pDoc->SetString(ScAddress(5,4,0), "=2*8");
+ m_pDoc->CalcAll();
+
+ aArray = m_pDoc->FetchVectorRefArray(aCxt, ScAddress(5,2,0), 4);
+ CPPUNIT_ASSERT_MESSAGE("Failed to fetch vector ref array.", aArray.isValid());
+ CPPUNIT_ASSERT_MESSAGE("Array should at least have a numeric array.", aArray.mpNumericArray);
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 0, 1.1));
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 1, 1.2));
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 2, 16));
+ CPPUNIT_ASSERT_MESSAGE("This should be empty.", isEmpty(aArray, 3));
+
+ aArray = m_pDoc->FetchVectorRefArray(aCxt, ScAddress(5,0,0), 3);
+ CPPUNIT_ASSERT_MESSAGE("Failed to fetch vector ref array.", aArray.isValid());
+ CPPUNIT_ASSERT_MESSAGE("Array should at least have a numeric array.", aArray.mpNumericArray);
+ CPPUNIT_ASSERT_MESSAGE("This should be empty.", isEmpty(aArray, 0));
+ CPPUNIT_ASSERT_MESSAGE("This should be empty.", isEmpty(aArray, 1));
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 2, 1.1));
+
+ aArray = m_pDoc->FetchVectorRefArray(aCxt, ScAddress(5,0,0), 10);
+ CPPUNIT_ASSERT_MESSAGE("Failed to fetch vector ref array.", aArray.isValid());
+ CPPUNIT_ASSERT_MESSAGE("Array should at least have a numeric array.", aArray.mpNumericArray);
+ CPPUNIT_ASSERT_MESSAGE("This should be empty.", isEmpty(aArray, 0));
+ CPPUNIT_ASSERT_MESSAGE("This should be empty.", isEmpty(aArray, 1));
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 2, 1.1));
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 3, 1.2));
+ CPPUNIT_ASSERT_MESSAGE("Unexpected numeric cell.", equals(aArray, 4, 16));
+ CPPUNIT_ASSERT_MESSAGE("This should be empty.", isEmpty(aArray, 5));
+ CPPUNIT_ASSERT_MESSAGE("This should be empty.", isEmpty(aArray, 6));
+ CPPUNIT_ASSERT_MESSAGE("This should be empty.", isEmpty(aArray, 7));
+ CPPUNIT_ASSERT_MESSAGE("This should be empty.", isEmpty(aArray, 8));
+ CPPUNIT_ASSERT_MESSAGE("This should be empty.", isEmpty(aArray, 9));
+
m_pDoc->DeleteTab(0);
}
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 5113435..22aca0a 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2483,14 +2483,13 @@ bool appendDouble(
return false;
}
-formula::VectorRefArray appendToNumBlock(
- ScDocument* pDoc, sc::FormulaGroupContext& rCxt, size_t nPos,
- size_t nLenRequested, sc::CellStoreType::iterator it, const sc::CellStoreType::iterator& itEnd )
+bool appendToNumBlock(
+ ScDocument* pDoc, sc::FormulaGroupContext& rCxt, sc::FormulaGroupContext::ColArray& rColArray,
+ size_t nPos, size_t nArrayLen, sc::CellStoreType::iterator it, const sc::CellStoreType::iterator& itEnd )
{
- sc::FormulaGroupContext::NumArrayType& rNumArray = rCxt.maNumArrays.back();
- sc::FormulaGroupContext::StrArrayType* pStrArray = NULL;
+ sc::FormulaGroupContext::NumArrayType& rNumArray = *rColArray.mpNumArray;
svl::SharedStringPool& rPool = pDoc->GetSharedStringPool();
- size_t nLenRemain = nLenRequested - nPos;
+ size_t nLenRemain = nArrayLen - nPos;
for (; it != itEnd; ++it)
{
@@ -2501,15 +2500,15 @@ formula::VectorRefArray appendToNumBlock(
sc::string_block::iterator itData, itDataEnd;
getBlockIterators<sc::string_block>(it, nLenRemain, itData, itDataEnd);
- if (!pStrArray)
+ if (!rColArray.mpStrArray)
{
rCxt.maStrArrays.push_back(
- new sc::FormulaGroupContext::StrArrayType(nLenRequested, NULL));
- pStrArray = &rCxt.maStrArrays.back();
+ new sc::FormulaGroupContext::StrArrayType(nArrayLen, NULL));
+ rColArray.mpStrArray = &rCxt.maStrArrays.back();
}
for (; itData != itDataEnd; ++itData, ++nPos)
- (*pStrArray)[nPos] = itData->getDataIgnoreCase();
+ (*rColArray.mpStrArray)[nPos] = itData->getDataIgnoreCase();
}
break;
case sc::element_type_edittext:
@@ -2517,17 +2516,17 @@ formula::VectorRefArray appendToNumBlock(
sc::edittext_block::iterator itData, itDataEnd;
getBlockIterators<sc::edittext_block>(it, nLenRemain, itData, itDataEnd);
- if (!pStrArray)
+ if (!rColArray.mpStrArray)
{
rCxt.maStrArrays.push_back(
- new sc::FormulaGroupContext::StrArrayType(nLenRequested, NULL));
- pStrArray = &rCxt.maStrArrays.back();
+ new sc::FormulaGroupContext::StrArrayType(nArrayLen, NULL));
+ rColArray.mpStrArray = &rCxt.maStrArrays.back();
}
for (; itData != itDataEnd; ++itData, ++nPos)
{
OUString aStr = ScEditUtil::GetString(**itData, pDoc);
- (*pStrArray)[nPos] = rPool.intern(aStr).getDataIgnoreCase();
+ (*rColArray.mpStrArray)[nPos] = rPool.intern(aStr).getDataIgnoreCase();
}
}
break;
@@ -2548,21 +2547,21 @@ formula::VectorRefArray appendToNumBlock(
rFC.SetErrCode(0);
rFC.SetDirtyVar();
}
- return formula::VectorRefArray();
+ return false;
}
if (aRes.meType == sc::FormulaResultValue::Value)
rNumArray[nPos] = aRes.mfValue;
else
{
- if (!pStrArray)
+ if (!rColArray.mpStrArray)
{
rCxt.maStrArrays.push_back(
- new sc::FormulaGroupContext::StrArrayType(nLenRequested, NULL));
- pStrArray = &rCxt.maStrArrays.back();
+ new sc::FormulaGroupContext::StrArrayType(nArrayLen, NULL));
+ rColArray.mpStrArray = &rCxt.maStrArrays.back();
}
- (*pStrArray)[nPos] = aRes.maString.getDataIgnoreCase();
+ (*rColArray.mpStrArray)[nPos] = aRes.maString.getDataIgnoreCase();
}
}
}
@@ -2576,7 +2575,7 @@ formula::VectorRefArray appendToNumBlock(
}
else
{
- nPos = nLenRequested;
+ nPos = nArrayLen;
nLenRemain = 0;
}
}
@@ -2591,29 +2590,23 @@ formula::VectorRefArray appendToNumBlock(
}
break;
default:
- return formula::VectorRefArray();
+ return false;
}
if (!nLenRemain)
- {
- if (pStrArray)
- return formula::VectorRefArray(&rNumArray[0], &(*pStrArray)[0]);
- else
- return formula::VectorRefArray(&rNumArray[0]);
- }
+ return true;
}
- return formula::VectorRefArray();
+ return false;
}
-formula::VectorRefArray appendToStringBlock(
- ScDocument* pDoc, sc::FormulaGroupContext& rCxt, size_t nPos,
- size_t nLenRequested, sc::CellStoreType::iterator it, const sc::CellStoreType::iterator& itEnd )
+bool appendToStringBlock(
+ ScDocument* pDoc, sc::FormulaGroupContext& rCxt, sc::FormulaGroupContext::ColArray& rColArray,
+ size_t nPos, size_t nArrayLen, sc::CellStoreType::iterator it, const sc::CellStoreType::iterator& itEnd )
{
- sc::FormulaGroupContext::StrArrayType& rStrArray = rCxt.maStrArrays.back();
- sc::FormulaGroupContext::NumArrayType* pNumArray = NULL;
+ sc::FormulaGroupContext::StrArrayType& rStrArray = *rColArray.mpStrArray;
svl::SharedStringPool& rPool = pDoc->GetSharedStringPool();
- size_t nLenRemain = nLenRequested - nPos;
+ size_t nLenRemain = nArrayLen - nPos;
double fNan;
rtl::math::setNan(&fNan);
@@ -2659,21 +2652,21 @@ formula::VectorRefArray appendToStringBlock(
rFC.SetErrCode(0);
rFC.SetDirtyVar();
}
- return formula::VectorRefArray();
+ return false;
}
if (aRes.meType == sc::FormulaResultValue::String)
rStrArray[nPos] = aRes.maString.getDataIgnoreCase();
else
{
- if (!pNumArray)
+ if (!rColArray.mpNumArray)
{
rCxt.maNumArrays.push_back(
- new sc::FormulaGroupContext::NumArrayType(nLenRequested, fNan));
- pNumArray = &rCxt.maNumArrays.back();
+ new sc::FormulaGroupContext::NumArrayType(nArrayLen, fNan));
+ rColArray.mpNumArray = &rCxt.maNumArrays.back();
}
- (*pNumArray)[nPos] = aRes.mfValue;
+ (*rColArray.mpNumArray)[nPos] = aRes.mfValue;
}
}
}
@@ -2687,7 +2680,7 @@ formula::VectorRefArray appendToStringBlock(
}
else
{
- nPos = nLenRequested;
+ nPos = nArrayLen;
nLenRemain = 0;
}
}
@@ -2697,60 +2690,56 @@ formula::VectorRefArray appendToStringBlock(
sc::numeric_block::iterator itData, itDataEnd;
getBlockIterators<sc::numeric_block>(it, nLenRemain, itData, itDataEnd);
- if (!pNumArray)
+ if (!rColArray.mpNumArray)
{
rCxt.maNumArrays.push_back(
- new sc::FormulaGroupContext::NumArrayType(nLenRequested, fNan));
- pNumArray = &rCxt.maNumArrays.back();
+ new sc::FormulaGroupContext::NumArrayType(nArrayLen, fNan));
+ rColArray.mpNumArray = &rCxt.maNumArrays.back();
}
for (; itData != itDataEnd; ++itData, ++nPos)
- (*pNumArray)[nPos] = *itData;
+ (*rColArray.mpNumArray)[nPos] = *itData;
}
break;
default:
- return formula::VectorRefArray();
+ return false;
}
if (!nLenRemain)
- {
- if (pNumArray)
- return formula::VectorRefArray(&(*pNumArray)[0], &rStrArray[0]);
- else
- return formula::VectorRefArray(&rStrArray[0]);
- }
+ return true;
}
- return formula::VectorRefArray();
+ return false;
}
void copyFirstStringBlock(
- ScDocument& rDoc, sc::FormulaGroupContext& rCxt, size_t nLen, const sc::CellStoreType::position_type& rPos )
+ ScDocument& rDoc, sc::FormulaGroupContext::StrArrayType& rArray, size_t nLen, const sc::CellStoreType::iterator& itBlk )
{
- rCxt.maStrArrays.push_back(new sc::FormulaGroupContext::StrArrayType);
- sc::FormulaGroupContext::StrArrayType& rArray = rCxt.maStrArrays.back();
- rArray.reserve(nLen);
+ sc::FormulaGroupContext::StrArrayType::iterator itArray = rArray.begin();
- switch (rPos.first->type)
+ switch (itBlk->type)
{
case sc::element_type_string:
{
- svl::SharedString* p = &sc::string_block::at(*rPos.first->data, rPos.second);
- svl::SharedString* pEnd = p + nLen;
- for (; p != pEnd; ++p)
- rArray.push_back(p->getDataIgnoreCase());
+ sc::string_block::iterator it = sc::string_block::begin(*itBlk->data);
+ sc::string_block::iterator itEnd = it;
+ std::advance(itEnd, nLen);
+ for (; it != itEnd; ++it, ++itArray)
+ *itArray = it->getDataIgnoreCase();
}
break;
case sc::element_type_edittext:
{
- EditTextObject** p = &sc::edittext_block::at(*rPos.first->data, rPos.second);
- EditTextObject** pEnd = p + nLen;
+ sc::edittext_block::iterator it = sc::edittext_block::begin(*itBlk->data);
+ sc::edittext_block::iterator itEnd = it;
+ std::advance(itEnd, nLen);
+
svl::SharedStringPool& rPool = rDoc.GetSharedStringPool();
- for (; p != pEnd; ++p)
+ for (; it != itEnd; ++it, ++itArray)
{
- EditTextObject* pText = *p;
+ EditTextObject* pText = *it;
OUString aStr = ScEditUtil::GetString(*pText, &rDoc);
- rArray.push_back(rPool.intern(aStr).getDataIgnoreCase());
+ *itArray = rPool.intern(aStr).getDataIgnoreCase();
}
}
break;
@@ -2759,6 +2748,71 @@ void copyFirstStringBlock(
}
}
+sc::FormulaGroupContext::ColArray*
+copyFirstFormulaBlock(
+ sc::FormulaGroupContext& rCxt, sc::CellStoreType::iterator itBlk, size_t nArrayLen,
+ SCTAB nTab, SCCOL nCol )
+{
+ double fNan;
+ rtl::math::setNan(&fNan);
+
+ size_t nLen = std::min(itBlk->size, nArrayLen);
+
+ sc::formula_block::iterator it = sc::formula_block::begin(*itBlk->data);
+ sc::formula_block::iterator itEnd;
+
+ sc::FormulaGroupContext::NumArrayType* pNumArray = NULL;
+ sc::FormulaGroupContext::StrArrayType* pStrArray = NULL;
+
+ itEnd = it;
+ std::advance(itEnd, nLen);
+ size_t nPos = 0;
+ for (; it != itEnd; ++it, ++nPos)
+ {
+ ScFormulaCell& rFC = **it;
+ sc::FormulaResultValue aRes = rFC.GetResult();
+ if (aRes.meType == sc::FormulaResultValue::Invalid || aRes.mnError)
+ {
+ if (aRes.mnError == ScErrorCodes::errCircularReference)
+ {
+ // This cell needs to be recalculated on next visit.
+ rFC.SetErrCode(0);
+ rFC.SetDirtyVar();
+ }
+ return NULL;
+ }
+
+ if (aRes.meType == sc::FormulaResultValue::Value)
+ {
+ if (!pNumArray)
+ {
+ rCxt.maNumArrays.push_back(
+ new sc::FormulaGroupContext::NumArrayType(nArrayLen, fNan));
+ pNumArray = &rCxt.maNumArrays.back();
+ }
+
+ (*pNumArray)[nPos] = aRes.mfValue;
+ }
+ else
+ {
+ if (!pStrArray)
+ {
+ rCxt.maStrArrays.push_back(
+ new sc::FormulaGroupContext::StrArrayType(nArrayLen, NULL));
+ pStrArray = &rCxt.maStrArrays.back();
+ }
+
+ (*pStrArray)[nPos] = aRes.maString.getDataIgnoreCase();
+ }
+ }
+
+ if (!pNumArray && !pStrArray)
+ // At least one of these arrays should be allocated.
+ return NULL;
+
+ return rCxt.setCachedColArray(nTab, nCol, pNumArray, pStrArray);
+}
+
}
formula::VectorRefArray ScColumn::FetchVectorRefArray( sc::FormulaGroupContext& rCxt, SCROW nRow1, SCROW nRow2 )
@@ -2766,142 +2820,168 @@ formula::VectorRefArray ScColumn::FetchVectorRefArray( sc::FormulaGroupContext&
if (nRow1 > nRow2)
return formula::VectorRefArray();
+ // See if the requested range is already cached.
+ sc::FormulaGroupContext::ColArray* pColArray = rCxt.getCachedColArray(nTab, nCol, nRow2+1);
+ if (pColArray)
+ {
+ const double* pNum = NULL;
+ if (pColArray->mpNumArray)
+ pNum = &(*pColArray->mpNumArray)[nRow1];
+
+ rtl_uString** pStr = NULL;
+ if (pColArray->mpStrArray)
+ pStr = &(*pColArray->mpStrArray)[nRow1];
+
+ return formula::VectorRefArray(pNum, pStr);
+ }
+
double fNan;
rtl::math::setNan(&fNan);
- size_t nLenRequested = nRow2 - nRow1 + 1;
- sc::CellStoreType::position_type aPos = maCells.position(nRow1);
- size_t nLen = aPos.first->size - aPos.second; // length of data from first block
- switch (aPos.first->type)
+ // We need to fetch all cell values from row 0 to nRow2 for caching purposes.
+ sc::CellStoreType::iterator itBlk = maCells.begin();
+ switch (itBlk->type)
{
case sc::element_type_numeric:
{
- // This is a numeric cell block.
- if (nLenRequested <= nLen)
+ if (static_cast<size_t>(nRow2) < itBlk->size)
{
- // Requested length fits a single block.
- const double* p = &sc::numeric_block::at(*aPos.first->data, aPos.second);
+ // Requested range falls within the first block. No need to cache.
+ const double* p = &sc::numeric_block::at(*itBlk->data, nRow1);
return formula::VectorRefArray(p);
}
// Allocate a new array and copy the values to it.
- sc::numeric_block::const_iterator it = sc::numeric_block::begin(*aPos.first->data);
- sc::numeric_block::const_iterator itEnd = sc::numeric_block::end(*aPos.first->data);
- std::advance(it, aPos.second);
+ sc::numeric_block::const_iterator it = sc::numeric_block::begin(*itBlk->data);
+ sc::numeric_block::const_iterator itEnd = sc::numeric_block::end(*itBlk->data);
rCxt.maNumArrays.push_back(new sc::FormulaGroupContext::NumArrayType(it, itEnd));
sc::FormulaGroupContext::NumArrayType& rArray = rCxt.maNumArrays.back();
- rArray.resize(nLenRequested, fNan); // allocate to the requested length.
+ rArray.resize(nRow2+1, fNan); // allocate to the requested length.
+
+ pColArray = rCxt.setCachedColArray(nTab, nCol, &rArray, NULL);
+ if (!pColArray)
+ // Failed to insert a new cached column array.
+ return formula::VectorRefArray();
// Fill the remaining array with values from the following blocks.
- ++aPos.first;
- return appendToNumBlock(pDocument, rCxt, nLen, nLenRequested, aPos.first, maCells.end());
+ size_t nPos = itBlk->size;
+ ++itBlk;
+ if (!appendToNumBlock(pDocument, rCxt, *pColArray, nPos, nRow2+1, itBlk, maCells.end()))
+ {
+ return formula::VectorRefArray();
+ }
+
+ if (pColArray->mpStrArray)
+ return formula::VectorRefArray(&(*pColArray->mpNumArray)[nRow1], &(*pColArray->mpStrArray)[nRow1]);
+ else
+ return formula::VectorRefArray(&(*pColArray->mpNumArray)[nRow1]);
}
break;
- case sc::element_type_formula:
+ case sc::element_type_string:
+ case sc::element_type_edittext:
{
- sal_uInt16 nErr;
- double fVal;
-
- rCxt.maNumArrays.push_back(new sc::FormulaGroupContext::NumArrayType);
- sc::FormulaGroupContext::NumArrayType& rArray = rCxt.maNumArrays.back();
- rArray.reserve(nLenRequested);
+ rCxt.maStrArrays.push_back(new sc::FormulaGroupContext::StrArrayType(nRow2+1, NULL));
+ sc::FormulaGroupContext::StrArrayType& rArray = rCxt.maStrArrays.back();
+ pColArray = rCxt.setCachedColArray(nTab, nCol, NULL, &rArray);
+ if (!pColArray)
+ // Failed to insert a new cached column array.
+ return formula::VectorRefArray();
- sc::formula_block::const_iterator it = sc::formula_block::begin(*aPos.first->data);
- std::advance(it, aPos.second);
- sc::formula_block::const_iterator itEnd;
- if (nLenRequested <= nLen)
+ if (static_cast<size_t>(nRow2) < itBlk->size)
{
- // Requested length is within a single block.
- itEnd = it;
- std::advance(itEnd, nLenRequested);
- for (; it != itEnd; ++it)
- {
- ScFormulaCell& rCell = **it;
- if (!rCell.GetErrorOrValue(nErr, fVal) || nErr)
- {
- if (nErr == ScErrorCodes::errCircularReference)
- {
- // This cell needs to be recalculated on next visit.
- rCell.SetErrCode(0);
- rCell.SetDirtyVar();
- }
- return formula::VectorRefArray();
- }
-
- rArray.push_back(fVal);
- }
-
+ // Requested range falls within the first block.
+ copyFirstStringBlock(*pDocument, rArray, nRow2+1, itBlk);
return formula::VectorRefArray(&rArray[0]);
}
- // Requested length goes beyond a single block. Fill the array
- // with the content of this formula block first.
- itEnd = sc::formula_block::end(*aPos.first->data);
- for (; it != itEnd; ++it)
- {
- ScFormulaCell& rCell = **it;
- if (!rCell.GetErrorOrValue(nErr, fVal) || nErr)
- {
- if (nErr == ScErrorCodes::errCircularReference)
- {
- // This cell needs to be recalculated on next visit.
- rCell.SetErrCode(0);
- rCell.SetDirtyVar();
- }
- return formula::VectorRefArray();
- }
-
- rArray.push_back(fVal);
- }
+ copyFirstStringBlock(*pDocument, rArray, itBlk->size, itBlk);
// Fill the remaining array with values from the following blocks.
- ++aPos.first;
- if (!appendDouble(rArray, nLenRequested - nLen, aPos.first, maCells.end()))
+ size_t nPos = itBlk->size;
+ ++itBlk;
+ if (!appendToStringBlock(pDocument, rCxt, *pColArray, nPos, nRow2+1, itBlk, maCells.end()))
return formula::VectorRefArray();
- return formula::VectorRefArray(&rArray[0]);
+ if (pColArray->mpNumArray)
+ return formula::VectorRefArray(&(*pColArray->mpNumArray)[nRow1], &(*pColArray->mpStrArray)[nRow1]);
+ else
+ return formula::VectorRefArray(&(*pColArray->mpStrArray)[nRow1]);
}
break;
- case sc::element_type_string:
- case sc::element_type_edittext:
+ case sc::element_type_formula:
{
- if (nLenRequested <= nLen)
+ if (static_cast<size_t>(nRow2) < itBlk->size)
{
- // Requested length fits a single block.
- copyFirstStringBlock(*pDocument, rCxt, nLenRequested, aPos);
- sc::FormulaGroupContext::StrArrayType& rArray = rCxt.maStrArrays.back();
- return formula::VectorRefArray(&rArray[0]);
+ // Requested length is within a single block, and the data is
+ // not cached.
+ pColArray = copyFirstFormulaBlock(rCxt, itBlk, nRow2+1, nTab, nCol);
+ if (!pColArray)
+ // Failed to insert a new cached column array.
+ return formula::VectorRefArray();
+
+ const double* pNum = NULL;
+ rtl_uString** pStr = NULL;
+ if (pColArray->mpNumArray)
+ pNum = &(*pColArray->mpNumArray)[0];
+ if (pColArray->mpStrArray)
+ pStr = &(*pColArray->mpStrArray)[0];
+
+ return formula::VectorRefArray(pNum, pStr);
}
- copyFirstStringBlock(*pDocument, rCxt, nLen, aPos);
- rCxt.maStrArrays.back().resize(nLenRequested, NULL); // allocate array to requested length.
+ pColArray = copyFirstFormulaBlock(rCxt, itBlk, nRow2+1, nTab, nCol);
+ if (!pColArray)
+ // Failed to insert a new cached column array.
+ return formula::VectorRefArray();
- // Fill the remaining array with values from the following blocks.
- ++aPos.first;
- return appendToStringBlock(pDocument, rCxt, nLen, nLenRequested, aPos.first, maCells.end());
+ size_t nPos = itBlk->size;
+ ++itBlk;
+ if (pColArray->mpNumArray)
+ {
+ if (!appendToNumBlock(pDocument, rCxt, *pColArray, nPos, nRow2+1, itBlk, maCells.end()))
+ return formula::VectorRefArray();
+ }
+ else
+ {
+ if (!appendToStringBlock(pDocument, rCxt, *pColArray, nPos, nRow2+1, itBlk, maCells.end()))
+ return formula::VectorRefArray();
+ }
+
+ const double* pNum = NULL;
+ rtl_uString** pStr = NULL;
+ if (pColArray->mpNumArray)
+ pNum = &(*pColArray->mpNumArray)[0];
+ if (pColArray->mpStrArray)
+ pStr = &(*pColArray->mpStrArray)[0];
+
+ return formula::VectorRefArray(pNum, pStr);
}
break;
case sc::element_type_empty:
{
- if (nLenRequested <= nLen)
- {
- // Fill the whole length with NaN's.
- rCxt.maNumArrays.push_back(new sc::FormulaGroupContext::NumArrayType(nLenRequested, fNan));
- return formula::VectorRefArray(&rCxt.maNumArrays.back()[0]);
- }
-
- // Fill the array with zero for the length of the empty block.
- rCxt.maNumArrays.push_back(new sc::FormulaGroupContext::NumArrayType(nLen, 0.0));
+ // Fill the whole length with NaN's.
+ rCxt.maNumArrays.push_back(new sc::FormulaGroupContext::NumArrayType(nRow2+1, fNan));
sc::FormulaGroupContext::NumArrayType& rArray = rCxt.maNumArrays.back();
- rArray.reserve(nLenRequested);
+ pColArray = rCxt.setCachedColArray(nTab, nCol, &rArray, NULL);
+ if (!pColArray)
+ // Failed to insert a new cached column array.
+ return formula::VectorRefArray();
+
+ if (static_cast<size_t>(nRow2) < itBlk->size)
+ return formula::VectorRefArray(&(*pColArray->mpNumArray)[0]);
// Fill the remaining array with values from the following blocks.
- ++aPos.first;
- if (!appendDouble(rArray, nLenRequested - nLen, aPos.first, maCells.end()))
+ size_t nPos = itBlk->size;
+ ++itBlk;
+ if (!appendToNumBlock(pDocument, rCxt, *pColArray, nPos, nRow2+1, itBlk, maCells.end()))
return formula::VectorRefArray();
- return formula::VectorRefArray(&rArray[0]);
+ if (pColArray->mpStrArray)
+ return formula::VectorRefArray(&(*pColArray->mpNumArray)[nRow1], &(*pColArray->mpStrArray)[nRow1]);
+ else
+ return formula::VectorRefArray(&(*pColArray->mpNumArray)[nRow1]);
}
+ break;
default:
;
}
diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx
index 7f1bd74..9482b1f 100644
--- a/sc/source/core/tool/formulagroup.cxx
+++ b/sc/source/core/tool/formulagroup.cxx
@@ -39,6 +39,70 @@ extern "C" void compileOpenCLKernels(const OUString*);
namespace sc {
+size_t FormulaGroupContext::ColKey::Hash::operator ()( const FormulaGroupContext::ColKey& rKey ) const
+{
+ return rKey.mnTab * MAXCOLCOUNT + rKey.mnCol;
+}
+
+FormulaGroupContext::ColKey::ColKey( SCTAB nTab, SCCOL nCol ) : mnTab(nTab), mnCol(nCol) {}
+
+bool FormulaGroupContext::ColKey::operator== ( const ColKey& r ) const
+{
+ return mnTab == r.mnTab && mnCol == r.mnCol;
+}
+
+bool FormulaGroupContext::ColKey::operator!= ( const ColKey& r ) const
+{
+ return !operator==(r);
+}
+
+FormulaGroupContext::ColArray::ColArray( NumArrayType* pNumArray, StrArrayType* pStrArray ) :
+ mpNumArray(pNumArray), mpStrArray(pStrArray), mnSize(0)
+{
+ if (mpNumArray)
+ mnSize = mpNumArray->size();
+ else if (mpStrArray)
+ mnSize = mpStrArray->size();
+}
+
+FormulaGroupContext::ColArray* FormulaGroupContext::getCachedColArray( SCTAB nTab, SCCOL nCol, size_t nSize )
+{
+ ColArraysType::iterator itColArray = maColArrays.find(ColKey(nTab, nCol));
+ if (itColArray == maColArrays.end())
+ // Not cached for this column.
+ return NULL;
+
+ ColArray& rCached = itColArray->second;
+ if (nSize > rCached.mnSize)
+ // Cached data array is not long enough for the requested range.
+ return NULL;
+
+ return &rCached;
+}
+
+FormulaGroupContext::ColArray* FormulaGroupContext::setCachedColArray(
+ SCTAB nTab, SCCOL nCol, NumArrayType* pNumArray, StrArrayType* pStrArray )
+{
+ ColArraysType::iterator it = maColArrays.find(ColKey(nTab, nCol));
+ if (it == maColArrays.end())
+ {
+ std::pair<ColArraysType::iterator,bool> r =
+ maColArrays.insert(
+ ColArraysType::value_type(ColKey(nTab, nCol), ColArray(pNumArray, pStrArray)));
+
+ if (!r.second)
+ // Somehow the insertion failed.
+ return NULL;
+
+ return &r.first->second;
+ }
+
+ // Prior array exists for this column. Overwrite it.
+ ColArray& rArray = it->second;
+ rArray = ColArray(pNumArray, pStrArray);
+ return &rArray;
+}
+
namespace {
/**
More information about the Libreoffice-commits
mailing list