From ae3f81a0c3da9aaaca50d3c733a5e8ce73761704 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 21 Mar 2019 23:36:18 +0100 Subject: [PATCH] created a cache for default icons to avoid allocating them everytime we need them. Should save a lot of memory --- retroshare-gui/src/gui/gxs/GxsIdDetails.cpp | 51 ++++++++++++++++++++- retroshare-gui/src/gui/gxs/GxsIdDetails.h | 7 ++- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp index 6168090eb..98f331730 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp @@ -64,6 +64,12 @@ //const int kRecognTagType_Dev_Patcher = 4; //const int kRecognTagType_Dev_Developer = 5; +uint32_t GxsIdDetails::mImagesAllocated = 0; +time_t GxsIdDetails::mLastIconCacheCleaning = time(NULL); +std::map > GxsIdDetails::mDefaultIconCache ; + +#define ICON_CACHE_STORAGE_TIME 600 +#define DELAY_BETWEEN_ICON_CACHE_CLEANING 300 void ReputationItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { @@ -450,9 +456,50 @@ static bool findTagIcon(int tag_class, int /*tag_type*/, QIcon &icon) * Bring the source code from this adaptation: * http://francisshanahan.com/identicon5/test.html */ -QImage GxsIdDetails::makeDefaultIcon(const RsGxsId& id) +const QImage& GxsIdDetails::makeDefaultIcon(const RsGxsId& id) { - return drawIdentIcon(QString::fromStdString(id.toStdString()),64*3, true); + // We use a cache for images. QImage has its own smart pointer system, but it does not prevent + // the same image to be allocated many times. We do this using a cache. The cache is also cleaned-up + // on a regular time basis so as to get rid of unused images. + + time_t now = time(NULL); + + // cleanup the cache every 10 mins + + if(mLastIconCacheCleaning + DELAY_BETWEEN_ICON_CACHE_CLEANING < now) + { + std::cerr << "(II) Cleaning the icons cache." << std::endl; + int nb_deleted = 0; + + for(auto it(mDefaultIconCache.begin());it!=mDefaultIconCache.end();) + if(it->second.first + ICON_CACHE_STORAGE_TIME < now) + { + it = mDefaultIconCache.erase(it); + ++nb_deleted; + } + else + ++it; + + mLastIconCacheCleaning = now; + std::cerr << "(II) Removed " << nb_deleted << " unused icons. Cache contains " << mDefaultIconCache.size() << " icons"<< std::endl; + } + + // now look for the icon + + auto it = mDefaultIconCache.find(id); + + if(it != mDefaultIconCache.end()) + { + it->second.first = now; + return it->second.second; + } + + QImage image = drawIdentIcon(QString::fromStdString(id.toStdString()),64*3, true); + + mDefaultIconCache[id] = std::make_pair(now,image); + it = mDefaultIconCache.find(id); + + return it->second.second; } /** diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.h b/retroshare-gui/src/gui/gxs/GxsIdDetails.h index 8c6c8edac..e506f5cf3 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdDetails.h +++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.h @@ -101,7 +101,7 @@ public: static void GenerateCombinedPixmap(QPixmap &pixmap, const QList &icons, int iconSize); //static QImage makeDefaultIcon(const RsGxsId& id); - static QImage makeDefaultIcon(const RsGxsId& id); + static const QImage& makeDefaultIcon(const RsGxsId& id); /* Processing */ static void enableProcess(bool enable); @@ -155,6 +155,11 @@ protected: /* Pending data */ QMap mPendingData; QMap::iterator mPendingDataIterator; + + static uint32_t mImagesAllocated; + static std::map > mDefaultIconCache; + static time_t mLastIconCacheCleaning; + int mCheckTimerId; int mProcessDisableCount;