[Libreoffice-commits] online.git: test/Makefile.am test/TileCacheTests.cpp wsd/DocumentBroker.cpp wsd/TileCache.cpp wsd/TileCache.hpp
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Fri Feb 15 11:42:32 UTC 2019
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.meeks at collabora.com>
AuthorDate: Thu Feb 14 22:40:33 2019 +0100
Commit: Michael Meeks <michael.meeks at 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;
};
More information about the Libreoffice-commits
mailing list