[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - 2 commits - sc/inc sc/source

Michael Meeks michael.meeks at suse.com
Tue Mar 19 09:35:23 PDT 2013


 sc/inc/cell.hxx                 |    1 
 sc/source/core/data/cell.cxx    |    8 ---
 sc/source/core/data/cell2.cxx   |   90 +++++++++++++++++++++++++++++++++++++++-
 sc/source/core/data/column3.cxx |    5 +-
 4 files changed, 95 insertions(+), 9 deletions(-)

New commits:
commit 16244fc05b57d30e9b079b68c75e53ed011ee198
Author: Michael Meeks <michael.meeks at suse.com>
Date:   Tue Mar 19 16:33:17 2013 +0000

    start of InterpretFormulaGroup.
    
    handle column invariant formulae, sketch comment more work,
    elide Matrix formulae.
    
    Change-Id: I9ce4da26b0ad2407021a10f21c81ada80442c76d

diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index a096c37..fa5cf23 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 5dfd8e5..8305127 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 ca21710..0724501 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: */
commit cc6351f4262d9f812dfd74eb0b5f486e06baa7d7
Author: Michael Meeks <michael.meeks at suse.com>
Date:   Tue Mar 19 15:52:07 2013 +0000

    get row offset calculation right for groups.
    
    Change-Id: Id65174bbb70a4387cddb985d0556a3bcd692d671

diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index f702b25..fb6c212 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2028,6 +2028,7 @@ void ScColumn::RebuildFormulaGroups()
         if ( rCur.pCell && rCur.pCell->GetCellType() == CELLTYPE_FORMULA )
             static_cast<ScFormulaCell *>( rCur.pCell )->SetCellGroup( xNone );
     }
+    maFnGroups.clear();
 
     // re-build groups
     ColDoubleEntry *pLastDouble = NULL;
@@ -2049,7 +2050,7 @@ void ScColumn::RebuildFormulaGroups()
             if ( !pLastDouble )
             {
                 pLastDouble = new ColDoubleEntry();
-                pLastDouble->mnStart = i - 1;
+                pLastDouble->mnStart = rPrev.nRow;
                 pLastDouble->maData.push_back(
                         static_cast< ScValueCell * >( rPrev.pCell )->GetValue() );
                 maDoubles.push_back( pLastDouble );
@@ -2081,7 +2082,7 @@ void ScColumn::RebuildFormulaGroups()
             // create a new group ...
             ScFormulaCellGroup *pGroup = new ScFormulaCellGroup();
             pGroup->mpDelta = pDelta;
-            pGroup->mnStart = i - 1;
+            pGroup->mnStart = rPrev.nRow;
             pGroup->mnLength = 2;
 
             xGroup.reset( pGroup );


More information about the Libreoffice-commits mailing list