Further hacking on tile cache
This commit is contained in:
parent
79a4eff2cf
commit
ad3fda27af
5 changed files with 108 additions and 33 deletions
|
@ -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: */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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: */
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue