desktop/inc/lib/init.hxx    |    3 
 desktop/source/lib/init.cxx |  213 ++++++++++++++++++++++++--------------------
 2 files changed, 120 insertions(+), 96 deletions(-)

New commits:
commit e9b341e477eba6f4593c5459bf947faf0cd2f2ea
Author:     Luboš Luňák <l.lu...@collabora.com>
AuthorDate: Sat Sep 25 21:26:31 2021 +0200
Commit:     Luboš Luňák <l.lu...@collabora.com>
CommitDate: Tue Sep 28 13:50:20 2021 +0200

    do not check a const variable in every lambda invocation
    
    If the variable is false, then every call to the lambda will be false
    as well, so the entire block may be skipped.
    
    Change-Id: I8b61133d246fcfa721145f9d28c55e9afdb06e5d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122644
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Luboš Luňák <l.lu...@collabora.com>

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 48db6cf4c434..73af13dd8910 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1612,11 +1612,14 @@ void CallbackFlushHandler::queue(const int type, const 
char* data)
                 const bool hyperLinkException = type == 
LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
                     payload.find("\"hyperlink\":\"\"") == std::string::npos &&
                     payload.find("\"hyperlink\": {}") == std::string::npos;
-                const int nViewId = lcl_getViewId(payload);
-                removeAll(type, [nViewId, hyperLinkException] (const 
CallbackData& elemData) {
-                        return (nViewId == lcl_getViewId(elemData) && 
!hyperLinkException);
-                    }
-                );
+                if(!hyperLinkException)
+                {
+                    const int nViewId = lcl_getViewId(payload);
+                    removeAll(type, [nViewId] (const CallbackData& elemData) {
+                            return (nViewId == lcl_getViewId(elemData));
+                        }
+                    );
+                }
             }
             break;
 
commit da16b920745887ce843623b5f3ef7d06dde59f3b
Author:     Luboš Luňák <l.lu...@collabora.com>
AuthorDate: Fri Sep 24 00:19:18 2021 +0200
Commit:     Luboš Luňák <l.lu...@collabora.com>
CommitDate: Tue Sep 28 13:50:05 2021 +0200

    optimize removing from the LOK flush queue
    
    All the lambdas check for event type, so it makes sense to first
    separately check the type and only then possibly call the lambda.
    Especially since 3b3e4ee97af23f21 separated the types for better
    searching.
    
    Change-Id: I144c88f5319ac2141336e1aa3c4ffd7b38265af9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122640
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Luboš Luňák <l.lu...@collabora.com>

diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index ed35ebc2fa13..6cbabd3ccccb 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -127,9 +127,12 @@ namespace desktop {
         typedef std::vector<CallbackData> queue_type2;
 
     private:
+        bool removeAll(int type);
+        bool removeAll(int type, const std::function<bool (const 
CallbackData&)>& rTestFunc);
         bool removeAll(const std::function<bool (int, const CallbackData&)>& 
rTestFunc);
         bool processInvalidateTilesEvent(int type, CallbackData& 
aCallbackData);
         bool processWindowEvent(int type, CallbackData& aCallbackData);
+        queue_type2::iterator toQueue2(queue_type1::iterator);
         queue_type2::reverse_iterator toQueue2(queue_type1::reverse_iterator);
 
         /** we frequently want to scan the queue, and mostly when we do so, we 
only care about the element type
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 0426b53946d3..48db6cf4c434 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1432,6 +1432,12 @@ void CallbackFlushHandler::callback(const int type, 
const char* payload, void* d
     }
 }
 
+CallbackFlushHandler::queue_type2::iterator 
CallbackFlushHandler::toQueue2(CallbackFlushHandler::queue_type1::iterator pos)
+{
+    int delta = std::distance(m_queue1.begin(), pos);
+    return m_queue2.begin() + delta;
+}
+
 CallbackFlushHandler::queue_type2::reverse_iterator 
CallbackFlushHandler::toQueue2(CallbackFlushHandler::queue_type1::reverse_iterator
 pos)
 {
     int delta = std::distance(m_queue1.rbegin(), pos);
@@ -1561,8 +1567,7 @@ void CallbackFlushHandler::queue(const int type, const 
char* data)
             case LOK_CALLBACK_GRAPHIC_SELECTION:
             case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
             case LOK_CALLBACK_INVALIDATE_TILES:
-                if (removeAll(
-                        [type](int elemType, const CallbackData&) { return 
(elemType == type); }))
+                if (removeAll(type))
                     SAL_INFO("lok", "Removed dups of [" << type << "]: [" << 
payload << "].");
                 break;
         }
@@ -1585,8 +1590,7 @@ void CallbackFlushHandler::queue(const int type, const 
char* data)
             case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
             case LOK_CALLBACK_RULER_UPDATE:
             {
-                if (removeAll(
-                        [type](int elemType, const CallbackData&) { return 
(elemType == type); }))
+                if (removeAll(type))
                     SAL_INFO("lok", "Removed dups of [" << type << "]: [" << 
payload << "].");
             }
             break;
@@ -1609,9 +1613,8 @@ void CallbackFlushHandler::queue(const int type, const 
char* data)
                     payload.find("\"hyperlink\":\"\"") == std::string::npos &&
                     payload.find("\"hyperlink\": {}") == std::string::npos;
                 const int nViewId = lcl_getViewId(payload);
-                removeAll(
-                    [type, nViewId, hyperLinkException] (int elemType, const 
CallbackData& elemData) {
-                        return (elemType == type && nViewId == 
lcl_getViewId(elemData) && !hyperLinkException);
+                removeAll(type, [nViewId, hyperLinkException] (const 
CallbackData& elemData) {
+                        return (nViewId == lcl_getViewId(elemData) && 
!hyperLinkException);
                     }
                 );
             }
@@ -1635,9 +1638,8 @@ void CallbackFlushHandler::queue(const int type, const 
char* data)
                     // a save occurs while a cell is still edited in Calc.
                     if (name != ".uno:ModifiedStatus=")
                     {
-                        removeAll(
-                            [type, &name] (int elemType, const CallbackData& 
elemData) {
-                                return (elemType == type) && 
(elemData.PayloadString.compare(0, name.size(), name) == 0);
+                        removeAll(type, [&name] (const CallbackData& elemData) 
{
+                                return (elemData.PayloadString.compare(0, 
name.size(), name) == 0);
                             }
                         );
                     }
@@ -1654,8 +1656,8 @@ void CallbackFlushHandler::queue(const int type, const 
char* data)
             {
                 // remove only selection ranges and 'EMPTY' messages
                 // always send 'INPLACE' and 'INPLACE EXIT' messages
-                removeAll([type, payload] (int elemType, const CallbackData& 
elemData)
-                    { return (elemType == type && elemData.PayloadString[0] != 
'I'); });
+                removeAll(type, [payload] (const CallbackData& elemData)
+                    { return (elemData.PayloadString[0] != 'I'); });
             }
             break;
         }
@@ -1740,16 +1742,9 @@ bool 
CallbackFlushHandler::processInvalidateTilesEvent(int type, CallbackData& a
     {
         SAL_INFO("lok", "Have Empty [" << type << "]: [" << payload
                                        << "] so removing all with part " << 
rcNew.m_nPart << ".");
-        removeAll([&rcNew](int elemType, const CallbackData& elemData) {
-            if (elemType == LOK_CALLBACK_INVALIDATE_TILES)
-            {
-                // Remove exiting if new is all-encompassing, or if of the 
same part.
-                const RectangleAndPart rcOld = 
RectangleAndPart::Create(elemData.PayloadString);
-                return (rcNew.m_nPart == -1 || rcOld.m_nPart == rcNew.m_nPart);
-            }
-
-            // Keep others.
-            return false;
+        removeAll(LOK_CALLBACK_INVALIDATE_TILES, [&rcNew](const CallbackData& 
elemData) {
+            // Remove exiting if new is all-encompassing, or if of the same 
part.
+            return (rcNew.m_nPart == -1 || rcNew.m_nPart == 
elemData.getRectangleAndPart().m_nPart);
         });
     }
     else
@@ -1757,55 +1752,52 @@ bool 
CallbackFlushHandler::processInvalidateTilesEvent(int type, CallbackData& a
         const auto rcOrig = rcNew;
 
         SAL_INFO("lok", "Have [" << type << "]: [" << payload << "] so merging 
overlapping.");
-        removeAll([&rcNew](int elemType, const CallbackData& elemData) {
-            if (elemType == LOK_CALLBACK_INVALIDATE_TILES)
+        removeAll(LOK_CALLBACK_INVALIDATE_TILES,[&rcNew](const CallbackData& 
elemData) {
+            const RectangleAndPart& rcOld = elemData.getRectangleAndPart();
+            if (rcNew.m_nPart != -1 && rcOld.m_nPart != -1 && rcOld.m_nPart != 
rcNew.m_nPart)
             {
-                const RectangleAndPart& rcOld = elemData.getRectangleAndPart();
-                if (rcNew.m_nPart != -1 && rcOld.m_nPart != -1 && 
rcOld.m_nPart != rcNew.m_nPart)
-                {
-                    SAL_INFO("lok", "Nothing to merge between new: "
-                                        << rcNew.toString() << ", and old: " 
<< rcOld.toString());
-                    return false;
-                }
+                SAL_INFO("lok", "Nothing to merge between new: "
+                                    << rcNew.toString() << ", and old: " << 
rcOld.toString());
+                return false;
+            }
 
-                if (rcNew.m_nPart == -1)
+            if (rcNew.m_nPart == -1)
+            {
+                // Don't merge unless fully overlapped.
+                SAL_INFO("lok", "New " << rcNew.toString() << " has " << 
rcOld.toString()
+                                       << "?");
+                if (rcNew.m_aRectangle.IsInside(rcOld.m_aRectangle))
                 {
-                    // Don't merge unless fully overlapped.
-                    SAL_INFO("lok", "New " << rcNew.toString() << " has " << 
rcOld.toString()
-                                           << "?");
-                    if (rcNew.m_aRectangle.IsInside(rcOld.m_aRectangle))
-                    {
-                        SAL_INFO("lok", "New " << rcNew.toString() << " 
engulfs old "
-                                               << rcOld.toString() << ".");
-                        return true;
-                    }
+                    SAL_INFO("lok", "New " << rcNew.toString() << " engulfs 
old "
+                                           << rcOld.toString() << ".");
+                    return true;
                 }
-                else if (rcOld.m_nPart == -1)
+            }
+            else if (rcOld.m_nPart == -1)
+            {
+                // Don't merge unless fully overlapped.
+                SAL_INFO("lok", "Old " << rcOld.toString() << " has " << 
rcNew.toString()
+                                       << "?");
+                if (rcOld.m_aRectangle.IsInside(rcNew.m_aRectangle))
                 {
-                    // Don't merge unless fully overlapped.
-                    SAL_INFO("lok", "Old " << rcOld.toString() << " has " << 
rcNew.toString()
-                                           << "?");
-                    if (rcOld.m_aRectangle.IsInside(rcNew.m_aRectangle))
-                    {
-                        SAL_INFO("lok", "New " << rcNew.toString() << " 
engulfs old "
-                                               << rcOld.toString() << ".");
-                        return true;
-                    }
+                    SAL_INFO("lok", "New " << rcNew.toString() << " engulfs 
old "
+                                           << rcOld.toString() << ".");
+                    return true;
                 }
-                else
+            }
+            else
+            {
+                const tools::Rectangle rcOverlap
+                    = rcNew.m_aRectangle.GetIntersection(rcOld.m_aRectangle);
+                const bool bOverlap = !rcOverlap.IsEmpty();
+                SAL_INFO("lok", "Merging " << rcNew.toString() << " & " << 
rcOld.toString()
+                                           << " => " << rcOverlap.toString()
+                                           << " Overlap: " << bOverlap);
+                if (bOverlap)
                 {
-                    const tools::Rectangle rcOverlap
-                        = 
rcNew.m_aRectangle.GetIntersection(rcOld.m_aRectangle);
-                    const bool bOverlap = !rcOverlap.IsEmpty();
-                    SAL_INFO("lok", "Merging " << rcNew.toString() << " & " << 
rcOld.toString()
-                                               << " => " << 
rcOverlap.toString()
-                                               << " Overlap: " << bOverlap);
-                    if (bOverlap)
-                    {
-                        rcNew.m_aRectangle.Union(rcOld.m_aRectangle);
-                        SAL_INFO("lok", "Merged: " << rcNew.toString());
-                        return true;
-                    }
+                    rcNew.m_aRectangle.Union(rcOld.m_aRectangle);
+                    SAL_INFO("lok", "Merged: " << rcNew.toString());
+                    return true;
                 }
             }
 
@@ -1843,15 +1835,12 @@ bool CallbackFlushHandler::processWindowEvent(int type, 
CallbackData& aCallbackD
         // remove all previous window part invalidations
         if (aRectStr.empty())
         {
-            removeAll([&nLOKWindowId](int elemType, const CallbackData& 
elemData) {
-                if (elemType == LOK_CALLBACK_WINDOW)
+            removeAll(LOK_CALLBACK_WINDOW,[&nLOKWindowId](const CallbackData& 
elemData) {
+                const boost::property_tree::ptree& aOldTree = 
elemData.getJson();
+                if (nLOKWindowId == aOldTree.get<unsigned>("id", 0)
+                    && aOldTree.get<std::string>("action", "") == "invalidate")
                 {
-                    const boost::property_tree::ptree& aOldTree = 
elemData.getJson();
-                    if (nLOKWindowId == aOldTree.get<unsigned>("id", 0)
-                        && aOldTree.get<std::string>("action", "") == 
"invalidate")
-                    {
-                        return true;
-                    }
+                    return true;
                 }
                 return false;
             });
@@ -1892,11 +1881,8 @@ bool CallbackFlushHandler::processWindowEvent(int type, 
CallbackData& aCallbackD
             aRectStream >> nLeft >> nComma >> nTop >> nComma >> nWidth >> 
nComma >> nHeight;
             tools::Rectangle aNewRect(nLeft, nTop, nLeft + nWidth, nTop + 
nHeight);
             bool currentIsRedundant = false;
-            removeAll([&aNewRect, &nLOKWindowId,
-                       &currentIsRedundant](int elemType, const CallbackData& 
elemData) {
-                if (elemType != LOK_CALLBACK_WINDOW)
-                    return false;
-
+            removeAll(LOK_CALLBACK_WINDOW, [&aNewRect, &nLOKWindowId,
+                       &currentIsRedundant](const CallbackData& elemData) {
                 const boost::property_tree::ptree& aOldTree = 
elemData.getJson();
                 if (aOldTree.get<std::string>("action", "") == "invalidate")
                 {
@@ -1968,13 +1954,10 @@ bool CallbackFlushHandler::processWindowEvent(int type, 
CallbackData& aCallbackD
     else if (aAction == "created")
     {
         // Remove all previous actions on same dialog, if we are creating it 
anew.
-        removeAll([&nLOKWindowId](int elemType, const CallbackData& elemData) {
-            if (elemType == LOK_CALLBACK_WINDOW)
-            {
-                const boost::property_tree::ptree& aOldTree = 
elemData.getJson();
-                if (nLOKWindowId == aOldTree.get<unsigned>("id", 0))
-                    return true;
-            }
+        removeAll(LOK_CALLBACK_WINDOW,[&nLOKWindowId](const CallbackData& 
elemData) {
+            const boost::property_tree::ptree& aOldTree = elemData.getJson();
+            if (nLOKWindowId == aOldTree.get<unsigned>("id", 0))
+                return true;
             return false;
         });
 
@@ -1996,16 +1979,13 @@ bool CallbackFlushHandler::processWindowEvent(int type, 
CallbackData& aCallbackD
     {
         // A size change is practically re-creation of the window.
         // But at a minimum it's a full invalidation.
-        removeAll([&nLOKWindowId](int elemType, const CallbackData& elemData) {
-            if (elemType == LOK_CALLBACK_WINDOW)
+        removeAll(LOK_CALLBACK_WINDOW, [&nLOKWindowId](const CallbackData& 
elemData) {
+            const boost::property_tree::ptree& aOldTree = elemData.getJson();
+            if (nLOKWindowId == aOldTree.get<unsigned>("id", 0))
             {
-                const boost::property_tree::ptree& aOldTree = 
elemData.getJson();
-                if (nLOKWindowId == aOldTree.get<unsigned>("id", 0))
-                {
-                    const std::string aOldAction = 
aOldTree.get<std::string>("action", "");
-                    if (aOldAction == "invalidate")
-                        return true;
-                }
+                const std::string aOldAction = 
aOldTree.get<std::string>("action", "");
+                if (aOldAction == "invalidate")
+                    return true;
             }
             return false;
         });
@@ -2083,6 +2063,44 @@ void CallbackFlushHandler::Invoke()
     m_queue2.clear();
 }
 
+bool CallbackFlushHandler::removeAll(int type)
+{
+    bool bErased = false;
+    auto it1 = m_queue1.begin();
+    for(;;)
+    {
+        it1 = std::find(it1, m_queue1.end(), type);
+        if(it1 == m_queue1.end())
+            break;
+        m_queue2.erase(toQueue2(it1));
+        it1 = m_queue1.erase(it1);
+        bErased = true;
+    }
+    return bErased;
+}
+
+bool CallbackFlushHandler::removeAll(int type, const std::function<bool (const 
CallbackData&)>& rTestFunc)
+{
+    bool bErased = false;
+    auto it1 = m_queue1.begin();
+    for(;;)
+    {
+        it1 = std::find(it1, m_queue1.end(), type);
+        if(it1 == m_queue1.end())
+            break;
+        auto it2 = toQueue2(it1);
+        if (rTestFunc(*it2))
+        {
+            m_queue2.erase(it2);
+            it1 = m_queue1.erase(it1);
+            bErased = true;
+        }
+        else
+            ++it1;
+    }
+    return bErased;
+}
+
 bool CallbackFlushHandler::removeAll(const std::function<bool (int, const 
CallbackData&)>& rTestFunc)
 {
     bool bErased = false;

Reply via email to