[Mesa-dev] [PATCH] util/disk_cache: pass predicate functions file stats directly

Alan Swanson reiver at improbability.net
Sun Mar 12 15:03:52 UTC 2017


Since switching to LRU eviction the only user of these predicate
functions now resolves directory entry stats itself so pass them
directly saving calling fstat and strlen twice (and the expensive
strlen is skipped entirely if access time is newer).
---
Depends on "util/disc_cache: use LRU eviction rather than random eviction" patch.

 src/util/disk_cache.c | 44 ++++++++++++++++----------------------------
 1 file changed, 16 insertions(+), 28 deletions(-)

diff --git a/src/util/disk_cache.c b/src/util/disk_cache.c
index be0f8822b6..bd223864f9 100644
--- a/src/util/disk_cache.c
+++ b/src/util/disk_cache.c
@@ -453,8 +453,9 @@ make_cache_file_directory(struct disk_cache *cache, const cache_key key)
  */
 static char *
 choose_lru_file_matching(const char *dir_path,
-                         bool (*predicate)(const struct dirent *,
-                                           const char *dir_path))
+                         bool (*predicate)(const struct stat,
+                                           const char *,
+                                           const size_t))
 {
    DIR *dir;
    struct dirent *entry;
@@ -470,13 +471,15 @@ choose_lru_file_matching(const char *dir_path,
       entry = readdir(dir);
       if (entry == NULL)
          break;
-      if (!predicate(entry, dir_path))
-         continue;
 
       struct stat sb;
       if (fstatat(dirfd(dir), entry->d_name, &sb, 0) == 0) {
          if (!lru_atime || (sb.st_atime < lru_atime)) {
             size_t len = strlen(entry->d_name) + 1;
+
+            if (!predicate(sb, entry->d_name, len))
+               continue;
+
             char *tmp = realloc(lru_name, len);
             if (tmp) {
                lru_name = tmp;
@@ -505,21 +508,13 @@ choose_lru_file_matching(const char *dir_path,
  * ".tmp"
  */
 static bool
-is_regular_non_tmp_file(const struct dirent *entry, const char *path)
+is_regular_non_tmp_file(const struct stat sb, const char *d_name,
+                        const size_t len)
 {
-   char *filename;
-   if (asprintf(&filename, "%s/%s", path, entry->d_name) == -1)
-      return false;
-
-   struct stat sb;
-   int res = stat(filename, &sb);
-   free(filename);
-
-   if (res == -1 || !S_ISREG(sb.st_mode))
+   if (!S_ISREG(sb.st_mode))
       return false;
 
-   size_t len = strlen (entry->d_name);
-   if (len >= 4 && strcmp(&entry->d_name[len-4], ".tmp") == 0)
+   if (len >= 4 && strcmp(&d_name[len-4], ".tmp") == 0)
       return false;
 
    return true;
@@ -552,23 +547,16 @@ unlink_lru_file_from_directory(const char *path)
  * special name of "..")
  */
 static bool
-is_two_character_sub_directory(const struct dirent *entry, const char *path)
+is_two_character_sub_directory(const struct stat sb, const char *d_name,
+                               const size_t len)
 {
-   char *subdir;
-   if (asprintf(&subdir, "%s/%s", path, entry->d_name) == -1)
-      return false;
-
-   struct stat sb;
-   int res = stat(subdir, &sb);
-   free(subdir);
-
-   if (res == -1 || !S_ISDIR(sb.st_mode))
+   if (!S_ISDIR(sb.st_mode))
       return false;
 
-   if (strlen(entry->d_name) != 2)
+   if (len != 2)
       return false;
 
-   if (strcmp(entry->d_name, "..") == 0)
+   if (strcmp(d_name, "..") == 0)
       return false;
 
    return true;
-- 
2.11.1



More information about the mesa-dev mailing list