test/TileCacheTests.cpp | 11 ++ wsd/ClientSession.cpp | 14 +-- wsd/DocumentBroker.cpp | 1 wsd/TileCache.cpp | 208 +++++++++++++++++++++++++----------------------- wsd/TileCache.hpp | 106 +++++++++++++++++++----- wsd/TileDesc.hpp | 2 6 files changed, 212 insertions(+), 130 deletions(-)
New commits: commit 6634d3b3e9c6ac8aac37a344fc2de4f543f52170 Author: Michael Meeks <[email protected]> AuthorDate: Fri Feb 15 21:55:47 2019 +0100 Commit: Michael Meeks <[email protected]> CommitDate: Tue Mar 5 06:58:50 2019 +0100 TileCache: key almost everything on TileDesc instead of string names. Saves lots of string construction and storage, simplifies lots of code. Store the more exotic font-caching bits etc. in a separate store: we should also pre-render these really and share them. Change-Id: Icaeff8fd72f52d7215c06a687b1e39cfb7631503 diff --git a/test/TileCacheTests.cpp b/test/TileCacheTests.cpp index c02989dee..d6577f50a 100644 --- a/test/TileCacheTests.cpp +++ b/test/TileCacheTests.cpp @@ -57,6 +57,7 @@ class TileCacheTests : public CPPUNIT_NS::TestFixture CPPUNIT_TEST_SUITE(TileCacheTests); + CPPUNIT_TEST(testDesc); CPPUNIT_TEST(testSimple); CPPUNIT_TEST(testSimpleCombine); CPPUNIT_TEST(testCancelTiles); @@ -91,6 +92,7 @@ class TileCacheTests : public CPPUNIT_NS::TestFixture CPPUNIT_TEST_SUITE_END(); + void testDesc(); void testSimple(); void testSimpleCombine(); void testCancelTiles(); @@ -173,6 +175,15 @@ public: } }; +void TileCacheTests::testDesc() +{ + TileCacheDesc descA = TileDesc(0, 256, 256, 0, 0, 3200, 3200, /* ignored in cache */ 0, 1234, 1, true); + TileCacheDesc descB = TileDesc(0, 256, 256, 0, 0, 3200, 3200, /* ignored in cache */ 1, 1235, 2, false); + + CPPUNIT_ASSERT_MESSAGE("versions do match", descA.getVersion() != descB.getVersion()); + CPPUNIT_ASSERT_MESSAGE("Compare includes fields it should not", descA == descB); +} + void TileCacheTests::testSimple() { if (isStandalone()) diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp index c3d5b9a83..6b61765ae 100644 --- a/wsd/ClientSession.cpp +++ b/wsd/ClientSession.cpp @@ -480,15 +480,11 @@ bool ClientSession::getCommandValues(const char *buffer, int length, const std:: { std::string command; if (tokens.size() != 2 || !getTokenString(tokens[1], "command", command)) - { return sendTextFrame("error: cmd=commandvalues kind=syntax"); - } std::string cmdValues; - if (docBroker->tileCache().getTextFile("cmdValues" + command + ".txt", cmdValues)) - { + if (docBroker->tileCache().getTextStream(TileCache::StreamType::CmdValues, command, cmdValues)) return sendTextFrame(cmdValues); - } return forwardToChild(std::string(buffer, length), docBroker); } @@ -505,8 +501,7 @@ bool ClientSession::sendFontRendering(const char *buffer, int length, const std: getTokenString(tokens[2], "char", text); - - TileCache::Tile cachedTile = docBroker->tileCache().lookupCachedTile(font+text, "font"); + TileCache::Tile cachedTile = docBroker->tileCache().lookupCachedStream(TileCache::StreamType::Font, font+text); if (cachedTile) { const std::string response = "renderfont: " + Poco::cat(std::string(" "), tokens.begin() + 1, tokens.end()) + "\n"; @@ -951,7 +946,7 @@ bool ClientSession::handleKitToClientMessage(const char* buffer, const int lengt commandName == ".uno:StyleApply") { // other commands should not be cached - docBroker->tileCache().saveTextFile(stringMsg, "cmdValues" + commandName + ".txt"); + docBroker->tileCache().saveTextStream(TileCache::StreamType::CmdValues, stringMsg, commandName); } } } @@ -1006,7 +1001,8 @@ bool ClientSession::handleKitToClientMessage(const char* buffer, const int lengt getTokenString(tokens[2], "char", text); assert(firstLine.size() < static_cast<std::string::size_type>(length)); - docBroker->tileCache().saveRendering(font+text, "font", buffer + firstLine.size() + 1, length - firstLine.size() - 1); + docBroker->tileCache().saveStream(TileCache::StreamType::Font, font+text, + buffer + firstLine.size() + 1, length - firstLine.size() - 1); return forwardToClient(payload); } } diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp index 888500de8..3194d4f58 100644 --- a/wsd/DocumentBroker.cpp +++ b/wsd/DocumentBroker.cpp @@ -1645,7 +1645,6 @@ void DocumentBroker::setModified(const bool value) } _storage->setUserModified(value); - _tileCache->setUnsavedChanges(value); } bool DocumentBroker::isInitialSettingSet(const std::string& name) const diff --git a/wsd/TileCache.cpp b/wsd/TileCache.cpp index 6ca40c9f9..3b9fb9d41 100644 --- a/wsd/TileCache.cpp +++ b/wsd/TileCache.cpp @@ -67,6 +67,8 @@ TileCache::~TileCache() void TileCache::clear() { _cache.clear(); + for (auto i : _streamCache) + i.clear(); LOG_INF("Completely cleared tile cache for: " << _docURL); } @@ -75,15 +77,13 @@ void TileCache::clear() /// rendering latency. struct TileCache::TileBeingRendered { - TileBeingRendered(const std::string& cachedName, const TileDesc& tile) + TileBeingRendered(const TileDesc& tile) : _startTime(std::chrono::steady_clock::now()), - _tile(tile), - _cachedName(cachedName) + _tile(tile) { } const TileDesc& getTile() const { return _tile; } - const std::string& getCacheName() const { return _cachedName; } int getVersion() const { return _tile.getVersion(); } void setVersion(int version) { _tile.setVersion(version); } @@ -95,7 +95,6 @@ private: std::vector<std::weak_ptr<ClientSession>> _subscribers; std::chrono::steady_clock::time_point _startTime; TileDesc _tile; - std::string _cachedName; }; size_t TileCache::countTilesBeingRenderedForSession(const std::shared_ptr<ClientSession>& session) @@ -111,13 +110,16 @@ size_t TileCache::countTilesBeingRenderedForSession(const std::shared_ptr<Client return count; } -std::shared_ptr<TileCache::TileBeingRendered> TileCache::findTileBeingRendered(const TileDesc& tileDesc) +bool TileCache::hasTileBeingRendered(const std::shared_ptr<TileCache::TileBeingRendered>& tileBeingRendered) { - const std::string cachedName = cacheFileName(tileDesc); + return _tilesBeingRendered.find(tileBeingRendered->getTile()) != _tilesBeingRendered.end(); +} +std::shared_ptr<TileCache::TileBeingRendered> TileCache::findTileBeingRendered(const TileDesc& tileDesc) +{ assertCorrectThread(); - const auto tile = _tilesBeingRendered.find(cachedName); + const auto tile = _tilesBeingRendered.find(tileDesc); return tile != _tilesBeingRendered.end() ? tile->second : nullptr; } @@ -125,23 +127,24 @@ void TileCache::forgetTileBeingRendered(const std::shared_ptr<TileCache::TileBei { assertCorrectThread(); assert(tileBeingRendered); - assert(_tilesBeingRendered.find(tileBeingRendered->getCacheName()) != _tilesBeingRendered.end()); + assert(hasTileBeingRendered(tileBeingRendered)); - _tilesBeingRendered.erase(tileBeingRendered->getCacheName()); + LOG_TRC("Removing all subscribers for " << tileBeingRendered->getTile().serialize()); + _tilesBeingRendered.erase(tileBeingRendered->getTile()); } -double TileCache::getTileBeingRenderedElapsedTimeMs(const std::string& tileCacheName) const +double TileCache::getTileBeingRenderedElapsedTimeMs(const TileDesc &tileDesc) const { - auto iterator = _tilesBeingRendered.find(tileCacheName); - if(iterator == _tilesBeingRendered.end()) + auto it = _tilesBeingRendered.find(tileDesc); + if (it == _tilesBeingRendered.end()) return -1.0; // Negativ value means that we did not find tileBeingRendered object - return iterator->second->getElapsedTimeMs(); + return it->second->getElapsedTimeMs(); } bool TileCache::hasTileBeingRendered(const TileDesc& tile) { - return (findTileBeingRendered(tile) != nullptr); + return findTileBeingRendered(tile) != nullptr; } int TileCache::getTileBeingRenderedVersion(const TileDesc& tile) @@ -158,8 +161,7 @@ TileCache::Tile TileCache::lookupTile(const TileDesc& tile) if (_dontCache) return TileCache::Tile(); - const std::string fileName = cacheFileName(tile); - TileCache::Tile ret = loadTile(fileName); + TileCache::Tile ret = findTile(tile); UnitWSD::get().lookupTile(tile.getPart(), tile.getWidth(), tile.getHeight(), tile.getTilePosX(), tile.getTilePosY(), @@ -168,16 +170,6 @@ TileCache::Tile TileCache::lookupTile(const TileDesc& tile) return ret; } -void TileCache::saveDataToCache(const std::string &fileName, const char *data, const size_t size) -{ - if (_dontCache) - return; - - TileCache::Tile tile = std::make_shared<std::vector<char>>(size); - std::memcpy(tile->data(), data, size); - _cache[fileName] = tile; -} - void TileCache::saveTileAndNotify(const TileDesc& tile, const char *data, const size_t size) { assertCorrectThread(); @@ -185,14 +177,11 @@ void TileCache::saveTileAndNotify(const TileDesc& tile, const char *data, const std::shared_ptr<TileBeingRendered> tileBeingRendered = findTileBeingRendered(tile); // Save to disk. - const std::string cachedName = (tileBeingRendered ? tileBeingRendered->getCacheName() - : cacheFileName(tile)); // Ignore if we can't save the tile, things will work anyway, but slower. // An error indication is supposed to be sent to all users in that case. - const auto fileName = cachedName; - saveDataToCache(fileName, data, size); - LOG_TRC("Saved cache tile: " << fileName); + saveDataToCache(tile, data, size); + LOG_TRC("Saved cache tile: " << cacheFileName(tile) << " of size " << size << " bytes"); // Notify subscribers, if any. if (tileBeingRendered) @@ -242,7 +231,7 @@ void TileCache::saveTileAndNotify(const TileDesc& tile, const char *data, const } else { - LOG_DBG("No subscribers for: " << cachedName); + LOG_DBG("No subscribers for: " << cacheFileName(tile)); } // Remove subscriptions. @@ -255,13 +244,13 @@ void TileCache::saveTileAndNotify(const TileDesc& tile, const char *data, const } else { - LOG_DBG("No subscribers for: " << cachedName); + LOG_DBG("No subscribers for: " << cacheFileName(tile)); } } -bool TileCache::getTextFile(const std::string& fileName, std::string& content) +bool TileCache::getTextStream(StreamType type, const std::string& fileName, std::string& content) { - Tile textStream = loadTile(fileName); + Tile textStream = lookupCachedStream(type, fileName); if (!textStream) { LOG_INF("Could not open " << fileName); @@ -280,33 +269,30 @@ bool TileCache::getTextFile(const std::string& fileName, std::string& content) return true; } -void TileCache::saveTextFile(const std::string& text, const std::string& fileName) +void TileCache::saveTextStream(StreamType type, const std::string& text, const std::string& fileName) { LOG_INF("Saving '" << LOOLProtocol::getAbbreviatedMessage(text.c_str(), text.size()) << - "' to " << fileName); + "' to " << fileName << " of size " << text.size() << " bytes"); - saveDataToCache(fileName, text.c_str(), text.size()); + saveDataToStreamCache(type, fileName, text.c_str(), text.size()); } -void TileCache::setUnsavedChanges(bool state) -{ - if (state) - saveTextFile("1", "unsaved.txt"); - else - removeFile("unsaved.txt"); -} - -void TileCache::saveRendering(const std::string& name, const std::string& dir, const char *data, std::size_t size) +void TileCache::saveStream(StreamType type, const std::string& name, const char *data, std::size_t size) { // can fonts be invalidated? - const std::string fileName = dir + "/" + name; - - saveDataToCache(fileName, data, size); + saveDataToStreamCache(type, name, data, size); } -TileCache::Tile TileCache::lookupCachedTile(const std::string& name, const std::string& dir) +TileCache::Tile TileCache::lookupCachedStream(StreamType type, const std::string& name) { - return loadTile(dir + "/" + name); + auto it = _streamCache[type].find(name); + if (it != _streamCache[type].end()) + { + LOG_TRC("Found stream cache tile: " << name << " of size " << it->second->size() << " bytes"); + return it->second; + } + else + return TileCache::Tile(); } void TileCache::invalidateTiles(int part, int x, int y, int width, int height) @@ -320,10 +306,9 @@ void TileCache::invalidateTiles(int part, int x, int y, int width, int height) for (auto it = _cache.begin(); it != _cache.end();) { - const std::string fileName = it->first; - if (intersectsTile(fileName, part, x, y, width, height)) + if (intersectsTile(it->first, part, x, y, width, height)) { - LOG_DBG("Removing tile: " << it->first); + LOG_DBG("Removing tile: " << it->first.serialize()); it = _cache.erase(it); } else @@ -375,13 +360,13 @@ std::pair<int, Util::Rectangle> TileCache::parseInvalidateMsg(const std::string& return std::pair<int, Util::Rectangle>(-1, Util::Rectangle(0, 0, 0, 0)); } -void TileCache::removeFile(const std::string& fileName) +void TileCache::removeStream(StreamType type, const std::string& fileName) { - auto it = _cache.find(fileName); - if (it != _cache.end()) + auto it = _streamCache[type].find(fileName); + if (it != _streamCache[type].end()) { LOG_INF("Removed file: " << fileName); - _cache.erase(it); + _streamCache[type].erase(it); } } @@ -399,24 +384,17 @@ bool TileCache::parseCacheFileName(const std::string& fileName, int& part, int& return std::sscanf(fileName.c_str(), "%d_%dx%d.%d,%d.%dx%d.png", &part, &width, &height, &tilePosX, &tilePosY, &tileWidth, &tileHeight) == 7; } -bool TileCache::intersectsTile(const std::string& fileName, int part, int x, int y, int width, int height) +bool TileCache::intersectsTile(const TileDesc &tileDesc, int part, int x, int y, int width, int height) { - int tilePart, tilePixelWidth, tilePixelHeight, tilePosX, tilePosY, tileWidth, tileHeight; - if (parseCacheFileName(fileName, tilePart, tilePixelWidth, tilePixelHeight, tilePosX, tilePosY, tileWidth, tileHeight)) - { - if (part != -1 && tilePart != part) - return false; - - const int left = std::max(x, tilePosX); - const int right = std::min(x + width, tilePosX + tileWidth); - const int top = std::max(y, tilePosY); - const int bottom = std::min(y + height, tilePosY + tileHeight); + if (part != -1 && tileDesc.getPart() != part) + return false; - if (left <= right && top <= bottom) - return true; - } + const int left = std::max(x, tileDesc.getTilePosX()); + const int right = std::min(x + width, tileDesc.getTilePosX() + tileDesc.getTileWidth()); + const int top = std::max(y, tileDesc.getTilePosY()); + const int bottom = std::min(y + height, tileDesc.getTilePosY() + tileDesc.getTileHeight()); - return false; + return left <= right && top <= bottom; } // FIXME: to be further simplified when we centralize tile messages. @@ -456,15 +434,13 @@ void TileCache::subscribeToTileRendering(const TileDesc& tile, const std::shared else { LOG_DBG("Subscribing " << subscriber->getName() << " to tile " << name << - " ver=" << tile.getVersion() << " which has no subscribers."); + " ver=" << tile.getVersion() << " which has no subscribers " << tile.serialize()); - const std::string cachedName = cacheFileName(tile); + assert(_tilesBeingRendered.find(tile) == _tilesBeingRendered.end()); - assert(_tilesBeingRendered.find(cachedName) == _tilesBeingRendered.end()); - - tileBeingRendered = std::make_shared<TileBeingRendered>(cachedName, tile); + tileBeingRendered = std::make_shared<TileBeingRendered>(tile); tileBeingRendered->getSubscribers().push_back(subscriber); - _tilesBeingRendered[cachedName] = tileBeingRendered; + _tilesBeingRendered[tile] = tileBeingRendered; } } @@ -482,12 +458,10 @@ void TileCache::registerTileBeingRendered(const TileDesc& tile) } else { - const std::string cachedName = cacheFileName(tile); - - assert(_tilesBeingRendered.find(cachedName) == _tilesBeingRendered.end()); + assert(_tilesBeingRendered.find(tile) == _tilesBeingRendered.end()); - tileBeingRendered = std::make_shared<TileBeingRendered>(cachedName, tile); - _tilesBeingRendered[cachedName] = tileBeingRendered; + tileBeingRendered = std::make_shared<TileBeingRendered>(tile); + _tilesBeingRendered[tile] = tileBeingRendered; } } @@ -512,13 +486,13 @@ std::string TileCache::cancelTiles(const std::shared_ptr<ClientSession> &subscri } auto& subscribers = it->second->getSubscribers(); - LOG_TRC("Tile " << it->first << " has " << subscribers.size() << " subscribers."); + LOG_TRC("Tile " << it->first.serialize() << " has " << subscribers.size() << " subscribers."); const auto itRem = std::find_if(subscribers.begin(), subscribers.end(), [sub](std::weak_ptr<ClientSession>& ptr){ return ptr.lock().get() == sub; }); if (itRem != subscribers.end()) { - LOG_TRC("Tile " << it->first << " has " << subscribers.size() << + LOG_TRC("Tile " << it->first.serialize() << " has " << subscribers.size() << " subscribers. Removing " << subscriber->getName() << "."); subscribers.erase(itRem, itRem + 1); if (subscribers.empty()) @@ -547,29 +521,69 @@ void TileCache::assertCorrectThread() assert (correctThread); } -TileCache::Tile TileCache::loadTile(const std::string &fileName) +TileCache::Tile TileCache::findTile(const TileDesc &desc) { - auto it = _cache.find(fileName); + auto it = _cache.find(desc); if (it != _cache.end()) { - LOG_TRC("Found cache tile: " << fileName); + LOG_TRC("Found cache tile: " << desc.serialize() << " of size " << it->second->size() << " bytes"); return it->second; } else return TileCache::Tile(); } +void TileCache::saveDataToCache(const TileDesc &desc, const char *data, const size_t size) +{ + if (_dontCache) + return; + + TileCache::Tile tile = std::make_shared<std::vector<char>>(size); + std::memcpy(tile->data(), data, size); + _cache[desc] = tile; +} + +void TileCache::saveDataToStreamCache(StreamType type, const std::string &fileName, const char *data, const size_t size) +{ + if (_dontCache) + return; + + TileCache::Tile tile = std::make_shared<std::vector<char>>(size); + std::memcpy(tile->data(), data, size); + _streamCache[type][fileName] = tile; +} + void TileCache::dumpState(std::ostream& os) { - size_t num = 0, size = 0; - for (auto it : _cache) { - num++; size += it.second->size(); + size_t num = 0, size = 0; + for (auto it : _cache) + { + num++; size += it.second->size(); + } + os << " tile cache: num: " << num << " size: " << size << " bytes\n"; + for (auto it : _cache) + { + os << " " << std::setw(4) << it.first.getWireId() + << "\t" << std::setw(6) << it.second->size() << " bytes" + << "\t'" << it.first.serialize() << "'\n" ; + } } - os << " tile cache: num: " << num << " size: " << size << " bytes\n"; - for (auto it : _cache) + + int type = 0; + for (auto i : _streamCache) { - os << " " /* << std::setw(4) << it.first->getWireId() */ << " - '" << it.first << "' - " << it.second->size() << " bytes\n"; + size_t num = 0, size = 0; + for (auto it : i) + { + num++; size += it.second->size(); + } + os << " stream cache: " << type++ << " num: " << num << " size: " << size << " bytes\n"; + for (auto it : i) + { + os << " " << it.first + << "\t" << std::setw(6) << it.second->size() << " bytes\n"; + } } } diff --git a/wsd/TileCache.hpp b/wsd/TileCache.hpp index 70dc04fa1..d922b941f 100644 --- a/wsd/TileCache.hpp +++ b/wsd/TileCache.hpp @@ -11,10 +11,10 @@ #define INCLUDED_TILECACHE_HPP #include <iosfwd> -#include <map> #include <memory> #include <thread> #include <string> +#include <unordered_map> #include <Poco/Timestamp.h> #include <Rectangle.hpp> @@ -23,11 +23,58 @@ class ClientSession; +class TileCacheDesc : public TileDesc +{ +public: + TileCacheDesc(const TileDesc ©) + : TileDesc(copy) + { + } + + // The cache cares about only some properties. + bool operator==(const TileCacheDesc& other) const + { + return _part == other._part && + _width == other._width && + _height == other._height && + _tilePosX == other._tilePosX && + _tilePosY == other._tilePosY && + _tileWidth == other._tileWidth && + _tileHeight == other._tileHeight; + } +}; + +// The cache cares about only some properties. +struct TileCacheDescCompareEqual +{ + bool operator()(const TileCacheDesc &l, const TileCacheDesc &r) const { return l == r; } +}; + +// The cache cares about only some properties. +struct TileCacheDescHasher +{ + size_t + operator()(const TileCacheDesc &t) const + { + size_t hash = t.getPart(); + + hash = (hash << 5) + hash + t.getWidth(); + hash = (hash << 5) + hash + t.getHeight(); + hash = (hash << 5) + hash + t.getTilePosX(); + hash = (hash << 5) + hash + t.getTilePosY(); + hash = (hash << 5) + hash + t.getTileWidth(); + hash = (hash << 5) + hash + t.getTileHeight(); + + return hash; + } +}; + /// Handles the caching of tiles of one document. class TileCache { struct TileBeingRendered; + bool hasTileBeingRendered(const std::shared_ptr<TileCache::TileBeingRendered>& tileBeingRendered); std::shared_ptr<TileBeingRendered> findTileBeingRendered(const TileDesc& tile); public: @@ -61,23 +108,26 @@ public: void saveTileAndNotify(const TileDesc& tile, const char* data, const size_t size); + enum StreamType { + Font, + Style, + CmdValues, + Last + }; + /// Get the content of a cache file. /// @param content Valid only when the call returns true. /// @return true when the file actually exists - bool getTextFile(const std::string& fileName, std::string& content); + bool getTextStream(StreamType type, const std::string& fileName, std::string& content); // Save some text into a file in the cache directory - void saveTextFile(const std::string& text, const std::string& fileName); - - // Set the unsaved-changes state, used for sanity checks, ideally not needed - void setUnsavedChanges(bool state); + void saveTextStream(StreamType type, const std::string& text, const std::string& fileName); // Saves a font / style / etc rendering - // The dir parameter should be the type of rendering, like "font", "style", etc - void saveRendering(const std::string& name, const std::string& dir, const char* data, size_t size); + void saveStream(StreamType type, const std::string& name, const char* data, size_t size); /// Return the tile data if we have it, or nothing. - Tile lookupCachedTile(const std::string& name, const std::string& dir); + Tile lookupCachedStream(StreamType type, const std::string& name); // The tiles parameter is an invalidatetiles: message as sent by the child process void invalidateTiles(const std::string& tiles); @@ -86,12 +136,11 @@ public: static std::pair<int, Util::Rectangle> parseInvalidateMsg(const std::string& tiles); void forgetTileBeingRendered(const std::shared_ptr<TileCache::TileBeingRendered>& tileBeingRendered); - double getTileBeingRenderedElapsedTimeMs(const std::string& tileCacheName) const; - - size_t countTilesBeingRenderedForSession(const std::shared_ptr<ClientSession>& subscriber); + double getTileBeingRenderedElapsedTimeMs(const TileDesc &tileDesc) const; - bool hasTileBeingRendered(const TileDesc& tile); - int getTileBeingRenderedVersion(const TileDesc& tile); + size_t countTilesBeingRenderedForSession(const std::shared_ptr<ClientSession>& session); + bool hasTileBeingRendered(const TileDesc& tileDesc); + int getTileBeingRenderedVersion(const TileDesc& tileDesc); // Debugging bits ... void dumpState(std::ostream& os); @@ -102,26 +151,39 @@ private: void invalidateTiles(int part, int x, int y, int width, int height); /// Lookup tile in our cache. - TileCache::Tile loadTile(const std::string &fileName); + TileCache::Tile findTile(const TileDesc &desc); + + /// Lookup tile in our stream cache. + TileCache::Tile findStreamTile(StreamType type, const std::string &fileName); - /// Removes the given file from the cache - void removeFile(const std::string& fileName); + /// Removes the named stream from the cache + void removeStream(StreamType type, const std::string& fileName); - static std::string cacheFileName(const TileDesc& tile); + static std::string cacheFileName(const TileDesc& tileDesc); static bool parseCacheFileName(const std::string& fileName, int& part, int& width, int& height, int& tilePosX, int& tilePosY, int& tileWidth, int& tileHeight); /// Extract location from fileName, and check if it intersects with [x, y, width, height]. - static bool intersectsTile(const std::string& fileName, int part, int x, int y, int width, int height); + static bool intersectsTile(const TileDesc &tileDesc, int part, int x, int y, int width, int height); - void saveDataToCache(const std::string &fileName, const char *data, const size_t size); + void saveDataToCache(const TileDesc &desc, const char *data, const size_t size); + void saveDataToStreamCache(StreamType type, const std::string &fileName, const char *data, const size_t size); const std::string _docURL; std::thread::id _owner; bool _dontCache; - std::map<std::string, Tile> _cache; - std::map<std::string, std::shared_ptr<TileBeingRendered> > _tilesBeingRendered; + // FIXME: should we have a tile-desc to WID map instead and a simpler lookup ? + std::unordered_map<TileCacheDesc, Tile, + TileCacheDescHasher, + TileCacheDescCompareEqual> _cache; + // FIXME: TileBeingRendered contains TileDesc too ... + std::unordered_map<TileCacheDesc, std::shared_ptr<TileBeingRendered>, + TileCacheDescHasher, + TileCacheDescCompareEqual> _tilesBeingRendered; + + // old-style file-name to data grab-bag. + std::map<std::string, Tile> _streamCache[(int)StreamType::Last]; }; #endif diff --git a/wsd/TileDesc.hpp b/wsd/TileDesc.hpp index 3a68040c8..38e805d38 100644 --- a/wsd/TileDesc.hpp +++ b/wsd/TileDesc.hpp @@ -233,7 +233,7 @@ public: return tileID.str(); } -private: +protected: int _part; int _width; int _height; _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
