1
1

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
Этот коммит содержится в:
yorhel 2007-07-26 16:37:33 +00:00
родитель eb10ca8a4b
Коммит c96bf1636a
5 изменённых файлов: 46 добавлений и 66 удалений

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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