Optimize dentfill

This commit is contained in:
Arun Prakash Jana 2017-04-11 01:11:06 +05:30
parent f2a5002fa9
commit afbce66747
No known key found for this signature in database
GPG key ID: A75979F35C080412
2 changed files with 74 additions and 9 deletions

View file

@ -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

82
nnn.c
View file

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