// SPDX-License-Identifier: GPL-2.0-only /* Manage a cache of file names' existence */ #include #include #include #include #include #include "fncache.h" #include "hashmap.h" static struct hashmap *fncache; static size_t fncache__hash(long key, void *ctx __maybe_unused) { return str_hash((const char *)key); } static bool fncache__equal(long key1, long key2, void *ctx __maybe_unused) { return strcmp((const char *)key1, (const char *)key2) == 0; } static void fncache__init(void) { fncache = hashmap__new(fncache__hash, fncache__equal, /*ctx=*/NULL); } static struct hashmap *fncache__get(void) { static pthread_once_t fncache_once = PTHREAD_ONCE_INIT; pthread_once(&fncache_once, fncache__init); return fncache; } static bool lookup_fncache(const char *name, bool *res) { long val; if (!hashmap__find(fncache__get(), name, &val)) return false; *res = (val != 0); return true; } static void update_fncache(const char *name, bool res) { char *old_key = NULL, *key = strdup(name); if (key) { hashmap__set(fncache__get(), key, res, &old_key, /*old_value*/NULL); free(old_key); } } /* No LRU, only use when bounded in some other way. */ bool file_available(const char *name) { bool res; if (lookup_fncache(name, &res)) return res; res = access(name, R_OK) == 0; update_fncache(name, res); return res; }