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:
Noel Grandin
2025-03-10 21:22:22 +02:00
parent dcfc32914f
commit a368b4321a
3 changed files with 10 additions and 5 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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;
} }
} }