Store the name of the item in the dir struct itself
Rather than storing a pointer to another memory allocation in the struct. This saves some memory and improves performance by significantly decreasing the number of calls to [c|m]alloc() and free().
Этот коммит содержится в:
родитель
b7ccf78b90
Коммит
6fa56c1b38
@ -168,13 +168,12 @@ int calc_item(struct dir *par, char *name) {
|
||||
return 0;
|
||||
|
||||
/* allocate dir and fix references */
|
||||
d = calloc(sizeof(struct dir), 1);
|
||||
d = calloc(SDIRSIZE+strlen(name), 1);
|
||||
d->parent = par;
|
||||
d->next = par->sub;
|
||||
par->sub = d;
|
||||
if(d->next)
|
||||
d->next->prev = d;
|
||||
d->name = malloc(strlen(name)+1);
|
||||
strcpy(d->name, name);
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
@ -434,16 +433,15 @@ int calc_process() {
|
||||
}
|
||||
|
||||
/* initialize parent dir */
|
||||
t = (struct dir *) calloc(1, sizeof(struct dir));
|
||||
n = orig ? strlen(orig->name) : strlen(path)+strlen(name)+1;
|
||||
t = (struct dir *) calloc(1, SDIRSIZE+n);
|
||||
t->size = fs.st_blocks * S_BLKSIZE;
|
||||
t->asize = fs.st_size;
|
||||
t->flags |= FF_DIR;
|
||||
if(orig) {
|
||||
t->name = malloc(strlen(orig->name)+1);
|
||||
strcpy(t->name, orig->name);
|
||||
t->parent = orig->parent;
|
||||
} else {
|
||||
t->name = malloc(strlen(path)+strlen(name)+2);
|
||||
t->name[0] = 0;
|
||||
if(strcmp(path, "/"))
|
||||
strcpy(t->name, path);
|
||||
|
@ -197,7 +197,7 @@ void dirlist_open(struct dir *d) {
|
||||
dirlist_parent_alloc.flags &= ~FF_BSEL;
|
||||
if(head->parent->parent) {
|
||||
dirlist_parent = &dirlist_parent_alloc;
|
||||
dirlist_parent->name = "..";
|
||||
strcpy(dirlist_parent->name, "..");
|
||||
dirlist_parent->next = head;
|
||||
dirlist_parent->parent = head->parent;
|
||||
dirlist_parent->sub = head->parent;
|
||||
|
16
src/global.h
16
src/global.h
@ -53,13 +53,21 @@
|
||||
* fixed-size integers instead, which are much more predictable */
|
||||
struct dir {
|
||||
struct dir *parent, *next, *prev, *sub, *hlnk;
|
||||
char *name;
|
||||
off_t size, asize;
|
||||
unsigned long items;
|
||||
unsigned char flags;
|
||||
dev_t dev;
|
||||
ino_t ino;
|
||||
unsigned long items;
|
||||
dev_t dev;
|
||||
unsigned char flags;
|
||||
char name[3]; /* must be large enough to hold ".." */
|
||||
};
|
||||
/* sizeof(total dir) = SDIRSIZE + strlen(name) = sizeof(struct dir) - 3 + strlen(name) + 1 */
|
||||
#define SDIRSIZE (sizeof(struct dir)-2)
|
||||
|
||||
/* Ideally, the name array should be as large as the padding added to the end of
|
||||
* the struct, but I can't figure out a portable way to calculate this. We can
|
||||
* be sure that it's at least 3 bytes, though, as the struct is aligned to at
|
||||
* least 4 bytes and the flags field is a single byte. */
|
||||
|
||||
|
||||
/* program state */
|
||||
extern int pstate;
|
||||
|
@ -211,7 +211,6 @@ void freedir_rec(struct dir *dr) {
|
||||
freedir_hlnk(tmp);
|
||||
/* remove item */
|
||||
if(tmp->sub) freedir_rec(tmp->sub);
|
||||
free(tmp->name);
|
||||
tmp2 = tmp->next;
|
||||
free(tmp);
|
||||
}
|
||||
@ -245,7 +244,6 @@ void freedir(struct dir *dr) {
|
||||
tmp->items -= dr->items+1;
|
||||
}
|
||||
|
||||
free(dr->name);
|
||||
free(dr);
|
||||
}
|
||||
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user