Commit 21b5cde4 authored by Warren Dukes's avatar Warren Dukes

ok, optimize memory sage of directorys, by iteratively creating the directories,

this code needs some serious testing: Note: The song name optimization i think is worth it, saves about 200k of ram on my syste, however, having to create directory names iteratively each time we print probably isn't worth the cpu. We only save about 10k of ram for the computer todo alot more work, and the code maybe a little messier git-svn-id: https://svn.musicpd.org/mpd/trunk@2604 09075e82-0dd4-0310-85a5-a0d7c8717e4f
parent 6e0c4369
...@@ -60,8 +60,8 @@ int countSongsInDirectory(FILE * fp, Directory * directory, void * data) { ...@@ -60,8 +60,8 @@ int countSongsInDirectory(FILE * fp, Directory * directory, void * data) {
} }
int printDirectoryInDirectory(FILE * fp, Directory * directory, void * data) { int printDirectoryInDirectory(FILE * fp, Directory * directory, void * data) {
if(directory->utf8name) { if(directory->name) {
myfprintf(fp,"directory: %s\n",directory->utf8name); myfprintf(fp,"directory: %s\n", getDirectoryPath(directory));
} }
return 0; return 0;
} }
...@@ -273,13 +273,15 @@ int listAllUniqueTags(FILE * fp, int type, int numConditionals, ...@@ -273,13 +273,15 @@ int listAllUniqueTags(FILE * fp, int type, int numConditionals,
int sumSavedMemoryInDirectory(FILE * fp, Directory * dir, void * data) { int sumSavedMemoryInDirectory(FILE * fp, Directory * dir, void * data) {
int * sum = data; int * sum = data;
if(!dir->utf8name) return 0; if(!dir->name) return 0;
*sum += (strlen(dir->utf8name)+1-sizeof(Directory *))* *sum += (strlen(getDirectoryPath(dir))+1-sizeof(Directory *))*
dir->songs->numberOfNodes; dir->songs->numberOfNodes;
/**sum += (strlen(dir->utf8name)+1)* *sum += (strlen(getDirectoryPath(dir))+1)*
dir->subDirectories->numberOfNodes;*/ dir->subDirectories->numberOfNodes;
*sum += strlen(dir->name)+1;
return 0; return 0;
} }
......
...@@ -250,8 +250,8 @@ Directory * newDirectory(char * dirname, Directory * parent) { ...@@ -250,8 +250,8 @@ Directory * newDirectory(char * dirname, Directory * parent) {
directory = malloc(sizeof(Directory)); directory = malloc(sizeof(Directory));
if(dirname!=NULL) directory->utf8name = strdup(dirname); if(dirname!=NULL) directory->name = strdup(dirname);
else directory->utf8name = NULL; else directory->name = NULL;
directory->subDirectories = newDirectoryList(); directory->subDirectories = newDirectoryList();
directory->songs = newSongList(); directory->songs = newSongList();
directory->stat = NULL; directory->stat = NULL;
...@@ -263,13 +263,14 @@ Directory * newDirectory(char * dirname, Directory * parent) { ...@@ -263,13 +263,14 @@ Directory * newDirectory(char * dirname, Directory * parent) {
void freeDirectory(Directory * directory) { void freeDirectory(Directory * directory) {
freeDirectoryList(directory->subDirectories); freeDirectoryList(directory->subDirectories);
freeSongList(directory->songs); freeSongList(directory->songs);
if(directory->utf8name) free(directory->utf8name); if(directory->name) free(directory->name);
freeDirectoryStatFromDirectory(directory); freeDirectoryStatFromDirectory(directory);
free(directory); free(directory);
getDirectoryPath(NULL);
} }
DirectoryList * newDirectoryList() { DirectoryList * newDirectoryList() {
return makeList((ListFreeDataFunc *)freeDirectory, 1); return makeList((ListFreeDataFunc *)freeDirectory, 0);
} }
void freeDirectoryList(DirectoryList * directoryList) { void freeDirectoryList(DirectoryList * directoryList) {
...@@ -351,7 +352,7 @@ int updateInDirectory(Directory * directory, char * shortname, char * name) { ...@@ -351,7 +352,7 @@ int updateInDirectory(Directory * directory, char * shortname, char * name) {
int removeDeletedFromDirectory(Directory * directory, DIR * dir) { int removeDeletedFromDirectory(Directory * directory, DIR * dir) {
char cwd[2]; char cwd[2];
struct dirent * ent; struct dirent * ent;
char * dirname = directory->utf8name; char * dirname = getDirectoryPath(directory);
List * entList = makeList(free, 1); List * entList = makeList(free, 1);
void * name; void * name;
char * s; char * s;
...@@ -372,9 +373,10 @@ int removeDeletedFromDirectory(Directory * directory, DIR * dir) { ...@@ -372,9 +373,10 @@ int removeDeletedFromDirectory(Directory * directory, DIR * dir) {
if(!utf8) continue; if(!utf8) continue;
if(directory->utf8name) { if(directory->name) {
s = malloc(strlen(directory->utf8name)+strlen(utf8)+2); s = malloc(strlen(getDirectoryPath(directory))
sprintf(s,"%s/%s",directory->utf8name,utf8); +strlen(utf8)+2);
sprintf(s,"%s/%s", getDirectoryPath(directory), utf8);
} }
else s= strdup(utf8); else s= strdup(utf8);
insertInList(entList,utf8,s); insertInList(entList,utf8,s);
...@@ -393,9 +395,9 @@ int removeDeletedFromDirectory(Directory * directory, DIR * dir) { ...@@ -393,9 +395,9 @@ int removeDeletedFromDirectory(Directory * directory, DIR * dir) {
} }
else { else {
LOG("removing directory: "); LOG("removing directory: ");
if(directory->utf8name) LOG("%s/",directory->utf8name); LOG("%s/",getDirectoryPath(directory));
LOG("%s\n",node->key); LOG("%s\n",node->key);
deleteFromList(directory->subDirectories,node->key); deleteFromList(directory->subDirectories, node->key);
ret = 1; ret = 1;
} }
node = tmpNode; node = tmpNode;
...@@ -451,8 +453,9 @@ Directory * addDirectoryPathToDB(char * utf8path, char ** shortname) { ...@@ -451,8 +453,9 @@ Directory * addDirectoryPathToDB(char * utf8path, char ** shortname) {
return NULL; return NULL;
} }
else { else {
directory = newDirectory(utf8path, parentDirectory); directory = newDirectory(*shortname, parentDirectory);
insertInList(parentDirectory->subDirectories,*shortname, insertInList(parentDirectory->subDirectories,
((Directory *)directory)->name,
directory); directory);
} }
} }
...@@ -596,7 +599,7 @@ int updateDirectory(Directory * directory) { ...@@ -596,7 +599,7 @@ int updateDirectory(Directory * directory) {
struct dirent * ent; struct dirent * ent;
char * s; char * s;
char * utf8; char * utf8;
char * dirname = directory->utf8name; char * dirname = getDirectoryPath(directory);
int ret = 0; int ret = 0;
{ {
...@@ -631,9 +634,10 @@ int updateDirectory(Directory * directory) { ...@@ -631,9 +634,10 @@ int updateDirectory(Directory * directory) {
utf8 = strdup(utf8); utf8 = strdup(utf8);
if(directory->utf8name) { if(directory->name) {
s = malloc(strlen(directory->utf8name)+strlen(utf8)+2); s = malloc(strlen(getDirectoryPath(directory))+
sprintf(s,"%s/%s",directory->utf8name,utf8); strlen(utf8)+2);
sprintf(s,"%s/%s", getDirectoryPath(directory), utf8);
} }
else s = strdup(utf8); else s = strdup(utf8);
if(updateInDirectory(directory,utf8,s)>0) ret = 1; if(updateInDirectory(directory,utf8,s)>0) ret = 1;
...@@ -657,7 +661,7 @@ int exploreDirectory(Directory * directory) { ...@@ -657,7 +661,7 @@ int exploreDirectory(Directory * directory) {
struct dirent * ent; struct dirent * ent;
char * s; char * s;
char * utf8; char * utf8;
char * dirname = directory->utf8name; char * dirname = getDirectoryPath(directory);
int ret = 0; int ret = 0;
cwd[0] = '.'; cwd[0] = '.';
...@@ -680,9 +684,10 @@ int exploreDirectory(Directory * directory) { ...@@ -680,9 +684,10 @@ int exploreDirectory(Directory * directory) {
DEBUG("explore: found: %s (%s)\n",ent->d_name,utf8); DEBUG("explore: found: %s (%s)\n",ent->d_name,utf8);
if(directory->utf8name) { if(directory->name) {
s = malloc(strlen(directory->utf8name)+strlen(utf8)+2); s = malloc(strlen(getDirectoryPath(directory))+
sprintf(s,"%s/%s",directory->utf8name,utf8); strlen(utf8)+2);
sprintf(s,"%s/%s", getDirectoryPath(directory) ,utf8);
} }
else s = strdup(utf8); else s = strdup(utf8);
if(addToDirectory(directory,utf8,s)>0) ret = 1; if(addToDirectory(directory,utf8,s)>0) ret = 1;
...@@ -698,7 +703,9 @@ int exploreDirectory(Directory * directory) { ...@@ -698,7 +703,9 @@ int exploreDirectory(Directory * directory) {
int statDirectory(Directory * dir) { int statDirectory(Directory * dir) {
struct stat st; struct stat st;
if(myStat(dir->utf8name ? dir->utf8name : "", &st) < 0) return -1; if(myStat(getDirectoryPath(dir) ? getDirectoryPath(dir) : "", &st) < 0) {
return -1;
}
dir->stat = newDirectoryStat(&st); dir->stat = newDirectoryStat(&st);
...@@ -729,7 +736,7 @@ int addSubDirectoryToDirectory(Directory * directory, char * shortname, ...@@ -729,7 +736,7 @@ int addSubDirectoryToDirectory(Directory * directory, char * shortname,
if(inodeFoundInParent(directory, st->st_ino, st->st_dev)) return 0; if(inodeFoundInParent(directory, st->st_ino, st->st_dev)) return 0;
subDirectory = newDirectory(name, directory); subDirectory = newDirectory(shortname, directory);
subDirectory->stat = newDirectoryStat(st); subDirectory->stat = newDirectoryStat(st);
if(exploreDirectory(subDirectory)<1) { if(exploreDirectory(subDirectory)<1) {
...@@ -737,7 +744,8 @@ int addSubDirectoryToDirectory(Directory * directory, char * shortname, ...@@ -737,7 +744,8 @@ int addSubDirectoryToDirectory(Directory * directory, char * shortname,
return 0; return 0;
} }
insertInList(directory->subDirectories,shortname,subDirectory); insertInList(directory->subDirectories, subDirectory->name,
subDirectory);
return 1; return 1;
} }
...@@ -828,7 +836,8 @@ int printDirectoryList(FILE * fp, DirectoryList * directoryList) { ...@@ -828,7 +836,8 @@ int printDirectoryList(FILE * fp, DirectoryList * directoryList) {
while(node!=NULL) { while(node!=NULL) {
directory = (Directory *)node->data; directory = (Directory *)node->data;
myfprintf(fp,"%s%s\n",DIRECTORY_DIR,directory->utf8name); myfprintf(fp,"%s%s\n", DIRECTORY_DIR,
getDirectoryPath(directory));
node = node->nextNode; node = node->nextNode;
} }
...@@ -854,8 +863,9 @@ void writeDirectoryInfo(FILE * fp, Directory * directory) { ...@@ -854,8 +863,9 @@ void writeDirectoryInfo(FILE * fp, Directory * directory) {
ListNode * node = (directory->subDirectories)->firstNode; ListNode * node = (directory->subDirectories)->firstNode;
Directory * subDirectory; Directory * subDirectory;
if(directory->utf8name) { if(directory->name) {
myfprintf(fp,"%s%s\n",DIRECTORY_BEGIN,directory->utf8name); myfprintf(fp,"%s%s\n", DIRECTORY_BEGIN,
getDirectoryPath(directory));
} }
while(node!=NULL) { while(node!=NULL) {
...@@ -867,8 +877,9 @@ void writeDirectoryInfo(FILE * fp, Directory * directory) { ...@@ -867,8 +877,9 @@ void writeDirectoryInfo(FILE * fp, Directory * directory) {
writeSongInfoFromList(fp,directory->songs); writeSongInfoFromList(fp,directory->songs);
if(directory->utf8name) { if(directory->name) {
myfprintf(fp,"%s%s\n",DIRECTORY_END,directory->utf8name); myfprintf(fp,"%s%s\n", DIRECTORY_END,
getDirectoryPath(directory));
} }
} }
...@@ -877,7 +888,6 @@ void readDirectoryInfo(FILE * fp,Directory * directory) { ...@@ -877,7 +888,6 @@ void readDirectoryInfo(FILE * fp,Directory * directory) {
int bufferSize = MAXPATHLEN*2; int bufferSize = MAXPATHLEN*2;
char * key; char * key;
Directory * subDirectory; Directory * subDirectory;
char * name;
int strcmpRet; int strcmpRet;
ListNode * nextDirNode = directory->subDirectories->firstNode; ListNode * nextDirNode = directory->subDirectories->firstNode;
ListNode * nodeTemp; ListNode * nodeTemp;
...@@ -902,7 +912,8 @@ void readDirectoryInfo(FILE * fp,Directory * directory) { ...@@ -902,7 +912,8 @@ void readDirectoryInfo(FILE * fp,Directory * directory) {
ERROR("Error reading db at line: %s\n",buffer); ERROR("Error reading db at line: %s\n",buffer);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
name = strdup(&(buffer[strlen(DIRECTORY_BEGIN)])); /* we ignore the name now
name = strdup(&(buffer[strlen(DIRECTORY_BEGIN)]));*/
while(nextDirNode && (strcmpRet = while(nextDirNode && (strcmpRet =
strcmp(key,nextDirNode->key)) > 0) { strcmp(key,nextDirNode->key)) > 0) {
...@@ -913,8 +924,9 @@ void readDirectoryInfo(FILE * fp,Directory * directory) { ...@@ -913,8 +924,9 @@ void readDirectoryInfo(FILE * fp,Directory * directory) {
} }
if(NULL==nextDirNode) { if(NULL==nextDirNode) {
subDirectory = newDirectory(name, directory); subDirectory = newDirectory(key, directory);
insertInList(directory->subDirectories,key, insertInList(directory->subDirectories,
subDirectory->name,
(void *)subDirectory); (void *)subDirectory);
} }
else if(strcmpRet == 0) { else if(strcmpRet == 0) {
...@@ -922,16 +934,15 @@ void readDirectoryInfo(FILE * fp,Directory * directory) { ...@@ -922,16 +934,15 @@ void readDirectoryInfo(FILE * fp,Directory * directory) {
nextDirNode = nextDirNode->nextNode; nextDirNode = nextDirNode->nextNode;
} }
else { else {
subDirectory = newDirectory(name, directory); subDirectory = newDirectory(key, directory);
insertInListBeforeNode( insertInListBeforeNode(
directory->subDirectories, directory->subDirectories,
nextDirNode, nextDirNode,
key, subDirectory->name,
(void *)subDirectory); (void *)subDirectory);
} }
free(key); free(key);
free(name);
readDirectoryInfo(fp,subDirectory); readDirectoryInfo(fp,subDirectory);
} }
else if(0==strncmp(SONG_BEGIN,buffer,strlen(SONG_BEGIN))) { else if(0==strncmp(SONG_BEGIN,buffer,strlen(SONG_BEGIN))) {
...@@ -1225,3 +1236,45 @@ Song * getSongFromDB(char * file) { ...@@ -1225,3 +1236,45 @@ Song * getSongFromDB(char * file) {
time_t getDbModTime() { time_t getDbModTime() {
return directory_dbModTime; return directory_dbModTime;
} }
/* pass a NULL to this function to clear the static lastDir, this way
* if a directory is freed, and then realloced, the wrong name isn't
* output */
char * getDirectoryPath(Directory * dir) {
static char * buffer = NULL;
static int bufferSize = 0;
static Directory * lastDir = NULL;
static int pos = 0;
int dlen;
if(!dir || !dir->name) {
lastDir = NULL;
return "";
}
if(lastDir == dir) return buffer+pos+1;
pos = bufferSize-1;
while(dir && dir->name) {
dlen = strlen(dir->name);
/* add one for the '/' */
pos -= dlen+1;
if(pos < 0) {
buffer = realloc(buffer, bufferSize-pos);
if(bufferSize) {
memmove(buffer-pos, buffer, bufferSize);
}
bufferSize += -pos;
buffer[bufferSize-1] = '\0';
pos = 0;
}
strncpy(buffer+pos+1, dir->name, dlen);
buffer[pos] = '/';
dir = dir->parent;
}
lastDir = dir;
return buffer+pos+1;
}
...@@ -35,7 +35,7 @@ typedef struct _DirectoryStat { ...@@ -35,7 +35,7 @@ typedef struct _DirectoryStat {
} DirectoryStat; } DirectoryStat;
typedef struct _Directory { typedef struct _Directory {
char * utf8name; char * name;
DirectoryList * subDirectories; DirectoryList * subDirectories;
SongList * songs; SongList * songs;
struct _Directory * parent; struct _Directory * parent;
...@@ -75,6 +75,9 @@ int traverseAllIn(FILE * fp, char * name, ...@@ -75,6 +75,9 @@ int traverseAllIn(FILE * fp, char * name,
int (*forEachDir)(FILE *, Directory *, void *), int (*forEachDir)(FILE *, Directory *, void *),
void * data); void * data);
/* don't free this */
char * getDirectoryPath(Directory * dir);
/* free the string that is returned */ /* free the string that is returned */
char * catDirAndFileName(Directory * dir, char * filename); char * catDirAndFileName(Directory * dir, char * filename);
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#define SONG_KEY "key: " #define SONG_KEY "key: "
#define SONG_FILE "file: " #define SONG_FILE "file: "
#define SONG_TIME "Time: " #define SONG_TIME "Time: "
#define SONG_MTIME "Mtime: " #define SONG_MTIME "mtime: "
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
...@@ -83,6 +83,7 @@ void freeJustSong(Song * song) { ...@@ -83,6 +83,7 @@ void freeJustSong(Song * song) {
free(song->url); free(song->url);
if(song->tag) freeMpdTag(song->tag); if(song->tag) freeMpdTag(song->tag);
free(song); free(song);
getSongUrl(NULL);
} }
SongList * newSongList() { SongList * newSongList() {
...@@ -118,8 +119,8 @@ void freeSongList(SongList * list) { ...@@ -118,8 +119,8 @@ void freeSongList(SongList * list) {
void printSongUrl(FILE * fp, Song * song) { void printSongUrl(FILE * fp, Song * song) {
if(song->parentDir) { if(song->parentDir) {
myfprintf(fp, "%s%s/%s\n", SONG_FILE, song->parentDir->utf8name, myfprintf(fp, "%s%s/%s\n", SONG_FILE,
song->url); getDirectoryPath(song->parentDir), song->url);
} }
else { else {
myfprintf(fp, "%s%s\n", SONG_FILE, song->url); myfprintf(fp, "%s%s\n", SONG_FILE, song->url);
...@@ -299,6 +300,8 @@ Song * songDup(Song * song) { ...@@ -299,6 +300,8 @@ Song * songDup(Song * song) {
return ret; return ret;
} }
/* pass song = NULL to reset, we do this freeJustSong(), so that if
* we free and recreate this memory we make sure to print it correctly*/
char * getSongUrl(Song * song) { char * getSongUrl(Song * song) {
static char * buffer = NULL; static char * buffer = NULL;
static int bufferSize = 0; static int bufferSize = 0;
...@@ -307,13 +310,18 @@ char * getSongUrl(Song * song) { ...@@ -307,13 +310,18 @@ char * getSongUrl(Song * song) {
int dlen; int dlen;
int size; int size;
if(!song->parentDir || !song->parentDir->utf8name) return song->url; if(!song) {
lastSong = song;
return NULL;
}
if(!song->parentDir || !song->parentDir->name) return song->url;
/* be careful with this! */ /* be careful with this!*/
if(song == lastSong) return buffer; if(song == lastSong) return buffer;
slen = strlen(song->url); slen = strlen(song->url);
dlen = strlen(song->parentDir->utf8name); dlen = strlen(getDirectoryPath(song->parentDir));
size = slen+dlen+2; size = slen+dlen+2;
...@@ -322,7 +330,7 @@ char * getSongUrl(Song * song) { ...@@ -322,7 +330,7 @@ char * getSongUrl(Song * song) {
bufferSize = size; bufferSize = size;
} }
strcpy(buffer, song->parentDir->utf8name); strcpy(buffer, getDirectoryPath(song->parentDir));
buffer[dlen] = '/'; buffer[dlen] = '/';
strcpy(buffer+dlen+1, song->url); strcpy(buffer+dlen+1, song->url);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment