Changed struct dir from a doubly to a singly linked list (less memory usage, faster, and easier)
git-svn-id: svn://blicky.net/ncdu/trunk@13 ce56bc8d-f834-0410-b703-f827bd498a76
Этот коммит содержится в:
родитель
eb10ca8a4b
Коммит
c96bf1636a
@ -26,13 +26,8 @@
|
||||
#include "ncdu.h"
|
||||
|
||||
struct dir *bcur;
|
||||
int helpwin;
|
||||
|
||||
|
||||
struct dir * removedir(struct dir *dr) {
|
||||
return(dr);
|
||||
}
|
||||
|
||||
int cmp(struct dir *x, struct dir *y) {
|
||||
struct dir *a, *b;
|
||||
int r = 0;
|
||||
@ -57,7 +52,7 @@ int cmp(struct dir *x, struct dir *y) {
|
||||
if(r == 0)
|
||||
r = a->size > b->size ? 1 : (a->size == b->size ? 0 : -1);
|
||||
if(r == 0)
|
||||
r = strcmp(a->name, b->name);
|
||||
r = strcmp(x->name, y->name);
|
||||
return(r);
|
||||
}
|
||||
|
||||
@ -68,8 +63,6 @@ struct dir *sortFiles(struct dir *list) {
|
||||
struct dir *p, *q, *e, *tail;
|
||||
int insize, nmerges, psize, qsize, i;
|
||||
|
||||
while(list->prev != NULL)
|
||||
list = list->prev;
|
||||
insize = 1;
|
||||
while(1) {
|
||||
p = list;
|
||||
@ -98,7 +91,6 @@ struct dir *sortFiles(struct dir *list) {
|
||||
}
|
||||
if(tail) tail->next = e;
|
||||
else list = e;
|
||||
e->prev = tail;
|
||||
tail = e;
|
||||
}
|
||||
p = q;
|
||||
@ -135,8 +127,8 @@ void drawBrowser(int change) {
|
||||
erase();
|
||||
|
||||
/* exit if there are no items to display */
|
||||
if(bcur->parent == NULL) {
|
||||
if(bcur->sub == NULL) {
|
||||
if(bcur == NULL || bcur->parent == NULL) {
|
||||
if(bcur == NULL || bcur->sub == NULL) {
|
||||
erase();
|
||||
refresh();
|
||||
endwin();
|
||||
@ -159,10 +151,9 @@ void drawBrowser(int change) {
|
||||
mvhline(1, 0, '-', wincols);
|
||||
mvaddstr(1, 3, cropdir(getpath(bcur, tmp), wincols-5));
|
||||
|
||||
/* make sure we have the first item, and the items are in correct order */
|
||||
/* make sure the items are in correct order */
|
||||
bcur = sortFiles(bcur);
|
||||
while(bcur->prev != NULL)
|
||||
bcur = bcur->prev;
|
||||
bcur->parent->sub = bcur;
|
||||
|
||||
/* get maximum size and selected item */
|
||||
for(n = bcur, selected = i = 0; n != NULL; n = n->next, i++) {
|
||||
@ -346,13 +337,13 @@ void showBrowser(void) {
|
||||
case KEY_RIGHT:
|
||||
n = selected();
|
||||
if(n->flags & FF_PAR)
|
||||
bcur = bcur->parent;
|
||||
bcur = bcur->parent->parent->sub;
|
||||
else if(n->sub != NULL)
|
||||
bcur = n->sub;
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
if(bcur->parent->parent != NULL) {
|
||||
bcur = bcur->parent;
|
||||
bcur = bcur->parent->parent->sub;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -360,17 +351,14 @@ void showBrowser(void) {
|
||||
case 'r':
|
||||
if((n = showCalc(getpath(bcur, tmp))) != NULL) {
|
||||
/* free current items */
|
||||
t = bcur;
|
||||
d = bcur;
|
||||
bcur = bcur->parent;
|
||||
while(t->prev != NULL)
|
||||
t = t->prev;
|
||||
d = t;
|
||||
while(d != NULL) {
|
||||
t = d;
|
||||
d = t->next;
|
||||
freedir(t);
|
||||
}
|
||||
|
||||
|
||||
/* update parent dir */
|
||||
bcur->sub = n->sub;
|
||||
bcur->files = n->files;
|
||||
@ -394,7 +382,6 @@ void showBrowser(void) {
|
||||
strcpy(t->name, "..");
|
||||
t->parent = bcur;
|
||||
t->next = bcur->sub;
|
||||
t->next->prev = t;
|
||||
bcur->sub = t;
|
||||
}
|
||||
|
||||
@ -418,6 +405,8 @@ void showBrowser(void) {
|
||||
n = selected();
|
||||
if(!(n->flags & FF_PAR))
|
||||
bcur = showDelete(n);
|
||||
if(bcur && bcur->parent)
|
||||
bcur = bcur->parent->sub;
|
||||
break;
|
||||
case 'q':
|
||||
goto endloop;
|
||||
|
19
src/calc.c
19
src/calc.c
@ -229,7 +229,7 @@ int updateProgress(char *path) {
|
||||
|
||||
/* recursive */
|
||||
int calcDir(struct dir *dest, char *path) {
|
||||
struct dir *d, *t;
|
||||
struct dir *d, *t, *last;
|
||||
struct stat fs;
|
||||
DIR *dir;
|
||||
struct dirent *dr;
|
||||
@ -257,6 +257,7 @@ int calcDir(struct dir *dest, char *path) {
|
||||
}
|
||||
|
||||
/* read directory */
|
||||
last = NULL;
|
||||
while((dr = readdir(dir)) != NULL) {
|
||||
f = dr->d_name;
|
||||
if(f[0] == '.' && (f[1] == '\0' || (f[1] == '.' && f[2] == '\0')))
|
||||
@ -272,11 +273,11 @@ int calcDir(struct dir *dest, char *path) {
|
||||
/* allocate dir and fix references */
|
||||
d = calloc(sizeof(struct dir), 1);
|
||||
d->parent = dest;
|
||||
if(dest->sub != NULL) {
|
||||
d->prev = dest->sub;
|
||||
d->prev->next = d;
|
||||
}
|
||||
d->parent->sub = d;
|
||||
if(dest->sub == NULL)
|
||||
dest->sub = d;
|
||||
if(last != NULL)
|
||||
last->next = d;
|
||||
last = d;
|
||||
|
||||
/* set d->name */
|
||||
d->name = malloc(strlen(f)+1);
|
||||
@ -339,10 +340,6 @@ int calcDir(struct dir *dest, char *path) {
|
||||
}
|
||||
|
||||
if(dest->sub) {
|
||||
/* update dest->sub to point to the first item */
|
||||
while(dest->sub->prev)
|
||||
dest->sub = dest->sub->prev;
|
||||
|
||||
/* add reference to parent dir */
|
||||
d = calloc(sizeof(struct dir), 1);
|
||||
d->flags |= FF_PAR;
|
||||
@ -350,7 +347,6 @@ int calcDir(struct dir *dest, char *path) {
|
||||
strcpy(d->name, "..");
|
||||
d->next = dest->sub;
|
||||
d->parent = dest;
|
||||
d->next->prev = d;
|
||||
dest->sub = d;
|
||||
|
||||
/* calculate subdirectories */
|
||||
@ -403,7 +399,6 @@ struct dir *showCalc(char *path) {
|
||||
/* remove reference to parent dir if we are in the parent dir */
|
||||
t = parent->sub;
|
||||
parent->sub = t->next;
|
||||
parent->sub->prev = NULL;
|
||||
free(t->name);
|
||||
free(t);
|
||||
|
||||
|
@ -117,7 +117,8 @@ struct dir *deleteDir(struct dir *dr) {
|
||||
struct timeval tv;
|
||||
|
||||
getpath(dr, file);
|
||||
strcat(file, "/");
|
||||
if(file[strlen(file)-1] != '/')
|
||||
strcat(file, "/");
|
||||
strcat(file, dr->name);
|
||||
|
||||
/* check for input or screen resizes */
|
||||
@ -145,15 +146,11 @@ struct dir *deleteDir(struct dir *dr) {
|
||||
if(dr->flags & FF_DIR) {
|
||||
if(dr->sub != NULL) {
|
||||
nxt = dr->sub;
|
||||
while(nxt->prev != NULL)
|
||||
nxt = nxt->prev;
|
||||
while(nxt != NULL) {
|
||||
cur = nxt;
|
||||
nxt = cur->next;
|
||||
if(cur->flags & FF_PAR) {
|
||||
freedir(cur);
|
||||
if(cur->flags & FF_PAR)
|
||||
continue;
|
||||
}
|
||||
if(deleteDir(cur) == NULL)
|
||||
return(NULL);
|
||||
}
|
||||
|
@ -110,7 +110,7 @@
|
||||
* S T R U C T U R E S
|
||||
*/
|
||||
struct dir {
|
||||
struct dir *parent, *next, *prev, *sub;
|
||||
struct dir *parent, *next, *sub;
|
||||
char *name;
|
||||
off_t size;
|
||||
unsigned int files, dirs;
|
||||
|
49
src/util.c
49
src/util.c
@ -98,8 +98,6 @@ void ncresize(void) {
|
||||
void freedir_rec(struct dir *dr) {
|
||||
struct dir *tmp, *tmp2;
|
||||
tmp2 = dr;
|
||||
while(tmp2->prev != NULL)
|
||||
tmp2 = tmp2->prev;
|
||||
while((tmp = tmp2) != NULL) {
|
||||
if(tmp->sub) freedir_rec(tmp->sub);
|
||||
free(tmp->name);
|
||||
@ -127,22 +125,23 @@ struct dir *freedir(struct dir *dr) {
|
||||
|
||||
/* update references */
|
||||
cur = NULL;
|
||||
if(dr->next != NULL) { dr->next->prev = dr->prev; cur = dr->next; }
|
||||
if(dr->prev != NULL) { dr->prev->next = dr->next; cur = dr->prev; }
|
||||
if(dr->parent) {
|
||||
/* item is at the top of the dir, refer to next item */
|
||||
if(dr->parent->sub == dr) {
|
||||
dr->parent->sub = dr->next;
|
||||
cur = dr->next;
|
||||
}
|
||||
/* else, get the previous item and update it's "next"-reference */
|
||||
else
|
||||
for(tmp = dr->parent->sub; tmp != NULL; tmp = tmp->next)
|
||||
if(tmp->next == dr) {
|
||||
tmp->next = dr->next;
|
||||
cur = tmp;
|
||||
}
|
||||
}
|
||||
if(cur != NULL)
|
||||
cur->flags |= FF_BSEL;
|
||||
|
||||
if(dr->parent && dr->parent->sub == dr) {
|
||||
if(dr->prev != NULL)
|
||||
dr->parent->sub = dr->prev;
|
||||
else if(dr->next != NULL)
|
||||
dr->parent->sub = dr->next;
|
||||
else {
|
||||
dr->parent->sub = NULL;
|
||||
cur = dr->parent;
|
||||
}
|
||||
}
|
||||
|
||||
free(dr->name);
|
||||
free(dr);
|
||||
|
||||
@ -150,18 +149,18 @@ struct dir *freedir(struct dir *dr) {
|
||||
}
|
||||
|
||||
char *getpath(struct dir *cur, char *to) {
|
||||
struct dir *d;
|
||||
d = cur;
|
||||
while(d->parent != NULL) {
|
||||
d->parent->sub = d;
|
||||
d = d->parent;
|
||||
}
|
||||
struct dir *d, *list[100];
|
||||
int c = 0;
|
||||
|
||||
for(d = cur; (d = d->parent) != NULL; )
|
||||
list[c++] = d;
|
||||
|
||||
to[0] = '\0';
|
||||
while(d->parent != cur->parent) {
|
||||
if(d->parent != NULL && d->parent->name[strlen(d->parent->name)-1] != '/')
|
||||
while(c--) {
|
||||
if(list[c]->parent && list[c]->name[strlen(list[c]->name)-1] != '/')
|
||||
strcat(to, "/");
|
||||
strcat(to, d->name);
|
||||
d = d->sub;
|
||||
strcat(to, list[c]->name);
|
||||
}
|
||||
|
||||
return to;
|
||||
}
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user