diff options
author | Michael Meeks <michael.meeks@suse.com> | 2013-03-19 16:33:17 +0000 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-03-19 13:40:26 -0400 |
commit | c27b2fb8433758240c00bcd76c7fa322eccdee9c (patch) | |
tree | 1711af48d502efd091c4ec080dbf57ae5f9ce6fd | |
parent | 244033d7148e0badbf5915e21b7f2d67e41bf4eb (diff) |
start of InterpretFormulaGroup.
handle column invariant formulae, sketch comment more work,
elide Matrix formulae.
Change-Id: I9ce4da26b0ad2407021a10f21c81ada80442c76d
-rw-r--r-- | sc/inc/cell.hxx | 1 | ||||
-rw-r--r-- | sc/source/core/data/cell.cxx | 8 | ||||
-rw-r--r-- | sc/source/core/data/cell2.cxx | 90 |
3 files changed, 92 insertions, 7 deletions
diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx index a096c37674f3..fa5cf235ecb0 100644 --- a/sc/inc/cell.hxx +++ b/sc/inc/cell.hxx @@ -598,6 +598,7 @@ public: { xGroup = xRef; } ScSimilarFormulaDelta *BuildDeltaTo( ScFormulaCell *pOther ); void ReleaseDelta( ScSimilarFormulaDelta *pDelta ); + bool InterpretFormulaGroup(); }; // Iterator for references in a formula cell diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx index 5dfd8e5ff1d7..830512783f28 100644 --- a/sc/source/core/data/cell.cxx +++ b/sc/source/core/data/cell.cxx @@ -1198,11 +1198,6 @@ void ScFormulaCell::Interpret() if (!IsDirtyOrInTableOpDirty() || pDocument->GetRecursionHelper().IsInReturn()) return; // no double/triple processing - // Re-build formulae groups - ideally this is done at import / insert / delete etc. - // and is reflected in the dependency data ... - pDocument->RebuildFormulaGroups(); - - //! HACK: // If the call originates from a Reschedule in DdeLink update, leave dirty // Better: Do a Dde Link Update without Reschedule or do it completely asynchronously! @@ -1243,7 +1238,8 @@ void ScFormulaCell::Interpret() } else { - InterpretTail( SCITP_NORMAL); + if ( ! InterpretFormulaGroup() ) + InterpretTail( SCITP_NORMAL); } // While leaving a recursion or iteration stack, insert its cells to the diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx index ca217102b800..0724501d2b63 100644 --- a/sc/source/core/data/cell2.cxx +++ b/sc/source/core/data/cell2.cxx @@ -1689,9 +1689,9 @@ void ScFormulaCell::CompileColRowNameFormula() } } +// we really want to be a lot more descriptive than this struct ScSimilarFormulaDelta : std::vector< size_t > { - // we really want to be a lot more descriptive than this bool IsCompatible( ScSimilarFormulaDelta *pDelta ) { if ( size() != pDelta->size() ) @@ -1710,6 +1710,17 @@ struct ScSimilarFormulaDelta : std::vector< size_t > 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 ) @@ -1722,6 +1733,10 @@ bool ScFormulaCellGroup::IsCompatible( ScSimilarFormulaDelta *pDelta ) /// formulae should produce pOther ScSimilarFormulaDelta *ScFormulaCell::BuildDeltaTo( ScFormulaCell *pOtherCell ) { + // no Matrix formulae yet. + if ( GetMatrixFlag() != MM_NONE ) + return NULL; + // are these formule at all similar ? if ( GetHash() != pOtherCell->GetHash() ) return NULL; @@ -1787,11 +1802,84 @@ ScSimilarFormulaDelta *ScFormulaCell::BuildDeltaTo( ScFormulaCell *pOtherCell ) return pDelta; } +/// To avoid exposing impl. details of ScSimilarFormulaDelta publicly void ScFormulaCell::ReleaseDelta( ScSimilarFormulaDelta *pDelta ) { delete pDelta; } +bool ScFormulaCell::InterpretFormulaGroup() +{ + // Re-build formulae groups if necessary - ideally this is done at + // import / insert / delete etc. and is integral to the data structures + pDocument->RebuildFormulaGroups(); + + if( !xGroup.get() ) + return false; + + fprintf( stderr, "Interpret cell %d, %d\n", (int)aPos.Col(), (int)aPos.Row() ); + + if ( xGroup->mpDelta->IsInvariant() ) + { + fprintf( stderr, "struck gold - completely invariant for %d items !\n", + (int)xGroup->mnLength ); + + // calculate ourselves: + InterpretTail( SCITP_NORMAL ); + for ( sal_Int32 i = 0; i < xGroup->mnLength; i++ ) + { + ScBaseCell *pBaseCell = NULL; + pDocument->GetCell( aPos.Col(), + xGroup->mnStart + i, + aPos.Tab(), pBaseCell ); + assert( pBaseCell != NULL ); + assert( pBaseCell->GetCellType() == CELLTYPE_FORMULA ); + ScFormulaCell *pCell = static_cast<ScFormulaCell *>( pBaseCell ); + + // FIXME: this set of horrors is unclear to me ... certainly + // the above GetCell is profoundly nasty & slow ... + + // Ensure the cell truly has a result: + pCell->aResult = aResult; + pCell->ResetDirty(); + + // FIXME: there is a view / refresh missing here it appears. + } + return true; + } + else + { + // scan the formula ... + // have a document method: "Get2DRangeAsDoublesArray" that does the + // column-based heavy lifting call it for each absolute range from the + // first cell pos in the formula group. + // + // Project single references to ranges by adding their vector * xGroup->mnLength + // + // TODO: + // elide multiple dimensional movement in vectors eg. =SUM(A1<1,1>) + // produces a diagonal 'column' that serves no useful purpose for us. + // these should be very rare. Should elide in GetDeltas anyway and + // assert here. + // + // Having built our input data ... + // Throw it, and the formula over to some 'OpenCLCalculage' hook + // + // on return - release references on these double buffers + // + // transfer the result to the formula cells (as above) + // store the doubles in the columns' maDoubles array for + // dependent formulae + // + // TODO: + // need to abort/fail when we get errors returned and fallback to + // stock interpreting [ I guess ], unless we can use NaN etc. to + // signal errors. + + return false; + } +} + // ============================================================================ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |