tdf#136238 Speedup deleting a very very large cross page table
We have a very large nested/list action here, which means that RemoveOldestUndoAction() cannot do anything, and we spin in the loop in sw::UndoManager::AddUndoAction So we need to break out of that loop in this situation, which makes the delete almost instantaneous. Change-Id: Ia2bd9c0fd00c6551e99ae09154ecf0f680b9fcea Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182748 Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk> Tested-by: Jenkins
This commit is contained in:
@@ -302,8 +302,10 @@ public:
|
|||||||
bool HasTopUndoActionMark( UndoStackMark const i_mark );
|
bool HasTopUndoActionMark( UndoStackMark const i_mark );
|
||||||
|
|
||||||
/** removes the oldest Undo actions from the stack
|
/** removes the oldest Undo actions from the stack
|
||||||
|
* @returns false if it could not do anything (can happen when the action is very large)
|
||||||
*/
|
*/
|
||||||
void RemoveOldestUndoAction();
|
[[nodiscard]]
|
||||||
|
bool RemoveOldestUndoAction();
|
||||||
|
|
||||||
void dumpAsXml(xmlTextWriterPtr pWriter) const;
|
void dumpAsXml(xmlTextWriterPtr pWriter) const;
|
||||||
|
|
||||||
|
@@ -1173,19 +1173,21 @@ void SfxUndoManager::UndoMark(UndoStackMark i_mark)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SfxUndoManager::RemoveOldestUndoAction()
|
bool SfxUndoManager::RemoveOldestUndoAction()
|
||||||
{
|
{
|
||||||
UndoManagerGuard aGuard( *m_xData );
|
UndoManagerGuard aGuard( *m_xData );
|
||||||
|
|
||||||
if ( IsInListAction() && ( m_xData->maUndoArray.nCurUndoAction == 1 ) )
|
if ( IsInListAction() && ( m_xData->maUndoArray.nCurUndoAction == 1 ) )
|
||||||
{
|
{
|
||||||
assert(!"SfxUndoManager::RemoveOldestUndoActions: cannot remove a not-yet-closed list action!");
|
// this can happen if we are performing a very large writer edit (e.g. removing a very large table)
|
||||||
return;
|
SAL_WARN("svl", "SfxUndoManager::RemoveOldestUndoActions: cannot remove a not-yet-closed list action!");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
aGuard.markForDeletion( m_xData->maUndoArray.Remove( 0 ) );
|
aGuard.markForDeletion( m_xData->maUndoArray.Remove( 0 ) );
|
||||||
--m_xData->maUndoArray.nCurUndoAction;
|
--m_xData->maUndoArray.nCurUndoAction;
|
||||||
ImplCheckEmptyActions();
|
ImplCheckEmptyActions();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SfxUndoManager::dumpAsXml(xmlTextWriterPtr pWriter) const
|
void SfxUndoManager::dumpAsXml(xmlTextWriterPtr pWriter) const
|
||||||
|
@@ -629,7 +629,8 @@ void UndoManager::AddUndoAction(std::unique_ptr<SfxUndoAction> pAction, bool bTr
|
|||||||
// if the undo nodes array is too large, delete some actions
|
// if the undo nodes array is too large, delete some actions
|
||||||
while (UNDO_ACTION_LIMIT < sal_Int32(GetUndoNodes().Count()))
|
while (UNDO_ACTION_LIMIT < sal_Int32(GetUndoNodes().Count()))
|
||||||
{
|
{
|
||||||
RemoveOldestUndoAction();
|
if (!RemoveOldestUndoAction())
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user