Use exact number of bytes for each filename.

Results in even less memory usage. The names are appended one after another.
The offsets are reset when the location of the memory changes die to realloc().

Other changes:

1. Use a debug mode print to measure time.
2. Remove redundant prefix when printing pointers in debug mode.
This commit is contained in:
Arun Prakash Jana 2017-12-19 01:16:03 +05:30
parent 8307bc95bd
commit ded690c693
No known key found for this signature in database
GPG Key ID: A75979F35C080412
1 changed files with 49 additions and 19 deletions

68
nnn.c
View File

@ -129,7 +129,7 @@ disabledbg()
#define DPRINTF_D(x) xprintf(DEBUG_FD, #x "=%d\n", x)
#define DPRINTF_U(x) xprintf(DEBUG_FD, #x "=%u\n", x)
#define DPRINTF_S(x) xprintf(DEBUG_FD, #x "=%s\n", x)
#define DPRINTF_P(x) xprintf(DEBUG_FD, #x "=0x%p\n", x)
#define DPRINTF_P(x) xprintf(DEBUG_FD, #x "=%p\n", x)
#else
#define DPRINTF_D(x)
#define DPRINTF_U(x)
@ -140,6 +140,7 @@ disabledbg()
/* Macro definitions */
#define VERSION "1.5"
#define GENERAL_INFO "License: BSD 2-Clause\nWebpage: https://github.com/jarun/nnn"
#define LEN(x) (sizeof(x) / sizeof(*(x)))
#undef MIN
#define MIN(x, y) ((x) < (y) ? (x) : (y))
@ -154,6 +155,8 @@ disabledbg()
#define FILTER '/'
#define REGEX_MAX 128
#define BM_MAX 10
#define ENTRY_INCR 64 /* Number of dir 'entry' structures to allocate per shot */
#define NAMEBUF_INCR 0x1000 /* 64 dir entries at a time, avg. 64 chars per filename = 64*64B = 4KB */
/* Macros to define process spawn behaviour as flags */
#define F_NONE 0x00 /* no flag set */
@ -192,13 +195,10 @@ typedef struct entry {
time_t t;
off_t size;
blkcnt_t blocks; /* number of 512B blocks allocated */
size_t noff;
mode_t mode;
} *pEntry;
typedef struct {
char pname[NAME_MAX + 1];
} namebuf;
/* Bookmark */
typedef struct {
char *key;
@ -225,7 +225,7 @@ typedef struct {
static settings cfg = {0, 0, 0, 0, 0, 1, 1, 0, 0, 4};
static struct entry *dents;
static namebuf *pnamebuf;
static char *pnamebuf;
static int ndents, cur, total_dents;
static uint idle;
static uint idletimeout;
@ -1765,12 +1765,14 @@ dentfill(char *path, struct entry **dents,
{
static DIR *dirp;
static struct dirent *dp;
static struct stat sb_path, sb;
static int fd, n, count;
static char *namep;
static ulong num_saved;
static char *namep, *pnb;
static struct entry *dentp;
static namebuf *pnb;
static size_t off, namebuflen = NAMEBUF_INCR;
static ulong num_saved;
static int fd, n, count;
static struct stat sb_path, sb;
off = 0;
dirp = opendir(path);
if (dirp == NULL)
@ -1836,28 +1838,41 @@ dentfill(char *path, struct entry **dents,
}
if (n == total_dents) {
total_dents += 64;
total_dents += ENTRY_INCR;
*dents = realloc(*dents, total_dents * sizeof(**dents));
if (*dents == NULL)
if (*dents == NULL) {
if (pnamebuf)
free(pnamebuf);
errexit();
}
}
/* If there's not enough bytes left to copy a file name of length NAME_MAX, re-allocate */
if (namebuflen - off < NAME_MAX + 1) {
namebuflen += NAMEBUF_INCR;
pnb = pnamebuf;
pnamebuf = (namebuf *)realloc(pnamebuf, total_dents * sizeof(namebuf));
pnamebuf = (char *)realloc(pnamebuf, namebuflen);
DPRINTF_P(pnamebuf);
if (pnamebuf == NULL) {
free(*dents);
errexit();
}
/* realloc() may result in memory move, we must re-adjust if that happens */
if (pnb && pnb != pnamebuf)
if (pnb != pnamebuf)
for (count = 0; count < n; ++count)
(&(*dents)[count])->name = pnamebuf[count].pname;
(*dents + count)->name = pnamebuf + (*dents + count)->noff;
}
dentp = &(*dents)[n];
xstrlcpy(pnamebuf[n].pname, namep, NAME_MAX + 1);
dentp->name = pnamebuf[n].pname;
dentp = *dents + n;
/* Copy file name */
dentp->name = pnamebuf + off;
dentp->noff = off;
off += xstrlcpy(dentp->name, namep, NAME_MAX + 1);
/* Copy other fields */
dentp->mode = sb.st_mode;
dentp->t = sb.st_mtime;
dentp->size = sb.st_size;
@ -1947,10 +1962,20 @@ populate(char *path, char *oldpath, char *fltr)
refresh();
}
#ifdef DEBUGMODE
struct timespec ts1, ts2;
clock_gettime(CLOCK_REALTIME, &ts1); /* Use CLOCK_MONOTONIC on FreeBSD */
#endif
ndents = dentfill(path, &dents, visible, &re);
qsort(dents, ndents, sizeof(*dents), entrycmp);
#ifdef DEBUGMODE
clock_gettime(CLOCK_REALTIME, &ts2);
DPRINTF_U(ts2.tv_nsec - ts1.tv_nsec);
#endif
/* Find cur from history */
cur = dentfind(dents, ndents, oldpath);
return 0;
@ -2103,6 +2128,11 @@ browse(char *ipath, char *ifilter)
else
presel = 0;
/* Allocate buffer to hold names */
pnamebuf = (char *)malloc(NAMEBUF_INCR);
if (pnamebuf == NULL)
errexit();
begin:
#ifdef LINUX_INOTIFY
if (dir_changed && inotify_wd >= 0) {