diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-04-24 21:43:06 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-04-30 13:10:39 -0400 |
commit | 1b99bc2028a0160eadd688878f5ec2cca87543cc (patch) | |
tree | cf8db38ed84b6255694f62ebb7e762754511c64f /sc | |
parent | c77cb290c3bb8ce3b5296f750cb3d1eacc21d28c (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.hxx | 11 | ||||
-rw-r--r-- | sc/source/core/data/column3.cxx | 31 | ||||
-rw-r--r-- | sc/source/core/data/formulacell.cxx | 150 |
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 ); |