UI: AppInfoManager: Simplify old apps purging

This commit is contained in:
Nodir Temirkhodjaev 2024-08-22 12:48:47 +05:00
parent 5062bb0241
commit b730873383
4 changed files with 51 additions and 49 deletions

View File

@ -16,18 +16,15 @@ namespace {
const QLoggingCategory LC("appInfo"); const QLoggingCategory LC("appInfo");
constexpr int DATABASE_USER_VERSION = 6; constexpr int DATABASE_USER_VERSION = 7;
constexpr int APP_CACHE_MAX_COUNT = 2000; constexpr int APP_CACHE_MAX_COUNT = 3000;
constexpr int APP_PURGE_INTERVAL = 3000; // 3 seconds
const char *const sqlSelectAppInfo = "SELECT alt_path, file_descr, company_name," const char *const sqlSelectAppInfo = "SELECT alt_path, file_descr, company_name,"
" product_name, product_ver, file_mod_time, icon_id" " product_name, product_ver, file_mod_time, icon_id"
" FROM app WHERE path = ?1;"; " FROM app WHERE path = ?1;";
const char *const sqlUpdateAppAccessTime = "UPDATE app"
" SET access_time = datetime('now')"
" WHERE path = ?1;";
const char *const sqlSelectIconImage = "SELECT image FROM icon WHERE icon_id = ?1;"; const char *const sqlSelectIconImage = "SELECT image FROM icon WHERE icon_id = ?1;";
const char *const sqlSelectIconIdByHash = "SELECT icon_id FROM icon WHERE hash = ?1;"; const char *const sqlSelectIconIdByHash = "SELECT icon_id FROM icon WHERE hash = ?1;";
@ -40,15 +37,14 @@ const char *const sqlUpdateIconRefCount = "UPDATE icon"
" WHERE icon_id = ?1;"; " WHERE icon_id = ?1;";
const char *const sqlInsertAppInfo = "INSERT INTO app(path, alt_path, file_descr, company_name," const char *const sqlInsertAppInfo = "INSERT INTO app(path, alt_path, file_descr, company_name,"
" product_name, product_ver, file_mod_time," " product_name, product_ver, file_mod_time, icon_id)"
" icon_id, access_time)" " VALUES(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8);";
" VALUES(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, datetime('now'));";
const char *const sqlSelectAppCount = "SELECT count(*) FROM app;"; const char *const sqlSelectAppCount = "SELECT count(*) FROM app;";
const char *const sqlSelectAppOlds = "SELECT path, icon_id" const char *const sqlSelectOldApps = "SELECT path, icon_id"
" FROM app" " FROM app"
" ORDER BY access_time DESC" " ORDER BY app_id"
" LIMIT ?1;"; " LIMIT ?1;";
const char *const sqlDeleteIconIfNotUsed = "DELETE FROM icon" const char *const sqlDeleteIconIfNotUsed = "DELETE FROM icon"
@ -59,9 +55,13 @@ const char *const sqlDeleteApp = "DELETE FROM app WHERE path = ?1;";
} }
AppInfoManager::AppInfoManager(const QString &filePath, QObject *parent, quint32 openFlags) : AppInfoManager::AppInfoManager(const QString &filePath, QObject *parent, quint32 openFlags) :
WorkerManager(parent), m_sqliteDb(new SqliteDb(filePath, openFlags)) WorkerManager(parent),
m_appsPurgeTimer(APP_PURGE_INTERVAL),
m_sqliteDb(new SqliteDb(filePath, openFlags))
{ {
setMaxWorkersCount(1); setMaxWorkersCount(1);
connect(&m_appsPurgeTimer, &QTimer::timeout, this, &AppInfoManager::purgeApps);
} }
void AppInfoManager::setUp() void AppInfoManager::setUp()
@ -127,17 +127,9 @@ bool AppInfoManager::loadInfoFromDb(const QString &appPath, AppInfo &appInfo)
appInfo.fileModTime = stmt.columnDateTime(5); appInfo.fileModTime = stmt.columnDateTime(5);
appInfo.iconId = stmt.columnInt64(6); appInfo.iconId = stmt.columnInt64(6);
// Update last access time
updateAppAccessTime(appPath);
return true; return true;
} }
void AppInfoManager::updateAppAccessTime(const QString &appPath)
{
DbQuery(sqliteDb()).sql(sqlUpdateAppAccessTime).vars({ appPath }).executeOk();
}
bool AppInfoManager::setupDb() bool AppInfoManager::setupDb()
{ {
if (!sqliteDb()->open()) { if (!sqliteDb()->open()) {
@ -196,14 +188,25 @@ void AppInfoManager::saveAppInfo(
DbQuery(sqliteDb(), &ok).sql(sqlInsertAppInfo).vars(vars).executeOk(); DbQuery(sqliteDb(), &ok).sql(sqlInsertAppInfo).vars(vars).executeOk();
} }
void AppInfoManager::deleteExcessAppInfos() void AppInfoManager::emitAppsPurge()
{ {
QMetaObject::invokeMethod(&m_appsPurgeTimer, &TriggerTimer::startTrigger, Qt::QueuedConnection);
}
void AppInfoManager::purgeApps()
{
QMutexLocker locker(&m_mutex);
sqliteDb()->beginWriteTransaction();
const int appCount = DbQuery(sqliteDb()).sql(sqlSelectAppCount).execute().toInt(); const int appCount = DbQuery(sqliteDb()).sql(sqlSelectAppCount).execute().toInt();
const int excessCount = appCount - APP_CACHE_MAX_COUNT; const int excessCount = appCount - APP_CACHE_MAX_COUNT;
if (excessCount > 0) { if (excessCount > 0) {
deleteOldApps(excessCount); deleteOldApps(excessCount);
} }
sqliteDb()->commitTransaction();
} }
QImage AppInfoManager::loadIconFromDb(qint64 iconId) QImage AppInfoManager::loadIconFromDb(qint64 iconId)
@ -240,8 +243,8 @@ bool AppInfoManager::saveToDb(const QString &appPath, AppInfo &appInfo, const QI
if (ok) { if (ok) {
appInfo.iconId = iconId.toLongLong(); appInfo.iconId = iconId.toLongLong();
// Delete excess info // Delete excess infos later
deleteExcessAppInfos(); emitAppsPurge();
} }
return ok; return ok;
@ -258,9 +261,16 @@ void AppInfoManager::deleteAppInfo(const QString &appPath, const AppInfo &appInf
iconIds.insert(appInfo.iconId, 1); iconIds.insert(appInfo.iconId, 1);
} }
QMutexLocker locker(&m_mutex); // Delete app info & icon
{
QMutexLocker locker(&m_mutex);
deleteAppsAndIcons(appPaths, iconIds); sqliteDb()->beginWriteTransaction();
deleteAppsAndIcons(appPaths, iconIds);
sqliteDb()->commitTransaction();
}
} }
void AppInfoManager::deleteOldApps(int limitCount) void AppInfoManager::deleteOldApps(int limitCount)
@ -281,12 +291,10 @@ void AppInfoManager::getOldAppsAndIcons(
QStringList &appPaths, QHash<qint64, int> &iconIds, int limitCount) const QStringList &appPaths, QHash<qint64, int> &iconIds, int limitCount) const
{ {
SqliteStmt stmt; SqliteStmt stmt;
if (!stmt.prepare(sqliteDb()->db(), sqlSelectAppOlds, SqliteStmt::PreparePersistent)) if (!stmt.prepare(sqliteDb()->db(), sqlSelectOldApps, SqliteStmt::PreparePersistent))
return; return;
if (limitCount != 0) { stmt.bindInt(1, limitCount);
stmt.bindInt(1, limitCount);
}
while (stmt.step() == SqliteStmt::StepRow) { while (stmt.step() == SqliteStmt::StepRow) {
const QString appPath = stmt.columnText(0); const QString appPath = stmt.columnText(0);
@ -298,13 +306,11 @@ void AppInfoManager::getOldAppsAndIcons(
} }
} }
bool AppInfoManager::deleteAppsAndIcons( void AppInfoManager::deleteAppsAndIcons(
const QStringList &appPaths, const QHash<qint64, int> &iconIds) const QStringList &appPaths, const QHash<qint64, int> &iconIds)
{ {
bool ok = false; bool ok = false;
sqliteDb()->beginWriteTransaction();
// Delete old icons // Delete old icons
deleteIcons(iconIds, ok); deleteIcons(iconIds, ok);
@ -312,10 +318,6 @@ bool AppInfoManager::deleteAppsAndIcons(
if (ok) { if (ok) {
deleteApps(appPaths, ok); deleteApps(appPaths, ok);
} }
sqliteDb()->endTransaction(ok);
return ok;
} }
void AppInfoManager::deleteIcons(const QHash<qint64, int> &iconIds, bool &ok) void AppInfoManager::deleteIcons(const QHash<qint64, int> &iconIds, bool &ok)

View File

@ -2,11 +2,13 @@
#define APPINFOMANAGER_H #define APPINFOMANAGER_H
#include <QMutex> #include <QMutex>
#include <QVector>
#include <sqlite/sqlite_types.h> #include <sqlite/sqlite_types.h>
#include <util/classhelpers.h> #include <util/classhelpers.h>
#include <util/ioc/iocservice.h> #include <util/ioc/iocservice.h>
#include <util/triggertimer.h>
#include <util/worker/workermanager.h> #include <util/worker/workermanager.h>
#include "appinfo.h" #include "appinfo.h"
@ -33,7 +35,7 @@ public:
bool saveToDb(const QString &appPath, AppInfo &appInfo, const QImage &appIcon); bool saveToDb(const QString &appPath, AppInfo &appInfo, const QImage &appIcon);
void deleteAppInfo(const QString &appPath, const AppInfo &appInfo); void deleteAppInfo(const QString &appPath, const AppInfo &appInfo);
void deleteOldApps(int limitCount = 0); void deleteOldApps(int limitCount);
signals: signals:
void lookupInfoFinished(const QString &appPath, const AppInfo &appInfo); void lookupInfoFinished(const QString &appPath, const AppInfo &appInfo);
@ -48,8 +50,6 @@ public slots:
protected: protected:
WorkerObject *createWorker() override; WorkerObject *createWorker() override;
virtual void updateAppAccessTime(const QString &appPath);
private: private:
bool setupDb(); bool setupDb();
@ -57,11 +57,12 @@ private:
void saveAppInfo( void saveAppInfo(
const QString &appPath, const AppInfo &appInfo, const QVariant &iconId, bool &ok); const QString &appPath, const AppInfo &appInfo, const QVariant &iconId, bool &ok);
void deleteExcessAppInfos(); void emitAppsPurge();
void purgeApps();
void getOldAppsAndIcons( void getOldAppsAndIcons(
QStringList &appPaths, QHash<qint64, int> &iconIds, int limitCount) const; QStringList &appPaths, QHash<qint64, int> &iconIds, int limitCount) const;
bool deleteAppsAndIcons(const QStringList &appPaths, const QHash<qint64, int> &iconIds); void deleteAppsAndIcons(const QStringList &appPaths, const QHash<qint64, int> &iconIds);
void deleteIcons(const QHash<qint64, int> &iconIds, bool &ok); void deleteIcons(const QHash<qint64, int> &iconIds, bool &ok);
void deleteIcon(qint64 iconId, int deleteCount, bool &ok); void deleteIcon(qint64 iconId, int deleteCount, bool &ok);
@ -70,6 +71,8 @@ private:
void deleteApp(const QString &appPath, bool &ok); void deleteApp(const QString &appPath, bool &ok);
private: private:
TriggerTimer m_appsPurgeTimer;
SqliteDbPtr m_sqliteDb; SqliteDbPtr m_sqliteDb;
QMutex m_mutex; QMutex m_mutex;
}; };

View File

@ -1,16 +1,16 @@
CREATE TABLE app( CREATE TABLE app(
path TEXT PRIMARY KEY, app_id INTEGER PRIMARY KEY,
path TEXT NOT NULL,
alt_path TEXT, alt_path TEXT,
file_descr TEXT, file_descr TEXT,
company_name TEXT, company_name TEXT,
product_name TEXT, product_name TEXT,
product_ver TEXT, product_ver TEXT,
file_mod_time INTEGER, file_mod_time INTEGER,
icon_id INTEGER, icon_id INTEGER
access_time DATETIME );
) WITHOUT ROWID;
CREATE INDEX app_access_time_idx ON app(access_time); CREATE UNIQUE INDEX app_path_uk ON app(path);
CREATE TABLE icon( CREATE TABLE icon(
icon_id INTEGER PRIMARY KEY, icon_id INTEGER PRIMARY KEY,

View File

@ -21,9 +21,6 @@ public:
public slots: public slots:
void lookupAppInfo(const QString &appPath) override; void lookupAppInfo(const QString &appPath) override;
protected:
void updateAppAccessTime(const QString & /*appPath*/) override { }
}; };
#endif // APPINFOMANAGERRPC_H #endif // APPINFOMANAGERRPC_H