From 33f2c2b1d29731f890d3835032d911610e4fc69d Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 16 May 2018 12:02:40 +0200 Subject: Unload content if it's not visible on the screen for a while --- src/Cache.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/main.cpp | 2 ++ 2 files changed, 51 insertions(+), 2 deletions(-) (limited to 'src') 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 contentUrlCache; + static unordered_map 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::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 lock(imageDownloadMutex); + + i64 now = chrono::duration_cast(chrono::steady_clock::now().time_since_epoch()).count(); + for(unordered_map::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 lock(imageDownloadMutex); auto it = contentUrlCache.find(url); if(it != contentUrlCache.end()) + { + it->second.lastAccessed = chrono::duration_cast(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::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 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 lock(channelMessageMutex); + //printf("Add node callback func %s\n", request.requestHash->toString().c_str()); for(Channel *channel : channels) { if(*request.nodeHash == *channel->getNodeInfo().getRequestHash()) -- cgit v1.2.3