]> Sergey Matveev's repositories - nnn.git/commitdiff
Optimize dentfill
authorArun Prakash Jana <engineerarun@gmail.com>
Mon, 10 Apr 2017 19:41:06 +0000 (01:11 +0530)
committerArun Prakash Jana <engineerarun@gmail.com>
Mon, 10 Apr 2017 20:28:27 +0000 (01:58 +0530)
README.md
nnn.c

index 9a3ea45592ec15d1a890070997acf18d3e175d89..964055463fb8dda589bf7842b2093d364444f9da 100644 (file)
--- a/README.md
+++ b/README.md
@@ -97,7 +97,6 @@ I chose to fork because:
 #### Optimizations
   - All redundant buffer removal
   - All frequently used local chunks now static
-  - No runtime surprises (0 malloc/free)
   - Removed some redundant string allocation and manipulation
   - Simplified some roundabout procedures
   - `-O3` level optimization, warning fixes
diff --git a/nnn.c b/nnn.c
index d45e4454f942c4aaa460da10c46d5ddc78ef7ed0..78d159c1492c938cae3393b1b737c67d785ec916 100644 (file)
--- a/nnn.c
+++ b/nnn.c
@@ -147,6 +147,16 @@ static void printmsg(char *);
 static void printwarn(void);
 static void printerr(int, char *);
 
+static void *
+xmalloc(size_t size)
+{
+       void *p = malloc(size);
+       if (p == NULL)
+               printerr(1, "malloc");
+       return p;
+}
+
+#if 0
 static void *
 xrealloc(void *p, size_t size)
 {
@@ -155,6 +165,7 @@ xrealloc(void *p, size_t size)
                printerr(1, "realloc");
        return p;
 }
+#endif
 
 static size_t
 xstrlcpy(char *dest, const char *src, size_t n)
@@ -941,6 +952,39 @@ sum_sizes(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ft
        return 0;
 }
 
+static int
+getorder(size_t size)
+{
+       switch (size) {
+       case 4096:
+               return 12;
+       case 512:
+               return 9;
+       case 8192:
+               return 13;
+       case 16384:
+               return 14;
+       case 32768:
+               return 15;
+       case 65536:
+               return 16;
+       case 131072:
+               return 17;
+       case 262144:
+               return 18;
+       case 524288:
+               return 19;
+       case 1048576:
+               return 20;
+       case 2048:
+               return 11;
+       case 1024:
+               return 10;
+       default:
+               return 0;
+       }
+}
+
 static int
 dentfill(char *path, struct entry **dents,
         int (*filter)(regex_t *, char *), regex_t *re)
@@ -957,20 +1001,34 @@ dentfill(char *path, struct entry **dents,
        if (dirp == NULL)
                return 0;
 
-       r = statvfs(path, &svb);
-       if (r == -1)
-               fs_free = 0;
-       else
-               fs_free = svb.f_bsize * svb.f_bavail;
+       long pos = telldir(dirp);
+       while ((dp = readdir(dirp)) != NULL) {
+               if (filter(re, dp->d_name) == 0)
+                       continue;
+
+               n++;
+       }
+
+       if (filter(re, ".") != 0)
+               n--;
+       if (filter(re, "..") != 0)
+               n--;
+       if (n == 0)
+               return n;
+
+       *dents = xmalloc(n * sizeof(**dents));
+       n = 0;
+
+       seekdir(dirp, pos);
 
        while ((dp = readdir(dirp)) != NULL) {
                /* Skip self and parent */
-               if (strcmp(dp->d_name, ".") == 0 ||
-                   strcmp(dp->d_name, "..") == 0)
+               if ((dp->d_name[0] == '.' && dp->d_name[1] == '\0') ||
+                   (dp->d_name[0] == '.' && dp->d_name[1] == '.' && dp->d_name[2] == '\0'))
                        continue;
                if (filter(re, dp->d_name) == 0)
                        continue;
-               *dents = xrealloc(*dents, (n + 1) * sizeof(**dents));
+               //*dents = xrealloc(*dents, (n + 1) * sizeof(**dents));
                xstrlcpy((*dents)[n].name, dp->d_name, sizeof((*dents)[n].name));
                /* Get mode flags */
                mkpath(path, dp->d_name, newpath, sizeof(newpath));
@@ -996,6 +1054,14 @@ dentfill(char *path, struct entry **dents,
                n++;
        }
 
+       if (bsizeorder) {
+               r = statvfs(path, &svb);
+               if (r == -1)
+                       fs_free = 0;
+               else
+                       fs_free = svb.f_bavail << getorder(svb.f_bsize);
+       }
+
        /* Should never be null */
        r = closedir(dirp);
        if (r == -1)