aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2018-05-16 12:02:40 +0200
committerdec05eba <dec05eba@protonmail.com>2018-05-16 12:02:43 +0200
commit33f2c2b1d29731f890d3835032d911610e4fc69d (patch)
treecbf0cd857954d852022d97a68f3c8e3b4f9bbe46
parente1dbec0b78671a4e90e578a2ab67b7b114d3b57b (diff)
Unload content if it's not visible on the screen for a while
m---------depends/odhtdb0
-rw-r--r--include/Cache.hpp4
-rw-r--r--src/Cache.cpp51
-rw-r--r--src/main.cpp2
4 files changed, 55 insertions, 2 deletions
diff --git a/depends/odhtdb b/depends/odhtdb
-Subproject 05920c5c5ffcedc435eeee29f6357c6b4fdc9c4
+Subproject 306579df31826dcb934dea6eabb88a856a707f7
diff --git a/include/Cache.hpp b/include/Cache.hpp
index 311658b..fc702a7 100644
--- a/include/Cache.hpp
+++ b/include/Cache.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include "types.hpp"
#include <boost/filesystem/path.hpp>
#include <SFML/Graphics/Texture.hpp>
#include <string>
@@ -7,6 +8,7 @@
#include <thread>
#include <mutex>
#include <vector>
+#include <chrono>
namespace TinyProcessLib
{
@@ -50,6 +52,7 @@ namespace dchat
Type type;
CachedType cachedType;
+ i64 lastAccessed;
};
class Cache
@@ -79,6 +82,7 @@ namespace dchat
};
std::thread downloadWaitThread;
+ std::thread checkContentAccessTimeThread;
std::vector<ImageDownloadInfo> imageDownloadProcesses;
std::vector<ImageDownloadInfo> imageDownloadProcessesQueue;
std::mutex imageDownloadMutex;
diff --git a/src/Cache.cpp b/src/Cache.cpp
index 1295475..15af6e7 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -24,9 +24,10 @@ using namespace TinyProcessLib;
namespace dchat
{
- unordered_map<string, ContentByUrlResult> contentUrlCache;
+ static unordered_map<string, ContentByUrlResult> contentUrlCache;
+ const i64 CONTENT_NOT_VISIBLE_AGE_MS = 20000; // Delete content from cache after a specified amount of time if the content is not visible on the screen
- boost::filesystem::path getHomeDir()
+ static boost::filesystem::path getHomeDir()
{
#if OS_FAMILY == OS_FAMILY_POSIX
const char *homeDir = getenv("HOME");
@@ -209,6 +210,7 @@ namespace dchat
else
{
contentByUrlResult = loadImageFromFile(filepath);
+ contentByUrlResult.lastAccessed = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now().time_since_epoch()).count();
if(contentByUrlResult.type == ContentByUrlResult::Type::CACHED)
{
printf("Download content from url: %s\n", it->url.c_str());
@@ -246,12 +248,53 @@ namespace dchat
this_thread::sleep_for(chrono::milliseconds(20));
}
});
+
+ checkContentAccessTimeThread = thread([this]
+ {
+ while(alive)
+ {
+ this_thread::sleep_for(chrono::milliseconds(500));
+ lock_guard<mutex> lock(imageDownloadMutex);
+
+ i64 now = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now().time_since_epoch()).count();
+ for(unordered_map<string, ContentByUrlResult>::iterator it = contentUrlCache.begin(); it != contentUrlCache.end();)
+ {
+ if(it->second.type == ContentByUrlResult::Type::CACHED && now - it->second.lastAccessed > CONTENT_NOT_VISIBLE_AGE_MS)
+ {
+ switch(it->second.cachedType)
+ {
+ case ContentByUrlResult::CachedType::TEXTURE:
+ {
+ delete it->second.texture;
+ break;
+ }
+ case ContentByUrlResult::CachedType::GIF:
+ {
+ delete it->second.gif;
+ break;
+ }
+ case ContentByUrlResult::CachedType::WEB_PAGE_PREVIEW:
+ {
+ delete it->second.webPagePreview;
+ break;
+ }
+ default:
+ break;
+ }
+ it = contentUrlCache.erase(it);
+ }
+ else
+ ++it;
+ }
+ }
+ });
}
Cache::~Cache()
{
alive = false;
downloadWaitThread.join();
+ checkContentAccessTimeThread.join();
}
void replaceFileIgnoreError(const boost::filesystem::path &path)
@@ -271,7 +314,10 @@ namespace dchat
lock_guard<mutex> lock(imageDownloadMutex);
auto it = contentUrlCache.find(url);
if(it != contentUrlCache.end())
+ {
+ it->second.lastAccessed = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now().time_since_epoch()).count();
return it->second;
+ }
// TODO: Verify hashed url is not too long for filepath on windows
boost::filesystem::path filepath = getImagesDir();
@@ -292,6 +338,7 @@ namespace dchat
ContentByUrlResult contentByUrlResult = loadImageFromFile(filepath);
if(contentByUrlResult.type == ContentByUrlResult::Type::CACHED)
{
+ contentByUrlResult.lastAccessed = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now().time_since_epoch()).count();
contentUrlCache[url] = contentByUrlResult;
printf("Loaded content from file cache: %s\n", url.c_str());
return contentByUrlResult;
diff --git a/src/main.cpp b/src/main.cpp
index 39ccd43..56c38a6 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -138,6 +138,7 @@ int main(int argc, char **argv)
callbackFuncs.createNodeCallbackFunc = [&waitingToJoinChannels, &database, &channels, &channelMessageMutex, &waitingToJoin, &localNodeUsers](const odhtdb::DatabaseCreateNodeRequest &request)
{
lock_guard<recursive_mutex> lock(channelMessageMutex);
+ //printf("Create node callback func %s\n", request.nodeHash->toString().c_str());
auto nodeUserData = localNodeUsers.find(*request.nodeHash);
if(nodeUserData == localNodeUsers.end()) return;
@@ -176,6 +177,7 @@ int main(int argc, char **argv)
callbackFuncs.addNodeCallbackFunc = [&channels, &channelMessageMutex](const odhtdb::DatabaseAddNodeRequest &request)
{
lock_guard<recursive_mutex> lock(channelMessageMutex);
+ //printf("Add node callback func %s\n", request.requestHash->toString().c_str());
for(Channel *channel : channels)
{
if(*request.nodeHash == *channel->getNodeInfo().getRequestHash())