include/svl/undo.hxx | 4 +++- svl/source/undo/undo.cxx | 8 +++++--- sw/source/core/undo/docundo.cxx | 3 ++- 3 files changed, 10 insertions(+), 5 deletions(-)
New commits: commit a368b4321a8f1584939cbc1f2bc2c4ac83ddb97d Author: Noel Grandin <noelgran...@gmail.com> AuthorDate: Mon Mar 10 21:22:22 2025 +0200 Commit: Noel Grandin <noelgran...@gmail.com> CommitDate: Tue Mar 11 08:16:39 2025 +0100 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.gran...@collabora.co.uk> Tested-by: Jenkins diff --git a/include/svl/undo.hxx b/include/svl/undo.hxx index 2ca0f3b0f8a4..fc4485bde602 100644 --- a/include/svl/undo.hxx +++ b/include/svl/undo.hxx @@ -302,8 +302,10 @@ public: bool HasTopUndoActionMark( UndoStackMark const i_mark ); /** 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; diff --git a/svl/source/undo/undo.cxx b/svl/source/undo/undo.cxx index cb278cf153c3..70f9411c28bf 100644 --- a/svl/source/undo/undo.cxx +++ b/svl/source/undo/undo.cxx @@ -1173,19 +1173,21 @@ void SfxUndoManager::UndoMark(UndoStackMark i_mark) } -void SfxUndoManager::RemoveOldestUndoAction() +bool SfxUndoManager::RemoveOldestUndoAction() { UndoManagerGuard aGuard( *m_xData ); if ( IsInListAction() && ( m_xData->maUndoArray.nCurUndoAction == 1 ) ) { - assert(!"SfxUndoManager::RemoveOldestUndoActions: cannot remove a not-yet-closed list action!"); - return; + // this can happen if we are performing a very large writer edit (e.g. removing a very large table) + SAL_WARN("svl", "SfxUndoManager::RemoveOldestUndoActions: cannot remove a not-yet-closed list action!"); + return false; } aGuard.markForDeletion( m_xData->maUndoArray.Remove( 0 ) ); --m_xData->maUndoArray.nCurUndoAction; ImplCheckEmptyActions(); + return true; } void SfxUndoManager::dumpAsXml(xmlTextWriterPtr pWriter) const diff --git a/sw/source/core/undo/docundo.cxx b/sw/source/core/undo/docundo.cxx index 576b0579e1e8..786bd3762815 100644 --- a/sw/source/core/undo/docundo.cxx +++ b/sw/source/core/undo/docundo.cxx @@ -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 while (UNDO_ACTION_LIMIT < sal_Int32(GetUndoNodes().Count())) { - RemoveOldestUndoAction(); + if (!RemoveOldestUndoAction()) + break; } }