Skip to content

Commit

Permalink
Packages (Linux): cache result based on mtime
Browse files Browse the repository at this point in the history
  • Loading branch information
CarterLi committed Sep 13, 2024
1 parent 7bbaca2 commit 03c901b
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 10 deletions.
44 changes: 44 additions & 0 deletions src/detection/packages/packages.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
#include "packages.h"
#include "common/io/io.h"

#include <inttypes.h>
#include <stddef.h>

#ifdef __APPLE__
#define st_mtim st_mtimespec
#endif

void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options);

const char* ffDetectPackages(FFPackagesResult* result, FFPackagesOptions* options)
Expand All @@ -16,3 +22,41 @@ const char* ffDetectPackages(FFPackagesResult* result, FFPackagesOptions* option

return NULL;
}

bool ffPackagesReadCache(FFstrbuf* cacheDir, FFstrbuf* cacheContent, const char* filePath, const char* packageId, uint32_t* result)
{
struct stat st;
if (stat(filePath, &st) < 0) // file doesn't exist or isn't accessable
{
*result = 0;
return true;
}

uint64_t mtime_current = (uint64_t) st.st_mtim.tv_sec * 1000 + (uint64_t) st.st_mtim.tv_nsec / 1000000;

ffStrbufSet(cacheDir, &instance.state.platform.cacheDir);
ffStrbufEnsureEndsWithC(cacheDir, '/');
ffStrbufAppendF(cacheDir, "fastfetch/packages/%s.txt", packageId);

if (ffReadFileBuffer(cacheDir->chars, cacheContent))
{
uint64_t mtime_cached;
uint32_t num_cached;
if (sscanf(cacheContent->chars, "%" SCNu64 " %" SCNu32, &mtime_cached, &num_cached) == 2 &&
mtime_cached == mtime_current && num_cached > 0)
{
*result = num_cached;
return true;
}
}

ffStrbufSetF(cacheContent, "%" PRIu64 " ", mtime_current);

return false;
}

bool ffPackagesWriteCache(FFstrbuf* cacheDir, FFstrbuf* cacheContent, uint32_t num_elements)
{
ffStrbufAppendF(cacheContent, "%" PRIu32, num_elements);
return ffWriteFileBuffer(cacheDir->chars, cacheContent);
}
2 changes: 2 additions & 0 deletions src/detection/packages/packages.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,5 @@ typedef struct FFPackagesResult
} FFPackagesResult;

const char* ffDetectPackages(FFPackagesResult* result, FFPackagesOptions* options);
bool ffPackagesReadCache(FFstrbuf* cacheDir, FFstrbuf* cacheContent, const char* filePath, const char* packageId, uint32_t* result);
bool ffPackagesWriteCache(FFstrbuf* cacheDir, FFstrbuf* cacheContent, uint32_t num_elements);
48 changes: 38 additions & 10 deletions src/detection/packages/packages_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,49 @@ static uint32_t getNumStringsImpl(const char* filename, const char* needle)
return count;
}

static uint32_t getNumStrings(FFstrbuf* baseDir, const char* filename, const char* needle)
static uint32_t getNumStrings(FFstrbuf* baseDir, const char* filename, const char* needle, const char* packageId)
{
uint32_t baseDirLength = baseDir->length;
ffStrbufAppendS(baseDir, filename);
uint32_t num_elements = getNumStringsImpl(baseDir->chars, needle);

FF_STRBUF_AUTO_DESTROY cacheDir = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY cacheContent = ffStrbufCreate();

uint32_t num_elements;
if (ffPackagesReadCache(&cacheDir, &cacheContent, baseDir->chars, packageId, &num_elements))
{
ffStrbufSubstrBefore(baseDir, baseDirLength);
return num_elements;
}

num_elements = getNumStringsImpl(baseDir->chars, needle);
ffStrbufSubstrBefore(baseDir, baseDirLength);

ffPackagesWriteCache(&cacheDir, &cacheContent, num_elements);

return num_elements;
}

static uint32_t getSQLite3Int(FFstrbuf* baseDir, const char* dbPath, const char* query)
static uint32_t getSQLite3Int(FFstrbuf* baseDir, const char* dbPath, const char* query, const char* packageId)
{
uint32_t baseDirLength = baseDir->length;
ffStrbufAppendS(baseDir, dbPath);
uint32_t num_elements = (uint32_t) ffSettingsGetSQLite3Int(baseDir->chars, query);

FF_STRBUF_AUTO_DESTROY cacheDir = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY cacheContent = ffStrbufCreate();

uint32_t num_elements;
if (ffPackagesReadCache(&cacheDir, &cacheContent, baseDir->chars, packageId, &num_elements))
{
ffStrbufSubstrBefore(baseDir, baseDirLength);
return num_elements;
}

num_elements = (uint32_t) ffSettingsGetSQLite3Int(baseDir->chars, query);
ffStrbufSubstrBefore(baseDir, baseDirLength);

ffPackagesWriteCache(&cacheDir, &cacheContent, num_elements);

return num_elements;
}

Expand Down Expand Up @@ -441,9 +469,9 @@ static uint32_t getGuixPackages(FFstrbuf* baseDir, const char* dirname)

static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts, FFPackagesOptions* options)
{
if (!(options->disabled & FF_PACKAGES_FLAG_APK_BIT)) packageCounts->apk += getNumStrings(baseDir, "/lib/apk/db/installed", "C:Q");
if (!(options->disabled & FF_PACKAGES_FLAG_DPKG_BIT)) packageCounts->dpkg += getNumStrings(baseDir, "/var/lib/dpkg/status", "Status: install ok installed");
if (!(options->disabled & FF_PACKAGES_FLAG_LPKG_BIT)) packageCounts->lpkg += getNumStrings(baseDir, "/opt/Loc-OS-LPKG/installed-lpkg/Listinstalled-lpkg.list", "\n");
if (!(options->disabled & FF_PACKAGES_FLAG_APK_BIT)) packageCounts->apk += getNumStrings(baseDir, "/lib/apk/db/installed", "C:Q", "apk");
if (!(options->disabled & FF_PACKAGES_FLAG_DPKG_BIT)) packageCounts->dpkg += getNumStrings(baseDir, "/var/lib/dpkg/status", "Status: install ok installed", "dpkg");
if (!(options->disabled & FF_PACKAGES_FLAG_LPKG_BIT)) packageCounts->lpkg += getNumStrings(baseDir, "/opt/Loc-OS-LPKG/installed-lpkg/Listinstalled-lpkg.list", "\n", "lpkg");
if (!(options->disabled & FF_PACKAGES_FLAG_EMERGE_BIT)) packageCounts->emerge += countFilesRecursive(baseDir, "/var/db/pkg", "SIZE");
if (!(options->disabled & FF_PACKAGES_FLAG_EOPKG_BIT)) packageCounts->eopkg += getNumElements(baseDir, "/var/lib/eopkg/package", DT_DIR);
if (!(options->disabled & FF_PACKAGES_FLAG_FLATPAK_BIT)) packageCounts->flatpakSystem += getNumElements(baseDir, "/var/lib/flatpak/app", DT_DIR);
Expand All @@ -455,7 +483,7 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts,
if (!(options->disabled & FF_PACKAGES_FLAG_PACMAN_BIT)) packageCounts->pacman += getNumElements(baseDir, "/var/lib/pacman/local", DT_DIR);
if (!(options->disabled & FF_PACKAGES_FLAG_LPKGBUILD_BIT)) packageCounts->lpkgbuild += getNumElements(baseDir, "/opt/Loc-OS-LPKG/lpkgbuild/remove", DT_REG);
if (!(options->disabled & FF_PACKAGES_FLAG_PKGTOOL_BIT)) packageCounts->pkgtool += getNumElements(baseDir, "/var/log/packages", DT_REG);
if (!(options->disabled & FF_PACKAGES_FLAG_RPM_BIT)) packageCounts->rpm += getSQLite3Int(baseDir, "/var/lib/rpm/rpmdb.sqlite", "SELECT count(*) FROM Packages");
if (!(options->disabled & FF_PACKAGES_FLAG_RPM_BIT)) packageCounts->rpm += getSQLite3Int(baseDir, "/var/lib/rpm/rpmdb.sqlite", "SELECT count(*) FROM Packages", "rpm");
if (!(options->disabled & FF_PACKAGES_FLAG_SNAP_BIT)) packageCounts->snap += getSnap(baseDir);
if (!(options->disabled & FF_PACKAGES_FLAG_XBPS_BIT)) packageCounts->xbps += getXBPS(baseDir, "/var/db/xbps");
if (!(options->disabled & FF_PACKAGES_FLAG_BREW_BIT))
Expand All @@ -464,9 +492,9 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts,
packageCounts->brew += getNumElements(baseDir, "/home/linuxbrew/.linuxbrew/Cellar", DT_DIR);
}
if (!(options->disabled & FF_PACKAGES_FLAG_PALUDIS_BIT)) packageCounts->paludis += countFilesRecursive(baseDir, "/var/db/paludis/repositories", "environment.bz2");
if (!(options->disabled & FF_PACKAGES_FLAG_OPKG_BIT)) packageCounts->opkg += getNumStrings(baseDir, "/usr/lib/opkg/status", "Package:"); // openwrt
if (!(options->disabled & FF_PACKAGES_FLAG_OPKG_BIT)) packageCounts->opkg += getNumStrings(baseDir, "/usr/lib/opkg/status", "Package:", "opkg"); // openwrt
if (!(options->disabled & FF_PACKAGES_FLAG_AM_BIT)) packageCounts->am = getAM(baseDir);
if (!(options->disabled & FF_PACKAGES_FLAG_SORCERY_BIT)) packageCounts->sorcery += getNumStrings(baseDir, "/var/state/sorcery/packages", ":installed:");
if (!(options->disabled & FF_PACKAGES_FLAG_SORCERY_BIT)) packageCounts->sorcery += getNumStrings(baseDir, "/var/state/sorcery/packages", ":installed:", "sorcery");
if (!(options->disabled & FF_PACKAGES_FLAG_GUIX_BIT))
{
packageCounts->guixSystem += getGuixPackages(baseDir, "/run/current-system/profile");
Expand Down

0 comments on commit 03c901b

Please sign in to comment.