[Libreoffice-commits] online.git: test/TileQueueTests.cpp wsd/SenderQueue.hpp

Ashod Nakashian ashod.nakashian at collabora.co.uk
Mon Dec 19 06:02:06 UTC 2016


 test/TileQueueTests.cpp |   62 ++++++++++++++++++++++++++++++++++++++++++++++++
 wsd/SenderQueue.hpp     |   57 ++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 114 insertions(+), 5 deletions(-)

New commits:
commit 839d7a9b436adc2b8ad05fd7b72a6f7b9bb42934
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sun Dec 18 17:28:35 2016 -0500

    wsd: deduplicate invalidate view cursor messages
    
    Change-Id: I898c98ad42fb807ebeafafa47d85930025def57f
    Reviewed-on: https://gerrit.libreoffice.org/32162
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>

diff --git a/test/TileQueueTests.cpp b/test/TileQueueTests.cpp
index 7df94ef..0e12f48 100644
--- a/test/TileQueueTests.cpp
+++ b/test/TileQueueTests.cpp
@@ -47,6 +47,7 @@ class TileQueueTests : public CPPUNIT_NS::TestFixture
     CPPUNIT_TEST(testPreviewsDeprioritization);
     CPPUNIT_TEST(testSenderQueue);
     CPPUNIT_TEST(testSenderQueueTileDeduplication);
+    CPPUNIT_TEST(testInvalidateViewCursorDeduplication);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -57,6 +58,7 @@ class TileQueueTests : public CPPUNIT_NS::TestFixture
     void testPreviewsDeprioritization();
     void testSenderQueue();
     void testSenderQueueTileDeduplication();
+    void testInvalidateViewCursorDeduplication();
 };
 
 void TileQueueTests::testTileQueuePriority()
@@ -295,6 +297,7 @@ void TileQueueTests::testSenderQueue()
     CPPUNIT_ASSERT_EQUAL(true, queue.waitDequeue(item, 0));
     CPPUNIT_ASSERT_EQUAL(1UL, queue.size());
     CPPUNIT_ASSERT_EQUAL(messages[1], std::string(item->data().data(), item->data().size()));
+
     CPPUNIT_ASSERT_EQUAL(true, queue.waitDequeue(item, 0));
     CPPUNIT_ASSERT_EQUAL(0UL, queue.size());
     CPPUNIT_ASSERT_EQUAL(messages[2], std::string(item->data().data(), item->data().size()));
@@ -352,6 +355,65 @@ void TileQueueTests::testSenderQueueTileDeduplication()
     CPPUNIT_ASSERT_EQUAL(0UL, queue.size());
 }
 
+void TileQueueTests::testInvalidateViewCursorDeduplication()
+{
+    SenderQueue<std::shared_ptr<MessagePayload>> queue;
+
+    std::shared_ptr<MessagePayload> item;
+
+    // Empty queue
+    CPPUNIT_ASSERT_EQUAL(false, queue.waitDequeue(item, 10));
+    CPPUNIT_ASSERT_EQUAL(0UL, queue.size());
+
+    const std::vector<std::string> view_messages =
+    {
+        "invalidateviewcursor: {    \"viewId\": \"1\",     \"rectangle\": \"3999, 1418, 0, 298\",     \"part\": \"0\" }",
+        "invalidateviewcursor: {    \"viewId\": \"2\",     \"rectangle\": \"3999, 1418, 0, 298\",     \"part\": \"0\" }",
+        "invalidateviewcursor: {    \"viewId\": \"3\",     \"rectangle\": \"3999, 1418, 0, 298\",     \"part\": \"0\" }",
+    };
+
+    for (const auto& msg : view_messages)
+    {
+        queue.enqueue(std::make_shared<MessagePayload>(msg));
+    }
+
+    CPPUNIT_ASSERT_EQUAL(3UL, queue.size());
+
+    CPPUNIT_ASSERT_EQUAL(true, queue.waitDequeue(item, 0));
+    CPPUNIT_ASSERT_EQUAL(2UL, queue.size());
+    CPPUNIT_ASSERT_EQUAL(view_messages[0], std::string(item->data().data(), item->data().size()));
+
+    CPPUNIT_ASSERT_EQUAL(true, queue.waitDequeue(item, 0));
+    CPPUNIT_ASSERT_EQUAL(1UL, queue.size());
+    CPPUNIT_ASSERT_EQUAL(view_messages[1], std::string(item->data().data(), item->data().size()));
+
+    CPPUNIT_ASSERT_EQUAL(true, queue.waitDequeue(item, 0));
+    CPPUNIT_ASSERT_EQUAL(0UL, queue.size());
+    CPPUNIT_ASSERT_EQUAL(view_messages[2], std::string(item->data().data(), item->data().size()));
+
+    CPPUNIT_ASSERT_EQUAL(0UL, queue.size());
+
+    const std::vector<std::string> dup_messages =
+    {
+        "invalidateviewcursor: {    \"viewId\": \"1\",     \"rectangle\": \"3999, 1418, 0, 298\",     \"part\": \"0\" }",
+        "invalidateviewcursor: {    \"viewId\": \"1\",     \"rectangle\": \"1000, 1418, 0, 298\",     \"part\": \"0\" }",
+        "invalidateviewcursor: {    \"viewId\": \"1\",     \"rectangle\": \"2000, 1418, 0, 298\",     \"part\": \"0\" }",
+    };
+
+    for (const auto& msg : dup_messages)
+    {
+        queue.enqueue(std::make_shared<MessagePayload>(msg));
+    }
+
+    CPPUNIT_ASSERT_EQUAL(1UL, queue.size());
+    CPPUNIT_ASSERT_EQUAL(true, queue.waitDequeue(item, 0));
+
+    // The last one should persist.
+    CPPUNIT_ASSERT_EQUAL(dup_messages[2], std::string(item->data().data(), item->data().size()));
+
+    CPPUNIT_ASSERT_EQUAL(0UL, queue.size());
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(TileQueueTests);
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/wsd/SenderQueue.hpp b/wsd/SenderQueue.hpp
index 4e1c425..3c42264 100644
--- a/wsd/SenderQueue.hpp
+++ b/wsd/SenderQueue.hpp
@@ -16,6 +16,11 @@
 #include <mutex>
 #include <vector>
 
+#include <Poco/Dynamic/Var.h>
+#include <Poco/JSON/JSON.h>
+#include <Poco/JSON/Object.h>
+#include <Poco/JSON/Parser.h>
+
 #include "common/SigUtil.hpp"
 #include "LOOLWebSocket.hpp"
 #include "Log.hpp"
@@ -26,16 +31,17 @@ class MessagePayload
 {
 public:
 
-    enum class Type { Text, Binary };
+    enum class Type { Text, JSON, Binary };
 
     /// Construct a text message.
     /// message must include the full first-line.
-    MessagePayload(const std::string& message) :
+    MessagePayload(const std::string& message,
+                   const enum Type type = Type::Text) :
         _data(message.data(), message.data() + message.size()),
         _tokens(LOOLProtocol::tokenize(_data.data(), _data.size())),
         _firstLine(LOOLProtocol::getFirstLine(_data.data(), _data.size())),
         _abbreviation(LOOLProtocol::getAbbreviatedMessage(_data.data(), _data.size())),
-        _type(Type::Text)
+        _type(type)
     {
     }
 
@@ -44,8 +50,8 @@ public:
     /// message must include the full first-line.
     MessagePayload(const std::string& message,
                    const enum Type type,
-                   const size_t reserve = 0) :
-        _data(reserve),
+                   const size_t reserve) :
+        _data(std::max(reserve, message.size())),
         _tokens(LOOLProtocol::tokenize(_data.data(), _data.size())),
         _firstLine(LOOLProtocol::getFirstLine(_data.data(), _data.size())),
         _abbreviation(LOOLProtocol::getAbbreviatedMessage(_data.data(), _data.size())),
@@ -76,6 +82,18 @@ public:
     const std::string& firstLine() const { return _firstLine; }
     const std::string& abbreviation() const { return _abbreviation; }
 
+    /// Returns the json part of the message, if any.
+    std::string jsonString() const
+    {
+        if (_tokens.size() > 1 && _tokens[1] == "{")
+        {
+            const auto firstTokenSize = _tokens[0].size();
+            return std::string(_data.data() + firstTokenSize, _data.size() - firstTokenSize);
+        }
+
+        return std::string();
+    }
+
     /// Append more data to the message.
     void append(const char* data, const size_t size)
     {
@@ -193,6 +211,35 @@ private:
                 _queue.erase(pos);
             }
         }
+        else if (command == "invalidateviewcursor:")
+        {
+            // Remove previous cursor invalidation for same view,
+            // if any, and use most recent (incoming).
+            const std::string newMsg = item->jsonString();
+            Poco::JSON::Parser newParser;
+            const auto newResult = newParser.parse(newMsg);
+            const auto& newJson = newResult.extract<Poco::JSON::Object::Ptr>();
+            const auto viewId = newJson->get("viewId").toString();
+            const auto& pos = std::find_if(_queue.begin(), _queue.end(),
+                [command, viewId](const queue_item_t& cur)
+                {
+                    if (cur->firstToken() == command)
+                    {
+                        const std::string msg = cur->jsonString();
+                        Poco::JSON::Parser parser;
+                        const auto result = parser.parse(msg);
+                        const auto& json = result.extract<Poco::JSON::Object::Ptr>();
+                        return (viewId == json->get("viewId").toString());
+                    }
+
+                    return false;
+                });
+
+            if (pos != _queue.end())
+            {
+                _queue.erase(pos);
+            }
+        }
 
         return true;
     }


More information about the Libreoffice-commits mailing list