test/Makefile.am | 1 test/TileCacheTests.cpp | 2 wsd/DocumentBroker.cpp | 16 ++-- wsd/TileCache.cpp | 187 +++++++++++++++--------------------------------- wsd/TileCache.hpp | 23 ++--- 5 files changed, 82 insertions(+), 147 deletions(-)
New commits: commit 66ac62429c67a4fadca4f5481c76bdbb98361f0a Author: Michael Meeks <michael.me...@collabora.com> AuthorDate: Thu Feb 14 22:40:33 2019 +0100 Commit: Michael Meeks <michael.me...@collabora.com> CommitDate: Fri Feb 15 12:10:16 2019 +0100 TileCache: switch to in-memory, rather than persistent. Remove significant complexity; if we need it later lets do it more simply serializing when we start / finish a session. Turn off caching for mobile - possibly should kill for single-user too. Change-Id: I5ea56088ddbb61f22fe7920f8c9ac7440cb3296a diff --git a/test/Makefile.am b/test/Makefile.am index 7af9b467b..2683bce16 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -122,6 +122,7 @@ check-local: ./run_unit.sh --log-file test.log --trs-file test.trs # FIXME 2: unit-oob.la fails with symbol undefined: # UnitWSD::testHandleRequest(UnitWSD::TestRequest, UnitHTTPServerRequest&, UnitHTTPServerResponse&) , + TESTS = unit-typing.la unit-convert.la unit-prefork.la unit-tilecache.la \ unit-timeout.la unit-oauth.la unit-wopi.la unit-wopi-saveas.la \ unit-wopi-ownertermination.la unit-wopi-versionrestore.la \ diff --git a/test/TileCacheTests.cpp b/test/TileCacheTests.cpp index 982d0351c..c02989dee 100644 --- a/test/TileCacheTests.cpp +++ b/test/TileCacheTests.cpp @@ -183,7 +183,7 @@ void TileCacheTests::testSimple() // Create TileCache and pretend the file was modified as recently as // now, so it discards the cached data. - TileCache tc("doc.ods", Poco::Timestamp(), "/tmp/tile_cache_tests", true); + TileCache tc("doc.ods", Poco::Timestamp()); int part = 0; int width = 256; diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp index 3cce77e62..01a78b9b8 100644 --- a/wsd/DocumentBroker.cpp +++ b/wsd/DocumentBroker.cpp @@ -391,9 +391,8 @@ void DocumentBroker::pollThread() LOOLWSD::doHousekeeping(); #endif - // Remove all tiles related to this document from the cache if configured so. - if (_tileCache && !LOOLWSD::TileCachePersistent) - _tileCache->completeCleanup(); + if (_tileCache) + _tileCache->clear(); LOG_INF("Finished docBroker polling thread for docKey [" << _docKey << "]."); } @@ -727,7 +726,15 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s // Use the local temp file's timestamp. _lastFileModifiedTime = Poco::File(_storage->getRootFilePath()).getLastModified(); - _tileCache.reset(new TileCache(_storage->getUriString(), _lastFileModifiedTime, _cacheRoot, LOOLWSD::TileCachePersistent)); + + bool dontUseCache = false; +#if MOBILEAPP + // avoid memory consumption for single-user local bits. + // FIXME: arguably should/could do this for single user documents too. + dontUseCache = true; +#endif + + _tileCache.reset(new TileCache(_storage->getUriString(), _lastFileModifiedTime, dontUseCache)); _tileCache->setThreadOwner(std::this_thread::get_id()); } @@ -856,7 +863,6 @@ bool DocumentBroker::saveToStorageInternal(const std::string& sessionId, // Saved and stored; update flags. setModified(false); _lastFileModifiedTime = newFileModifiedTime; - _tileCache->saveLastModified(_lastFileModifiedTime); _lastSaveTime = std::chrono::steady_clock::now(); // Save the storage timestamp. diff --git a/wsd/TileCache.cpp b/wsd/TileCache.cpp index b709bde2c..e87fe9214 100644 --- a/wsd/TileCache.cpp +++ b/wsd/TileCache.cpp @@ -44,54 +44,18 @@ using Poco::File; using Poco::StringTokenizer; using Poco::Timestamp; -namespace { - TileCache::Tile loadTile(const std::string &fileName) - { - TileCache::Tile ret; - - std::unique_ptr<std::fstream> result(new std::fstream(fileName, std::ios::in)); - if (result && result->is_open()) - { - LOG_TRC("Found cache tile: " << fileName); - - result->seekg(0, std::ios_base::end); - std::streamsize size = result->tellg(); - ret = std::make_shared<std::vector<char>>(size); - result->seekg(0, std::ios_base::beg); - result->read(ret->data(), size); - result->close(); - } - return ret; - } -} - TileCache::TileCache(const std::string& docURL, const Timestamp& modifiedTime, - const std::string& cacheDir, - const bool tileCachePersistent) : + bool dontCache) : _docURL(docURL), - _cacheDir(cacheDir), - _tileCachePersistent(tileCachePersistent) + _dontCache(dontCache) { #ifndef BUILDING_TESTS LOG_INF("TileCache ctor for uri [" << LOOLWSD::anonymizeUrl(_docURL) << - "], cacheDir: [" << _cacheDir << "], modifiedTime=" << (modifiedTime.raw()/1000000) << - " getLastModified()=" << (getLastModified().raw()/1000000)); + "], dontCache=" << _dontCache); #endif - File directory(_cacheDir); - std::string unsaved; - if (directory.exists() && - (getLastModified() < modifiedTime || - getTextFile("unsaved.txt", unsaved))) - { - // Document changed externally or modifications were not saved after all. Cache not useful. - completeCleanup(); - } - - File(_cacheDir).createDirectories(); - - saveLastModified(modifiedTime); + (void)modifiedTime; } TileCache::~TileCache() @@ -102,10 +66,10 @@ TileCache::~TileCache() #endif } -void TileCache::completeCleanup() const +void TileCache::clear() { - FileUtil::removeFile(_cacheDir, true); - LOG_INF("Completely cleared tile cache: " << _cacheDir); + _cache.clear(); + LOG_INF("Completely cleared tile cache for: " << _docURL); } /// Tracks the rendering of a given tile @@ -187,10 +151,10 @@ int TileCache::getTileBeingRenderedVersion(const TileDesc& tile) TileCache::Tile TileCache::lookupTile(const TileDesc& tile) { - if (!_tileCachePersistent) - return nullptr; + if (_dontCache) + return TileCache::Tile(); - const std::string fileName = _cacheDir + "/" + cacheFileName(tile); + const std::string fileName = cacheFileName(tile); TileCache::Tile ret = loadTile(fileName); UnitWSD::get().lookupTile(tile.getPart(), tile.getWidth(), tile.getHeight(), @@ -200,6 +164,16 @@ 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(); @@ -212,11 +186,9 @@ void TileCache::saveTileAndNotify(const TileDesc& tile, const char *data, const // 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 = _cacheDir + "/" + cachedName; - if (_tileCachePersistent && FileUtil::saveDataToFileSafely(fileName, data, size)) - { - LOG_TRC("Saved cache tile: " << fileName); - } + const auto fileName = cachedName; + saveDataToCache(fileName, data, size); + LOG_TRC("Saved cache tile: " << fileName); // Notify subscribers, if any. if (tileBeingRendered) @@ -285,51 +257,31 @@ void TileCache::saveTileAndNotify(const TileDesc& tile, const char *data, const bool TileCache::getTextFile(const std::string& fileName, std::string& content) { - const std::string fullFileName = _cacheDir + "/" + fileName; - - std::fstream textStream(fullFileName, std::ios::in); - if (!textStream.is_open()) + Tile textStream = loadTile(fileName); + if (!textStream) { - LOG_INF("Could not open " << fullFileName); + LOG_INF("Could not open " << fileName); return false; } - std::vector<char> buffer; - textStream.seekg(0, std::ios_base::end); - std::streamsize size = textStream.tellg(); - buffer.resize(size); - textStream.seekg(0, std::ios_base::beg); - textStream.read(buffer.data(), size); - textStream.close(); + std::vector<char> buffer = *textStream; if (buffer.size() > 0 && buffer.back() == '\n') buffer.pop_back(); content = std::string(buffer.data(), buffer.size()); LOG_INF("Read '" << LOOLProtocol::getAbbreviatedMessage(content.c_str(), content.size()) << - "' from " << fullFileName); + "' from " << fileName); return true; } void TileCache::saveTextFile(const std::string& text, const std::string& fileName) { - const std::string fullFileName = _cacheDir + "/" + fileName; - std::fstream textStream(fullFileName, std::ios::out); + LOG_INF("Saving '" << LOOLProtocol::getAbbreviatedMessage(text.c_str(), text.size()) << + "' to " << fileName); - if (!textStream.is_open()) - { - LOG_ERR("Could not save '" << text << "' to " << fullFileName); - return; - } - else - { - LOG_INF("Saving '" << LOOLProtocol::getAbbreviatedMessage(text.c_str(), text.size()) << - "' to " << fullFileName); - } - - textStream << text << std::endl; - textStream.close(); + saveDataToCache(fileName, text.c_str(), text.size()); } void TileCache::setUnsavedChanges(bool state) @@ -343,25 +295,14 @@ void TileCache::setUnsavedChanges(bool state) void TileCache::saveRendering(const std::string& name, const std::string& dir, const char *data, std::size_t size) { // can fonts be invalidated? - const std::string dirName = _cacheDir + "/" + dir; - - File(dirName).createDirectories(); + const std::string fileName = dir + "/" + name; - const std::string fileName = dirName + "/" + name; - - FileUtil::saveDataToFileSafely(fileName, data, size); + saveDataToCache(fileName, data, size); } TileCache::Tile TileCache::lookupCachedTile(const std::string& name, const std::string& dir) { - const std::string dirName = _cacheDir + "/" + dir; - const std::string fileName = dirName + "/" + name; - File directory(dirName); - - if (directory.exists() && directory.isDirectory() && File(fileName).exists()) - return loadTile(fileName); - else - return Tile(); + return loadTile(dir + "/" + name); } void TileCache::invalidateTiles(int part, int x, int y, int width, int height) @@ -371,21 +312,18 @@ void TileCache::invalidateTiles(int part, int x, int y, int width, int height) ", width: " << width << ", height: " << height); - File dir(_cacheDir); - assertCorrectThread(); - if (dir.exists() && dir.isDirectory()) + for (auto it = _cache.begin(); it != _cache.end();) { - for (auto tileIterator = DirectoryIterator(dir); tileIterator != DirectoryIterator(); ++tileIterator) + const std::string fileName = it->first; + if (intersectsTile(fileName, part, x, y, width, height)) { - const std::string fileName = tileIterator.path().getFileName(); - if (intersectsTile(fileName, part, x, y, width, height)) - { - LOG_DBG("Removing tile: " << tileIterator.path().toString()); - FileUtil::removeFile(tileIterator.path()); - } + LOG_DBG("Removing tile: " << it->first); + it = _cache.erase(it); } + else + ++it; } } @@ -435,10 +373,12 @@ std::pair<int, Util::Rectangle> TileCache::parseInvalidateMsg(const std::string& void TileCache::removeFile(const std::string& fileName) { - const std::string fullFileName = _cacheDir + "/" + fileName; - - if (std::remove(fullFileName.c_str()) == 0) - LOG_INF("Removed file: " << fullFileName); + auto it = _cache.find(fileName); + if (it != _cache.end()) + { + LOG_INF("Removed file: " << fileName); + _cache.erase(it); + } } std::string TileCache::cacheFileName(const TileDesc& tile) @@ -475,27 +415,6 @@ bool TileCache::intersectsTile(const std::string& fileName, int part, int x, int return false; } -Timestamp TileCache::getLastModified() -{ - std::fstream modTimeFile(_cacheDir + "/modtime.txt", std::ios::in); - - if (!modTimeFile.is_open()) - return 0; - - Timestamp::TimeVal result; - modTimeFile >> result; - - modTimeFile.close(); - return result; -} - -void TileCache::saveLastModified(const Timestamp& timestamp) -{ - std::fstream modTimeFile(_cacheDir + "/modtime.txt", std::ios::out); - modTimeFile << timestamp.raw() << std::endl; - modTimeFile.close(); -} - // FIXME: to be further simplified when we centralize tile messages. void TileCache::subscribeToTileRendering(const TileDesc& tile, const std::shared_ptr<ClientSession>& subscriber) { @@ -628,4 +547,16 @@ void TileCache::assertCorrectThread() assert (correctThread); } +TileCache::Tile TileCache::loadTile(const std::string &fileName) +{ + auto it = _cache.find(fileName); + if (it != _cache.end()) + { + LOG_TRC("Found cache tile: " << fileName); + return it->second; + } + else + return TileCache::Tile(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/wsd/TileCache.hpp b/wsd/TileCache.hpp index 1a9ba0a26..9f847fc5d 100644 --- a/wsd/TileCache.hpp +++ b/wsd/TileCache.hpp @@ -36,11 +36,11 @@ public: /// When the docURL is a non-file:// url, the timestamp has to be provided by the caller. /// For file:// url's, it's ignored. /// When it is missing for non-file:// url, it is assumed the document must be read, and no cached value used. - TileCache(const std::string& docURL, const Poco::Timestamp& modifiedTime, const std::string& cacheDir, bool tileCachePersistent); + TileCache(const std::string& docURL, const Poco::Timestamp& modifiedTime, bool dontCache = false); ~TileCache(); - /// Remove the entire cache directory. - void completeCleanup() const; + /// Completely clear the cache contents. + void clear(); TileCache(const TileCache&) = delete; @@ -85,9 +85,6 @@ public: /// Parse invalidateTiles message to a part number and a rectangle of the invalidated area static std::pair<int, Util::Rectangle> parseInvalidateMsg(const std::string& tiles); - /// Store the timestamp to modtime.txt. - void saveLastModified(const Poco::Timestamp& timestamp); - void forgetTileBeingRendered(const std::shared_ptr<TileCache::TileBeingRendered>& tileBeingRendered, const TileDesc& tile); double getTileBeingRenderedElapsedTimeMs(const std::string& tileCacheName) const; @@ -102,7 +99,10 @@ public: private: void invalidateTiles(int part, int x, int y, int width, int height); - // Removes the given file from the cache + /// Lookup tile in our cache. + TileCache::Tile loadTile(const std::string &fileName); + + /// Removes the given file from the cache void removeFile(const std::string& fileName); static std::string cacheFileName(const TileDesc& tile); @@ -111,17 +111,14 @@ private: /// 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); - /// Load the timestamp from modtime.txt. - Poco::Timestamp getLastModified(); + void saveDataToCache(const std::string &fileName, const char *data, const size_t size); const std::string _docURL; - const std::string _cacheDir; - - const bool _tileCachePersistent; - std::thread::id _owner; + bool _dontCache; + std::map<std::string, Tile> _cache; std::map<std::string, std::shared_ptr<TileBeingRendered> > _tilesBeingRendered; }; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits