[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