Further hacking on tile cache

This commit is contained in:
Tor Lillqvist 2015-03-13 01:34:42 +02:00
parent 79a4eff2cf
commit ad3fda27af
5 changed files with 108 additions and 33 deletions

View file

@ -80,6 +80,11 @@ bool LOOLSession::handleInput(char *buffer, int length)
return true;
}
bool LOOLSession::haveSeparateProcess() const
{
return _haveSeparateProcess;
}
void LOOLSession::sendTextFrame(std::string text)
{
_ws.sendFrame(text.data(), text.size());
@ -123,11 +128,14 @@ void LOOLSession::loadDocument(StringTokenizer& tokens)
sendTextFrame("error: cmd=load kind=syntax");
return;
}
if ((_loKitDocument = _loKit->pClass->documentLoad(_loKit, tokens[1].c_str())) != NULL)
_docURL = tokens[1];
_tileCache.reset(new TileCache(_docURL));
if ((_loKitDocument = _loKit->pClass->documentLoad(_loKit, _docURL.c_str())) != NULL)
{
sendTextFrame(getStatus());
_loKitDocument->pClass->registerCallback(_loKitDocument, myCallback, this);
_docURL = tokens[1];
}
}
@ -229,9 +237,10 @@ void LOOLSession::sendTile(StringTokenizer& tokens)
output.resize(response.size());
memcpy(output.data(), response.data(), response.size());
std::unique_ptr<std::fstream> cachedTile = TileCache::lookup(_docURL, width, height, tilePosX, tilePosY, tileWidth, tileHeight);
if (cachedTile->is_open())
std::unique_ptr<std::fstream> cachedTile = _tileCache->lookup(width, height, tilePosX, tilePosY, tileWidth, tileHeight);
if (cachedTile && cachedTile->is_open())
{
std::cout << "Found in cache!" << std::endl;
cachedTile->seekg(0, std::ios_base::end);
size_t pos = output.size();
std::streamsize size = cachedTile->tellg();
@ -276,9 +285,13 @@ void LOOLSession::sendTile(StringTokenizer& tokens)
delete[] buffer;
TileCache::save(_docURL, width, height, tilePosX, tilePosY, tileWidth, tileHeight, output.data() + response.size(), output.size() - response.size());
_tileCache->save(width, height, tilePosX, tilePosY, tileWidth, tileHeight, output.data() + response.size(), output.size() - response.size());
sendBinaryFrame(output.data(), output.size());
}
void LOOLSession::forkOff()
{
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View file

@ -19,17 +19,27 @@
#include <Poco/Net/WebSocket.h>
#include <Poco/StringTokenizer.h>
struct LOOLSession
#include "TileCache.hpp"
class LOOLSession
{
public:
LOOLSession(Poco::Net::WebSocket& ws, LibreOfficeKit *loKit);
~LOOLSession();
bool handleInput(char *buffer, int length);
bool haveSeparateProcess() const;
void sendTextFrame(std::string text);
void sendBinaryFrame(const char *buffer, int length);
private:
void loadDocument(Poco::StringTokenizer& tokens);
std::string getStatus();
void sendTile(Poco::StringTokenizer& tokens);
void forkOff();
bool _haveSeparateProcess;
pid_t _pid;
int _pipe;
@ -39,6 +49,8 @@ struct LOOLSession
Poco::Net::WebSocket& _ws;
LibreOfficeKit *_loKit;
LibreOfficeKitDocument *_loKitDocument;
std::unique_ptr<TileCache> _tileCache;
};
#endif

View file

@ -120,8 +120,8 @@ public:
if (!session.handleInput(buffer, n))
n = 0;
}
while (n > 0 && !session._haveSeparateProcess && (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);
if (session._haveSeparateProcess)
while (n > 0 && !session.haveSeparateProcess() && (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);
if (session.haveSeparateProcess())
{
// TODO: is this the right thing to do?
ws.close();

View file

@ -19,43 +19,81 @@
#include "TileCache.hpp"
namespace {
std::string cacheFileName(const std::string& docURL, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight)
TileCache::TileCache(const std::string& docURL) :
_docURL(docURL)
{
Poco::File dir(cacheDirName());
// TODO: get last modified time of docURL if it *is* some kind of URL and not a local file
if (dir.exists() && dir.isDirectory() && Poco::File(_docURL).exists() && Poco::File(_docURL).isFile())
{
Poco::SHA1Engine digestEngine;
digestEngine.update(docURL.c_str(), docURL.size());
digestEngine.update(std::to_string(width));
digestEngine.update(std::to_string(height));
digestEngine.update(std::to_string(tilePosX));
digestEngine.update(std::to_string(tilePosY));
digestEngine.update(std::to_string(tileWidth));
digestEngine.update(std::to_string(tileHeight));
std::string digest = Poco::DigestEngine::digestToHex(digestEngine.digest()).insert(3, "/").insert(2, "/").insert(1, "/");
return LOOLWSD_CACHEDIR "/" + digest + ".png";
if (getLastModified() != Poco::File(_docURL).getLastModified())
{
dir.remove(true);
}
}
}
std::unique_ptr<std::fstream> TileCache::lookup(const std::string& docURL, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight)
std::unique_ptr<std::fstream> TileCache::lookup(int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight)
{
std::string file = cacheFileName(docURL, width, height, tilePosX, tilePosY, tileWidth, tileHeight);
std::string dirName = cacheDirName();
std::unique_ptr<std::fstream> result(new std::fstream(file, std::ios::in));
if (!Poco::File(dirName).exists() || !Poco::File(dirName).isDirectory())
return nullptr;
std::string fileName = dirName + "/" + cacheFileName(width, height, tilePosX, tilePosY, tileWidth, tileHeight);
std::unique_ptr<std::fstream> result(new std::fstream(fileName, std::ios::in));
return result;
}
void TileCache::save(const std::string& docURL, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, const char *data, size_t size)
void TileCache::save(int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, const char *data, size_t size)
{
std::string file = cacheFileName(docURL, width, height, tilePosX, tilePosY, tileWidth, tileHeight);
std::string dirName = cacheDirName();
std::string fileName = dirName + "/" + cacheFileName(width, height, tilePosX, tilePosY, tileWidth, tileHeight);
Poco::File(Poco::Path(file).makeFile().makeParent()).createDirectories();
Poco::File(dirName).createDirectories();
std::fstream outStream(file, std::ios::out);
std::fstream outStream(fileName, std::ios::out);
outStream.write(data, size);
outStream.close();
std::fstream modTimeFile(dirName + "/modtime.txt", std::ios::out);
modTimeFile << Poco::File(_docURL).getLastModified().raw() << std::endl;
modTimeFile.close();
}
std::string TileCache::cacheDirName()
{
Poco::SHA1Engine digestEngine;
digestEngine.update(_docURL.c_str(), _docURL.size());
return (LOOLWSD_CACHEDIR "/" +
Poco::DigestEngine::digestToHex(digestEngine.digest()).insert(3, "/").insert(2, "/").insert(1, "/"));
}
std::string TileCache::cacheFileName(int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight)
{
return (std::to_string(width) + "x" + std::to_string(height) + "." +
std::to_string(tilePosX) + "," + std::to_string(tilePosY) + "." +
std::to_string(tileWidth) + "x" + std::to_string(tileHeight) + ".png");
}
Poco::Timestamp TileCache::getLastModified()
{
std::fstream modTimeFile(cacheDirName() + "/modtime.txt", std::ios::in);
if (!modTimeFile.is_open())
return 0;
Poco::Timestamp::TimeVal result;
modTimeFile >> result;
modTimeFile.close();
return result;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View file

@ -13,10 +13,22 @@
#include <fstream>
#include <memory>
struct TileCache
#include <Poco/Timestamp.h>
class TileCache
{
static std::unique_ptr<std::fstream> lookup(const std::string& docURL, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight);
static void save(const std::string& docURL, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, const char *data, size_t size);
public:
TileCache(const std::string& docURL);
std::unique_ptr<std::fstream> lookup(int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight);
void save(int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, const char *data, size_t size);
private:
std::string cacheDirName();
std::string cacheFileName(int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight);
Poco::Timestamp getLastModified();
const std::string& _docURL;
};
#endif