Mesa (master): util/disk_cache: pass predicate functions file stats directly (v4)

Timothy Arceri tarceri at kemper.freedesktop.org
Sat Mar 18 03:34:12 UTC 2017


Module: Mesa
Branch: master
Commit: a7eb7984bf2ad0562c315c1d641561419c3f1ebe
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a7eb7984bf2ad0562c315c1d641561419c3f1ebe

Author: Alan Swanson <reiver at improbability.net>
Date:   Fri Mar 17 18:05:43 2017 +0000

util/disk_cache: pass predicate functions file stats directly (v4)

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).

v2: Update for empty cache dir detection changes
v3: Fix passing string length to predicate with the +1 for NULL
    termination and also pass sb as pointer
v4: Missed ampersand for passing sb as pointer

Reviewed-by: Grazvydas Ignotas <notasas at gmail.com>
Acked-by: Timothy Arceri <tarceri at itsqueeze.com>

---

 src/util/disk_cache.c | 55 ++++++++++++++++++++-------------------------------
 1 file changed, 21 insertions(+), 34 deletions(-)

diff --git a/src/util/disk_cache.c b/src/util/disk_cache.c
index 30756bc428..6c91f23ffb 100644
--- a/src/util/disk_cache.c
+++ b/src/util/disk_cache.c
@@ -481,8 +481,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 char *dir_path,
+                                           const struct stat *,
+                                           const char *, const size_t))
 {
    DIR *dir;
    struct dirent *entry;
@@ -498,17 +499,19 @@ 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;
-            char *tmp = realloc(lru_name, len);
+            size_t len = strlen(entry->d_name);
+
+            if (!predicate(dir_path, &sb, entry->d_name, len))
+               continue;
+
+            char *tmp = realloc(lru_name, len + 1);
             if (tmp) {
                lru_name = tmp;
-               memcpy(lru_name, entry->d_name, len);
+               memcpy(lru_name, entry->d_name, len + 1);
                lru_atime = sb.st_atime;
             }
          }
@@ -533,21 +536,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 char *path, 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;
@@ -579,29 +574,21 @@ unlink_lru_file_from_directory(const char *path)
  * special name of ".."). We also return false if the dir is empty.
  */
 static bool
-is_two_character_sub_directory(const struct dirent *entry, const char *path)
+is_two_character_sub_directory(const char *path, const struct stat *sb,
+                               const char *d_name, const size_t len)
 {
-   char *subdir;
-   if (asprintf(&subdir, "%s/%s", path, entry->d_name) == -1)
+   if (!S_ISDIR(sb->st_mode))
       return false;
 
-   struct stat sb;
-   int res = stat(subdir, &sb);
-   if (res == -1 || !S_ISDIR(sb.st_mode)) {
-      free(subdir);
+   if (len != 2)
       return false;
-   }
 
-   if (strlen(entry->d_name) != 2) {
-      free(subdir);
+   if (strcmp(d_name, "..") == 0)
       return false;
-   }
 
-   if (strcmp(entry->d_name, "..") == 0) {
-      free(subdir);
+   char *subdir;
+   if (asprintf(&subdir, "%s/%s", path, d_name) == -1)
       return false;
-   }
-
    DIR *dir = opendir(subdir);
    free(subdir);
 




More information about the mesa-commit mailing list