From 4ec3df033954d01663087011efecfca37749f965 Mon Sep 17 00:00:00 2001 From: Warren Dukes Date: Thu, 11 Nov 2004 02:36:25 +0000 Subject: implement saved memory by not storing full path git-svn-id: https://svn.musicpd.org/mpd/trunk@2601 09075e82-0dd4-0310-85a5-a0d7c8717e4f --- src/dbUtils.c | 27 +++++++++++++++-- src/dbUtils.h | 2 ++ src/directory.c | 18 +++++------ src/directory.h | 4 +++ src/main.c | 2 ++ src/player.c | 10 +++---- src/playlist.c | 27 +++++++---------- src/song.c | 92 ++++++++++++++++++++++++++++++++++++++------------------- src/song.h | 9 ++++-- 9 files changed, 124 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/dbUtils.c b/src/dbUtils.c index 63f1f33b..55791653 100644 --- a/src/dbUtils.c +++ b/src/dbUtils.c @@ -6,6 +6,7 @@ #include "playlist.h" #include "tag.h" #include "tagTracker.h" +#include "log.h" #define LOCATE_TAG_FILE_TYPE TAG_NUM_OF_ITEM_TYPES+10 #define LOCATE_TAG_FILE_KEY "filename" @@ -76,7 +77,7 @@ static inline int strstrSearchTag(Song * song, int type, char * str) { int ret = 0; if(type == LOCATE_TAG_FILE_TYPE) { - dup = strDupToUpper(song->utf8url); + dup = strDupToUpper(getSongUrl(song)); if(strstr(dup, str)) ret = 1; free(dup); return ret; @@ -122,7 +123,7 @@ static inline int tagItemFoundAndMatches(Song * song, int type, char * str) { int i; if(type == LOCATE_TAG_FILE_TYPE) { - if(0 == strcmp(str, song->utf8url)) return 1; + if(0 == strcmp(str, getSongUrl(song))) return 1; } if(!song->tag) return 0; @@ -217,7 +218,7 @@ void printUnvisitedTags(FILE * fp, Song * song, int tagType) { MpdTag * tag = song->tag; if(tagType == LOCATE_TAG_FILE_TYPE) { - myfprintf(fp, "file: %s\n", song->utf8url); + printSongUrl(fp, song); return; } @@ -268,3 +269,23 @@ int listAllUniqueTags(FILE * fp, int type, int numConditionals, return ret; } + +int sumSavedMemoryInDirectory(FILE * fp, Directory * dir, void * data) { + int * sum = data; + + if(!dir->utf8name) return 0; + + *sum += (strlen(dir->utf8name)+1-sizeof(Directory *))* + dir->songs->numberOfNodes; + + return 0; +} + +void printSavedMemoryFromFilenames() { + int sum; + + traverseAllIn(stderr, NULL, NULL, sumSavedMemoryInDirectory, + (void *)&sum); + + DEBUG("saved memory from filenames: %i\n", sum); +} diff --git a/src/dbUtils.h b/src/dbUtils.h index 20d80f99..df5a7165 100644 --- a/src/dbUtils.h +++ b/src/dbUtils.h @@ -36,4 +36,6 @@ unsigned long sumSongTimesIn(FILE * fp, char * name); int listAllUniqueTags(FILE * fp, int type, int numConditiionals, LocateTagItem * conditionals); +void printSavedMemoryFromFilenames(); + #endif diff --git a/src/directory.c b/src/directory.c index 5ac78afa..18c0b7c9 100644 --- a/src/directory.c +++ b/src/directory.c @@ -280,8 +280,8 @@ void removeSongFromDirectory(Directory * directory, char * shortname) { void * song; if(findInList(directory->songs,shortname,&song)) { - LOG("removing: %s\n",((Song *)song)->utf8url); - deleteFromList(directory->songs,shortname); + LOG("removing: %s\n", getSongUrl((Song *)song)); + deleteFromList(directory->songs, shortname); } } @@ -317,7 +317,7 @@ int updateInDirectory(Directory * directory, char * shortname, char * name) { if(S_ISREG(st.st_mode) && hasMusicSuffix(name)) { if(0==findInList(directory->songs,shortname,&song)) { - addToDirectory(directory,shortname,name); + addToDirectory(directory, shortname, name); return DIRECTORY_RETURN_UPDATE; } else if(st.st_mtime!=((Song *)song)->mtime) { @@ -540,7 +540,7 @@ int updatePath(char * utf8path) { parentDirectory->parent, parentDirectory->stat->inode, parentDirectory->stat->device) && - song && isMusic(song->utf8url,&mtime)) + song && isMusic(getSongUrl(song), &mtime)) { free(path); if(song->mtime==mtime) return 0; @@ -553,7 +553,7 @@ int updatePath(char * utf8path) { } /* if updateDirectory fials, means we should delete it */ else { - removeSongFromDirectory(parentDirectory,shortname); + removeSongFromDirectory(parentDirectory, shortname); ret = 1; /* don't return, path maybe a directory now*/ } @@ -749,10 +749,10 @@ int addToDirectory(Directory * directory, char * shortname, char * name) { if(S_ISREG(st.st_mode) && hasMusicSuffix(name)) { Song * song; - song = addSongToList(directory->songs,shortname,name, - SONG_TYPE_FILE); + song = addSongToList(directory->songs, shortname, name, + SONG_TYPE_FILE, directory); if(!song) return -1; - LOG("added %s\n",name); + LOG("added %s\n", name); return 1; } else if(S_ISDIR(st.st_mode)) { @@ -935,7 +935,7 @@ void readDirectoryInfo(FILE * fp,Directory * directory) { readDirectoryInfo(fp,subDirectory); } else if(0==strncmp(SONG_BEGIN,buffer,strlen(SONG_BEGIN))) { - readSongInfoIntoList(fp,directory->songs); + readSongInfoIntoList(fp, directory->songs, directory); } else { ERROR("Unknown line in db: %s\n",buffer); diff --git a/src/directory.h b/src/directory.h index b0b2c843..a607d254 100644 --- a/src/directory.h +++ b/src/directory.h @@ -74,4 +74,8 @@ int traverseAllIn(FILE * fp, char * name, int (*forEachSong)(FILE *, Song *, void *), int (*forEachDir)(FILE *, Directory *, void *), void * data); + +/* free the string that is returned */ +char * catDirAndFileName(Directory * dir, char * filename); + #endif diff --git a/src/main.c b/src/main.c index 65557a4b..e1b71189 100644 --- a/src/main.c +++ b/src/main.c @@ -36,6 +36,7 @@ #include "inputStream.h" #include "tag.h" #include "tagTracker.h" +#include "dbUtils.h" #include "../config.h" #include @@ -431,6 +432,7 @@ int main(int argc, char * argv[]) { initInputStream(); printMemorySavedByTagTracker(); + printSavedMemoryFromFilenames(); daemonize(&options); diff --git a/src/player.c b/src/player.c index 5b829897..e398323e 100644 --- a/src/player.c +++ b/src/player.c @@ -179,7 +179,7 @@ int playerPlay(FILE * fp, Song * song) { copyMpdTagToMetadataChunk(song->tag, &(pc->fileMetadataChunk)); - strncpy(pc->utf8url, song->utf8url, MAXPATHLEN); + strncpy(pc->utf8url, getSongUrl(song), MAXPATHLEN); pc->utf8url[MAXPATHLEN] = '\0'; pc->play = 1; @@ -324,7 +324,7 @@ int queueSong(Song * song) { PlayerControl * pc = &(getPlayerData()->playerControl); if(pc->queueState==PLAYER_QUEUE_BLANK) { - strncpy(pc->utf8url, song->utf8url, MAXPATHLEN); + strncpy(pc->utf8url, getSongUrl(song), MAXPATHLEN); pc->utf8url[MAXPATHLEN] = '\0'; if(song->tag) pc->fileTime = song->tag->time; @@ -380,13 +380,13 @@ int playerSeek(FILE * fp, Song * song, float time) { return -1; } - if(strcmp(pc->utf8url, song->utf8url)!=0) { + if(strcmp(pc->utf8url, getSongUrl(song))!=0) { if(song->tag) pc->fileTime = song->tag->time; else pc->fileTime = 0; copyMpdTagToMetadataChunk(song->tag, &(pc->fileMetadataChunk)); - strncpy(pc->utf8url, song->utf8url, MAXPATHLEN); + strncpy(pc->utf8url, getSongUrl(song), MAXPATHLEN); pc->utf8url[MAXPATHLEN] = '\0'; } @@ -476,7 +476,7 @@ Song * playerCurrentDecodeSong() { memcpy(prev, &(pc->metadataChunk), sizeof(MetadataChunk)); if(song) freeJustSong(song); song = newNullSong(); - song->utf8url = strdup(pc->currentUrl); + song->url = strdup(pc->currentUrl); song->tag = metadataChunkToMpdTagDup(prev); ret = song; resetPlayerMetadata(); diff --git a/src/playlist.c b/src/playlist.c index ea88ef18..d7a946e2 100644 --- a/src/playlist.c +++ b/src/playlist.c @@ -245,7 +245,7 @@ int showPlaylist(FILE * fp) { int i; for(i=0;iutf8url); + myfprintf(fp,"%i:%s\n", i, getSongUrl(playlist.songs[i])); } return 0; @@ -428,12 +428,7 @@ void readPlaylistState() { } void printPlaylistSongInfo(FILE * fp, int song) { - MpdTag * tag; - - myfprintf(fp, "file: %s\n", (playlist.songs[song])->utf8url); - if((tag = (playlist.songs[song])->tag)) { - printMpdTag(fp, tag); - } + printSongInfo(fp, playlist.songs[song]); myfprintf(fp, "Pos: %i\n", song); myfprintf(fp, "Id: %i\n", playlist.positionToId[song]); } @@ -523,8 +518,8 @@ void queueNextSongInPlaylist() { playlist.queued = playlist.current+1; DEBUG("playlist: queue song %i:\"%s\"\n", playlist.queued, - playlist.songs[playlist.order[ - playlist.queued]]->utf8url); + getSongUrl(playlist.songs[playlist.order[ + playlist.queued]])); if(queueSong(playlist.songs[playlist.order[playlist.queued]]) < 0) { @@ -539,8 +534,8 @@ void queueNextSongInPlaylist() { playlist.queued = 0; DEBUG("playlist: queue song %i:\"%s\"\n", playlist.queued, - playlist.songs[playlist.order[ - playlist.queued]]->utf8url); + getSongUrl(playlist.songs[playlist.order[ + playlist.queued]])); if(queueSong(playlist.songs[playlist.order[playlist.queued]]) < 0) { @@ -603,7 +598,7 @@ int addToPlaylist(FILE * fp, char * url, int printId) { if((song = getSongFromDB(url))) { } else if(isValidRemoteUtf8Url(url) && - (song = newSong(url,SONG_TYPE_URL))) + (song = newSong(url, SONG_TYPE_URL, NULL))) { } else { @@ -836,7 +831,7 @@ int playPlaylistOrderNumber(FILE * fp, int orderNum) { playlist_queueError = 0; DEBUG("playlist: play %i:\"%s\"\n",orderNum, - (playlist.songs[playlist.order[orderNum]])->utf8url); + getSongUrl(playlist.songs[playlist.order[orderNum]])); if(playerPlay(fp,(playlist.songs[playlist.order[orderNum]])) < 0) { stopPlaylist(fp); @@ -917,7 +912,7 @@ void syncCurrentPlayerDecodeMetadata() { song = playlist.songs[songNum]; if(song->type == SONG_TYPE_URL && - 0 == strcmp(song->utf8url, songPlayer->utf8url) && + 0 == strcmp(getSongUrl(song), songPlayer->url) && !mpdTagsAreEqual(song->tag, songPlayer->tag)) { if(song->tag) freeMpdTag(song->tag); @@ -1321,10 +1316,10 @@ int savePlaylist(FILE * fp, char * utf8file) { playlist.songs[i]->type==SONG_TYPE_FILE) { myfprintf(fileP,"%s\n",rmp2amp(utf8ToFsCharset(( - playlist.songs[i])->utf8url))); + getSongUrl(playlist.songs[i]))))); } else myfprintf(fileP,"%s\n", - utf8ToFsCharset((playlist.songs[i])->utf8url)); + utf8ToFsCharset(getSongUrl(playlist.songs[i]))); } while(fclose(fileP) && errno==EINTR); diff --git a/src/song.c b/src/song.c index 44afcbe4..5e35ecb2 100644 --- a/src/song.c +++ b/src/song.c @@ -29,16 +29,17 @@ #define SONG_KEY "key: " #define SONG_FILE "file: " #define SONG_TIME "Time: " -#define SONG_MTIME "mtime: " +#define SONG_MTIME "Mtime: " #include #include +#include Song * newNullSong() { Song * song = malloc(sizeof(Song)); song->tag = NULL; - song->utf8url = NULL; + song->url = NULL; song->type = SONG_TYPE_FILE; song->parentDir = NULL; @@ -48,11 +49,11 @@ Song * newNullSong() { Song * newSong(char * url, int type, Directory * parentDir) { Song * song = NULL; - if(strchr(utf8url, '\n')) return NULL; + if(strchr(url, '\n')) return NULL; song = newNullSong(); - song->utf8url = strdup(utf8url); + song->url = strdup(url); song->type = type; song->parentDir = parentDir; @@ -60,9 +61,9 @@ Song * newSong(char * url, int type, Directory * parentDir) { if(song->type == SONG_TYPE_FILE) { InputPlugin * plugin; - if((plugin = isMusic(utf8url,&(song->mtime)))) { + if((plugin = isMusic(getSongUrl(song), &(song->mtime)))) { song->tag = plugin->tagDupFunc( - rmp2amp(utf8ToFsCharset(utf8url))); + rmp2amp(utf8ToFsCharset(getSongUrl(song)))); } if(!song->tag || song->tag->time<0) { freeSong(song); @@ -75,13 +76,11 @@ Song * newSong(char * url, int type, Directory * parentDir) { void freeSong(Song * song) { deleteASongFromPlaylist(song); - free(song->utf8url); - if(song->tag) freeMpdTag(song->tag); - free(song); + freeJustSong(song); } void freeJustSong(Song * song) { - free(song->utf8url); + free(song->url); if(song->tag) freeMpdTag(song->tag); free(song); } @@ -90,19 +89,19 @@ SongList * newSongList() { return makeList((ListFreeDataFunc *)freeSong); } -Song * addSongToList(SongList * list, char * url, int songType, - Directory * parentDirectory) +Song * addSongToList(SongList * list, char * url, char * utf8path, + int songType, Directory * parentDirectory) { Song * song = NULL; - switch(type) { + switch(songType) { case SONG_TYPE_FILE: - if(isMusic(utf8url,NULL)) { - song = newSong(url, type, parentDirectory); + if(isMusic(utf8path, NULL)) { + song = newSong(url, songType, parentDirectory); } break; case SONG_TYPE_URL: - song = newSong(utf8url, type, parentDirectory); + song = newSong(url, songType, parentDirectory); break; } @@ -119,7 +118,7 @@ void freeSongList(SongList * list) { void printSongUrl(FILE * fp, Song * song) { if(song->parentDir) { - myfprintf(fp, "%s%s%s\n", SONG_FILE, song->parentDir->utf8name, + myfprintf(fp, "%s%s/%s\n", SONG_FILE, song->parentDir->utf8name, song->url); } else { @@ -208,11 +207,10 @@ static int matchesAnMpdTagItemKey(char * buffer, int * itemType) { return 0; } -void readSongInfoIntoList(FILE * fp, SongList * list) { +void readSongInfoIntoList(FILE * fp, SongList * list, Directory * parentDir) { char buffer[MAXPATHLEN+1024]; int bufferSize = MAXPATHLEN+1024; Song * song = NULL; - char * key = NULL; ListNode * nextSongNode = list->firstNode; ListNode * nodeTemp; int itemType; @@ -220,21 +218,25 @@ void readSongInfoIntoList(FILE * fp, SongList * list) { while(myFgets(buffer,bufferSize,fp) && 0!=strcmp(SONG_END,buffer)) { if(0==strncmp(SONG_KEY,buffer,strlen(SONG_KEY))) { if(song) { - insertSongIntoList(list,&nextSongNode,key,song); + insertSongIntoList(list,&nextSongNode, + song->url, + song); song = NULL; - free(key); } - key = strdup(&(buffer[strlen(SONG_KEY)])); song = newNullSong(); + song->url = strdup(buffer+strlen(SONG_KEY)); song->type = SONG_TYPE_FILE; + song->parentDir = parentDir; } else if(0==strncmp(SONG_FILE,buffer,strlen(SONG_FILE))) { - if(!song || song->utf8url) { + if(!song) { ERROR("Problems reading song info\n"); exit(EXIT_FAILURE); } - song->utf8url = strdup(&(buffer[strlen(SONG_FILE)])); + /* we don't need this info anymore + song->url = strdup(&(buffer[strlen(SONG_FILE)])); + */ } else if(matchesAnMpdTagItemKey(buffer, &itemType)) { if(!song->tag) song->tag = newMpdTag(); @@ -255,9 +257,8 @@ void readSongInfoIntoList(FILE * fp, SongList * list) { } if(song) { - insertSongIntoList(list,&nextSongNode,key,song); + insertSongIntoList(list, &nextSongNode, song->url, song); song = NULL; - free(key); } while(nextSongNode) { @@ -268,8 +269,6 @@ void readSongInfoIntoList(FILE * fp, SongList * list) { } int updateSongInfo(Song * song) { - char * utf8url = song->utf8url; - if(song->type == SONG_TYPE_FILE) { InputPlugin * plugin; @@ -277,9 +276,9 @@ int updateSongInfo(Song * song) { song->tag = NULL; - if((plugin = isMusic(utf8url,&(song->mtime)))) { + if((plugin = isMusic(getSongUrl(song),&(song->mtime)))) { song->tag = plugin->tagDupFunc( - rmp2amp(utf8ToFsCharset(utf8url))); + rmp2amp(getSongUrl(song))); } if(!song->tag || song->tag->time<0) return -1; } @@ -290,10 +289,41 @@ int updateSongInfo(Song * song) { Song * songDup(Song * song) { Song * ret = malloc(sizeof(Song)); - ret->utf8url = strdup(song->utf8url); + ret->url = strdup(song->url); ret->mtime = song->mtime; ret->tag = mpdTagDup(song->tag); ret->type = song->type; + ret->parentDir = song->parentDir; return ret; } + +char * getSongUrl(Song * song) { + static char * buffer = NULL; + static int bufferSize = 0; + static Song * lastSong = NULL; + int slen; + int dlen; + int size; + + if(!song->parentDir || !song->parentDir->utf8name) return song->url; + + /* be careful with this! */ + if(song == lastSong) return buffer; + + slen = strlen(song->url); + dlen = strlen(song->parentDir->utf8name); + + size = slen+dlen+2; + + if(size > bufferSize) { + buffer = realloc(buffer, size); + bufferSize = size; + } + + strcpy(buffer, song->parentDir->utf8name); + buffer[dlen] = '/'; + strcpy(buffer+dlen+1, song->url); + + return buffer; +} diff --git a/src/song.h b/src/song.h index 45f9e792..81e5b550 100644 --- a/src/song.h +++ b/src/song.h @@ -45,7 +45,7 @@ typedef List SongList; Song * newNullSong(); -Song * newSong(char * utf8url, int songType, struct _Directory * parentDir); +Song * newSong(char * url, int songType, struct _Directory * parentDir); void freeSong(Song *); @@ -55,7 +55,7 @@ SongList * newSongList(); void freeSongList(SongList * list); -Song * addSongToList(SongList * list, char * key, char * utf8file, +Song * addSongToList(SongList * list, char * url, char * utf8path, int songType, struct _Directory * parentDir); int printSongInfo(FILE * fp, Song * song); @@ -64,7 +64,8 @@ int printSongInfoFromList(FILE * fp, SongList * list); void writeSongInfoFromList(FILE * fp, SongList * list); -void readSongInfoIntoList(FILE * fp, SongList * list); +void readSongInfoIntoList(FILE * fp, SongList * list, + struct _Directory * parent); int updateSongInfo(Song * song); @@ -72,4 +73,6 @@ Song * songDup(Song * song); void printSongUrl(FILE * fp, Song * song); +char * getSongUrl(Song * song); + #endif -- cgit v1.2.3