Kaydet (Commit) c27b2fb8 authored tarafından Michael Meeks's avatar Michael Meeks Kaydeden (comit) Kohei Yoshida

start of InterpretFormulaGroup.

handle column invariant formulae, sketch comment more work,
elide Matrix formulae.

Change-Id: I9ce4da26b0ad2407021a10f21c81ada80442c76d
üst 244033d7
...@@ -598,6 +598,7 @@ public: ...@@ -598,6 +598,7 @@ public:
{ xGroup = xRef; } { xGroup = xRef; }
ScSimilarFormulaDelta *BuildDeltaTo( ScFormulaCell *pOther ); ScSimilarFormulaDelta *BuildDeltaTo( ScFormulaCell *pOther );
void ReleaseDelta( ScSimilarFormulaDelta *pDelta ); void ReleaseDelta( ScSimilarFormulaDelta *pDelta );
bool InterpretFormulaGroup();
}; };
// Iterator for references in a formula cell // Iterator for references in a formula cell
......
...@@ -1198,11 +1198,6 @@ void ScFormulaCell::Interpret() ...@@ -1198,11 +1198,6 @@ void ScFormulaCell::Interpret()
if (!IsDirtyOrInTableOpDirty() || pDocument->GetRecursionHelper().IsInReturn()) if (!IsDirtyOrInTableOpDirty() || pDocument->GetRecursionHelper().IsInReturn())
return; // no double/triple processing 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: //! HACK:
// If the call originates from a Reschedule in DdeLink update, leave dirty // 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! // Better: Do a Dde Link Update without Reschedule or do it completely asynchronously!
...@@ -1243,7 +1238,8 @@ void ScFormulaCell::Interpret() ...@@ -1243,7 +1238,8 @@ void ScFormulaCell::Interpret()
} }
else else
{ {
InterpretTail( SCITP_NORMAL); if ( ! InterpretFormulaGroup() )
InterpretTail( SCITP_NORMAL);
} }
// While leaving a recursion or iteration stack, insert its cells to the // While leaving a recursion or iteration stack, insert its cells to the
......
...@@ -1689,9 +1689,9 @@ void ScFormulaCell::CompileColRowNameFormula() ...@@ -1689,9 +1689,9 @@ void ScFormulaCell::CompileColRowNameFormula()
} }
} }
// we really want to be a lot more descriptive than this
struct ScSimilarFormulaDelta : std::vector< size_t > struct ScSimilarFormulaDelta : std::vector< size_t >
{ {
// we really want to be a lot more descriptive than this
bool IsCompatible( ScSimilarFormulaDelta *pDelta ) bool IsCompatible( ScSimilarFormulaDelta *pDelta )
{ {
if ( size() != pDelta->size() ) if ( size() != pDelta->size() )
...@@ -1710,6 +1710,17 @@ struct ScSimilarFormulaDelta : std::vector< size_t > ...@@ -1710,6 +1710,17 @@ struct ScSimilarFormulaDelta : std::vector< size_t >
push_back( b.nRow - a.nRow ); push_back( b.nRow - a.nRow );
push_back( b.nTab - a.nTab ); 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 ) bool ScFormulaCellGroup::IsCompatible( ScSimilarFormulaDelta *pDelta )
...@@ -1722,6 +1733,10 @@ bool ScFormulaCellGroup::IsCompatible( ScSimilarFormulaDelta *pDelta ) ...@@ -1722,6 +1733,10 @@ bool ScFormulaCellGroup::IsCompatible( ScSimilarFormulaDelta *pDelta )
/// formulae should produce pOther /// formulae should produce pOther
ScSimilarFormulaDelta *ScFormulaCell::BuildDeltaTo( ScFormulaCell *pOtherCell ) ScSimilarFormulaDelta *ScFormulaCell::BuildDeltaTo( ScFormulaCell *pOtherCell )
{ {
// no Matrix formulae yet.
if ( GetMatrixFlag() != MM_NONE )
return NULL;
// are these formule at all similar ? // are these formule at all similar ?
if ( GetHash() != pOtherCell->GetHash() ) if ( GetHash() != pOtherCell->GetHash() )
return NULL; return NULL;
...@@ -1787,11 +1802,84 @@ ScSimilarFormulaDelta *ScFormulaCell::BuildDeltaTo( ScFormulaCell *pOtherCell ) ...@@ -1787,11 +1802,84 @@ ScSimilarFormulaDelta *ScFormulaCell::BuildDeltaTo( ScFormulaCell *pOtherCell )
return pDelta; return pDelta;
} }
/// To avoid exposing impl. details of ScSimilarFormulaDelta publicly
void ScFormulaCell::ReleaseDelta( ScSimilarFormulaDelta *pDelta ) void ScFormulaCell::ReleaseDelta( ScSimilarFormulaDelta *pDelta )
{ {
delete 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: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment