summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2013-04-24 21:43:06 -0400
committerKohei Yoshida <kohei.yoshida@gmail.com>2013-04-30 13:10:39 -0400
commit1b99bc2028a0160eadd688878f5ec2cca87543cc (patch)
treecf8db38ed84b6255694f62ebb7e762754511c64f /sc
parentc77cb290c3bb8ce3b5296f750cb3d1eacc21d28c (diff)
We really don't need to use similar data unless I missed something.
Change-Id: Iaab6033120c3d50a54fb151916dc2a7b7ba5a98c
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/formulacell.hxx11
-rw-r--r--sc/source/core/data/column3.cxx31
-rw-r--r--sc/source/core/data/formulacell.cxx150
3 files changed, 71 insertions, 121 deletions
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index 469495a91f11..3e6814439e67 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -34,14 +34,12 @@ struct ScSimilarFormulaDelta;
struct SC_DLLPUBLIC ScFormulaCellGroup
{
sal_Int32 mnRefCount;
- ScSimilarFormulaDelta *mpDelta; // difference between items in column
sal_Int32 mnStart; // Start offset of that cell
sal_Int32 mnLength; // How many of these do we have ?
+ bool mbInvariant;
ScFormulaCellGroup();
~ScFormulaCellGroup();
-
- bool IsCompatible( ScSimilarFormulaDelta *pDelta );
};
inline void intrusive_ptr_add_ref(ScFormulaCellGroup *p)
{
@@ -100,6 +98,8 @@ private:
public:
+ enum CompareState { NotEqual = 0, EqualInvariant, EqualRelativeRef };
+
#ifdef USE_MEMPOOL
DECL_FIXEDMEMPOOL_NEWDEL( ScFormulaCell )
#endif
@@ -297,8 +297,9 @@ public:
{ return xGroup; }
void SetCellGroup( const ScFormulaCellGroupRef &xRef )
{ xGroup = xRef; }
- ScSimilarFormulaDelta *BuildDeltaTo( ScFormulaCell *pOther );
- void ReleaseDelta( ScSimilarFormulaDelta *pDelta );
+
+ CompareState CompareByTokenArray( ScFormulaCell *pOther ) const;
+
bool InterpretFormulaGroup();
// nOnlyNames may be one or more of SC_LISTENING_NAMES_*
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 3eb4b178b4b3..615fbaf8c30e 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2118,15 +2118,14 @@ void ScColumn::RebuildFormulaGroups()
if ( rCur.pCell->GetCellType() != CELLTYPE_FORMULA )
continue;
- // see if these formulae are similar
+ // see if these formula tokens are identical.
ScFormulaCell *pCur = static_cast< ScFormulaCell *>( rCur.pCell );
ScFormulaCell *pPrev = static_cast< ScFormulaCell *>( rPrev.pCell );
- ScSimilarFormulaDelta *pDelta = pPrev->BuildDeltaTo( pCur );
-
- if ( !pDelta )
+ ScFormulaCell::CompareState eCompState = pPrev->CompareByTokenArray(pCur);
+ if (eCompState == ScFormulaCell::NotEqual)
{
- // not similar
+ // different formula tokens.
pCur->SetCellGroup( xNone );
continue;
}
@@ -2136,8 +2135,8 @@ void ScColumn::RebuildFormulaGroups()
{
// create a new group ...
xGroup.reset(new ScFormulaCellGroup);
- xGroup->mpDelta = pDelta;
xGroup->mnStart = rPrev.nRow;
+ xGroup->mbInvariant = eCompState == ScFormulaCell::EqualInvariant;
xGroup->mnLength = 2;
maFnGroups.push_back( xGroup );
@@ -2145,27 +2144,11 @@ void ScColumn::RebuildFormulaGroups()
pCur->SetCellGroup( xGroup );
pPrev->SetCellGroup( xGroup );
}
- else if ( xGroup->IsCompatible( pDelta ) )
+ else
{
- // we are a compatible extension - extend the group
+ // existing group. extend its length.
pCur->SetCellGroup( xGroup );
xGroup->mnLength++;
- pCur->ReleaseDelta( pDelta );
- }
- else
- {
-#if OSL_DEBUG_LEVEL > 1
- OUString aFormula;
- pCur->GetFormula( aFormula );
- ScAddress aAddr( nCol, rCur.nRow, nTab );
- OUString aCellAddr;
- aAddr.Format( aCellAddr, 0, pDocument );
-
- fprintf( stderr, "unusual incompatible extension in cell '%s' of formulae '%s'\n" ,
- OUStringToOString( aCellAddr, RTL_TEXTENCODING_UTF8 ).getStr(),
- OUStringToOString( aFormula, RTL_TEXTENCODING_UTF8 ).getStr() );
-#endif
- pCur->ReleaseDelta( pDelta );
}
}
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index ab703442fc2c..fe956f5e4c93 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -376,7 +376,7 @@ void adjustDBRange(ScToken* pToken, ScDocument& rNewDoc, const ScDocument* pOldD
}
ScFormulaCellGroup::ScFormulaCellGroup() :
- mnRefCount(0), mpDelta(NULL), mnStart(0), mnLength(0)
+ mnRefCount(0), mnStart(0), mnLength(0), mbInvariant(false)
{
}
@@ -2857,123 +2857,89 @@ void ScFormulaCell::CompileColRowNameFormula()
}
}
-// we really want to be a lot more descriptive than this
-struct ScSimilarFormulaDelta : std::vector< size_t >
-{
- bool IsCompatible( ScSimilarFormulaDelta *pDelta )
- {
- if ( size() != pDelta->size() )
- return false;
- for ( size_t i = 0; i < size(); i++ )
- {
- if ( (*this)[ i ] != (*pDelta)[ i ] )
- return false;
- }
- return true;
- }
-
- void push_delta( const ScSingleRefData& a, const ScSingleRefData& b )
- {
- push_back( b.nCol - a.nCol );
- push_back( b.nRow - a.nRow );
- push_back( b.nTab - a.nTab );
- }
-
- /// if the vector is zero then nothing changes down the column.
- bool IsInvariant() const
- {
- for ( size_t i = 0; i < size(); i++ )
- {
- if ( (*this)[ i ] != 0 )
- return false;
- }
- return true;
- }
-};
-
-bool ScFormulaCellGroup::IsCompatible( ScSimilarFormulaDelta *pDelta )
-{
- return pDelta && mpDelta && mpDelta->IsCompatible( pDelta );
-}
-
-/// compare formulae tokens and build a series of deltas describing
-/// the difference - ie. the result, when added to this
-/// formulae should produce pOther
-ScSimilarFormulaDelta *ScFormulaCell::BuildDeltaTo( ScFormulaCell *pOtherCell )
+ScFormulaCell::CompareState ScFormulaCell::CompareByTokenArray( ScFormulaCell *pOtherCell ) const
{
// no Matrix formulae yet.
if ( GetMatrixFlag() != MM_NONE )
- return NULL;
+ return NotEqual;
// are these formule at all similar ?
if ( GetHash() != pOtherCell->GetHash() )
- return NULL;
+ return NotEqual;
FormulaToken **pThis = pCode->GetCode();
- sal_uInt16 pThisLen = pCode->GetCodeLen();
+ sal_uInt16 nThisLen = pCode->GetCodeLen();
FormulaToken **pOther = pOtherCell->pCode->GetCode();
- sal_uInt16 pOtherLen = pOtherCell->pCode->GetCodeLen();
+ sal_uInt16 nOtherLen = pOtherCell->pCode->GetCodeLen();
if ( !pThis || !pOther )
{
-// fprintf( stderr, "Error: no compiled code for cells !" );
- return NULL;
+ // Error: no compiled code for cells !"
+ return NotEqual;
}
- if ( pThisLen != pOtherLen )
- return NULL;
+ if ( nThisLen != nOtherLen )
+ return NotEqual;
+
+ bool bInvariant = true;
// check we are basically the same function
- for ( sal_uInt16 i = 0; i < pThisLen; i++ )
+ for ( sal_uInt16 i = 0; i < nThisLen; i++ )
{
- if ( pThis[ i ]->GetType() != pOther[ i ]->GetType() ||
- pThis[ i ]->GetOpCode() != pOther[ i ]->GetOpCode() ||
- pThis[ i ]->GetParamCount() != pOther[ i ]->GetParamCount() )
+ ScToken *pThisTok = static_cast<ScToken*>( pThis[i] );
+ ScToken *pOtherTok = static_cast<ScToken*>( pOther[i] );
+
+ if ( pThisTok->GetType() != pOtherTok->GetType() ||
+ pThisTok->GetOpCode() != pOtherTok->GetOpCode() ||
+ pThisTok->GetParamCount() != pOtherTok->GetParamCount() )
{
-// fprintf( stderr, "Incompatible type, op-code or param counts\n" );
- return NULL;
+ // Incompatible type, op-code or param counts.
+ return NotEqual;
}
- switch( pThis[ i ]->GetType() )
+
+ switch (pThisTok->GetType())
{
- case formula::svMatrix:
- case formula::svExternalSingleRef:
- case formula::svExternalDoubleRef:
-// fprintf( stderr, "Ignoring matrix and external references for now\n" );
- return NULL;
- default:
+ case formula::svMatrix:
+ case formula::svExternalSingleRef:
+ case formula::svExternalDoubleRef:
+ // Ignoring matrix and external references for now.
+ return NotEqual;
+
+ case formula::svSingleRef:
+ {
+ // Single cell reference.
+ const ScSingleRefData& rRef = pThisTok->GetSingleRef();
+ if (rRef != pOtherTok->GetSingleRef())
+ return NotEqual;
+
+ if (rRef.IsColRel() || rRef.IsRowRel())
+ bInvariant = false;
+ }
break;
- }
- }
+ case formula::svDoubleRef:
+ {
+ // Range reference.
+ const ScSingleRefData& rRef1 = pThisTok->GetSingleRef();
+ const ScSingleRefData& rRef2 = pThisTok->GetSingleRef2();
+ if (rRef1 != pOtherTok->GetSingleRef())
+ return NotEqual;
- ScSimilarFormulaDelta *pDelta = new ScSimilarFormulaDelta();
+ if (rRef2 != pOtherTok->GetSingleRef2())
+ return NotEqual;
- for ( sal_uInt16 i = 0; i < pThisLen; i++ )
- {
- ScToken *pThisTok = static_cast< ScToken * >( pThis[ i ] );
- ScToken *pOtherTok = static_cast< ScToken * >( pOther[ i ] );
+ if (rRef1.IsColRel() || rRef1.IsRowRel())
+ bInvariant = false;
- if ( pThis[i]->GetType() == formula::svSingleRef ||
- pThis[i]->GetType() == formula::svDoubleRef )
- {
- const ScSingleRefData& aThisRef = pThisTok->GetSingleRef();
- const ScSingleRefData& aOtherRef = pOtherTok->GetSingleRef();
- pDelta->push_delta( aThisRef, aOtherRef );
- }
- if ( pThis[i]->GetType() == formula::svDoubleRef )
- {
- const ScSingleRefData& aThisRef2 = pThisTok->GetSingleRef2();
- const ScSingleRefData& aOtherRef2 = pOtherTok->GetSingleRef2();
- pDelta->push_delta( aThisRef2, aOtherRef2 );
+ if (rRef2.IsColRel() || rRef2.IsRowRel())
+ bInvariant = false;
+ }
+ break;
+ default:
+ ;
}
}
- return pDelta;
-}
-
-/// To avoid exposing impl. details of ScSimilarFormulaDelta publicly
-void ScFormulaCell::ReleaseDelta( ScSimilarFormulaDelta *pDelta )
-{
- delete pDelta;
+ return bInvariant ? EqualInvariant : EqualRelativeRef;
}
bool ScFormulaCell::InterpretFormulaGroup()
@@ -2987,7 +2953,7 @@ bool ScFormulaCell::InterpretFormulaGroup()
// fprintf( stderr, "Interpret cell %d, %d\n", (int)aPos.Col(), (int)aPos.Row() );
- if ( xGroup->mpDelta->IsInvariant() )
+ if (xGroup->mbInvariant)
{
// fprintf( stderr, "struck gold - completely invariant for %d items !\n",
// (int)xGroup->mnLength );