Kaydet (Commit) d21cbd97 authored tarafından Kohei Yoshida's avatar Kohei Yoshida

Optimize area broadcast iteration ...

for cases where no areas are marked for removal, which I believe is mor
common use case than others.

Change-Id: I3f53fb5e6ab4a9172e358bec0c71289d1e92ac19
üst cc35f070
......@@ -108,7 +108,8 @@ ScBroadcastAreaSlot::ScBroadcastAreaSlot( ScDocument* pDocument,
aTmpSeekBroadcastArea( ScRange()),
pDoc( pDocument ),
pBASM( pBASMa ),
mbInBroadcastIteration( false)
mbInBroadcastIteration( false),
mbHasErasedArea(false)
{
}
......@@ -247,15 +248,20 @@ bool ScBroadcastAreaSlot::AreaBroadcast( const ScHint& rHint)
{
if (aBroadcastAreaTbl.empty())
return false;
bool bInBroadcast = mbInBroadcastIteration;
mbInBroadcastIteration = true;
bool bIsBroadcasted = false;
mbHasErasedArea = false;
const ScAddress& rAddress = rHint.GetAddress();
for (ScBroadcastAreas::const_iterator aIter( aBroadcastAreaTbl.begin()),
aIterEnd( aBroadcastAreaTbl.end()); aIter != aIterEnd; ++aIter )
{
if (isMarkedErased( aIter))
if (mbHasErasedArea && isMarkedErased( aIter))
continue;
ScBroadcastArea* pArea = (*aIter).mpArea;
const ScRange& rAreaRange = pArea->GetRange();
if (rAreaRange.In( rAddress))
......@@ -267,11 +273,14 @@ bool ScBroadcastAreaSlot::AreaBroadcast( const ScHint& rHint)
}
}
}
mbInBroadcastIteration = bInBroadcast;
// A Notify() during broadcast may call EndListeningArea() and thus dispose
// an area if it was the last listener, which would invalidate an iterator
// pointing to it, hence the real erase is done afterwards.
FinallyEraseAreas();
return bIsBroadcasted;
}
......@@ -418,6 +427,7 @@ void ScBroadcastAreaSlot::EraseArea( ScBroadcastAreas::iterator& rIter )
if (mbInBroadcastIteration)
{
(*rIter).mbErasure = true; // mark for erasure
mbHasErasedArea = true; // at least one area is marked for erasure.
pBASM->PushAreaToBeErased( this, rIter);
}
else
......
......@@ -136,6 +136,15 @@ private:
ScBroadcastAreaSlotMachine* pBASM;
bool mbInBroadcastIteration;
/**
* If true, the slot has at least one area broadcaster marked for removal.
* This flag is used only during broadcast iteration, to speed up
* iteration. Using this flag is cheaper than dereferencing each iterator
* and checking its own flag inside especially when no areas are marked
* for removal.
*/
bool mbHasErasedArea;
ScBroadcastAreas::const_iterator FindBroadcastArea( const ScRange& rRange ) const;
/**
......
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