From ab33ab34bc5689a3fb3e28168b17f1bdebf78986 Mon Sep 17 00:00:00 2001 From: Justin Maggard Date: Fri, 10 Feb 2012 23:35:11 +0000 Subject: [PATCH] * Fix false positives in playlist caching optimization when we have duplicate file names in different directories. --- NEWS | 2 +- albumart.c | 15 --------------- playlist.c | 37 +++++++++++++++++++++++++++++++++++-- utils.c | 15 +++++++++++++++ utils.h | 3 +++ 5 files changed, 54 insertions(+), 18 deletions(-) diff --git a/NEWS b/NEWS index ebb3c6c..5017bfa 100644 --- a/NEWS +++ b/NEWS @@ -3,7 +3,7 @@ - Add support for other operating systems. - Switch to autoconf from our little genconfig.sh. -1.0.23 - Released 00-Month-0000 +1.0.23 - Released 23-Jan-2012 -------------------------------- - Enable the subtitle menu on some Samsung TV's. - Add subtitle support for Panasonic TV's. diff --git a/albumart.c b/albumart.c index 3dde221..f78d2b7 100644 --- a/albumart.c +++ b/albumart.c @@ -90,21 +90,6 @@ error: return NULL; } -/* Simple, efficient hash function from Daniel J. Bernstein */ -static unsigned int -DJBHash(const char *str, int len) -{ - unsigned int hash = 5381; - unsigned int i = 0; - - for(i = 0; i < len; str++, i++) - { - hash = ((hash << 5) + hash) + (*str); - } - - return hash; -} - /* And our main album art functions */ void update_if_album_art(const char *path) diff --git a/playlist.c b/playlist.c index 47a06c3..6215fa1 100644 --- a/playlist.c +++ b/playlist.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -84,12 +85,36 @@ insert_playlist(const char * path, char * name) return 0; } +static unsigned int +gen_dir_hash(const char *path) +{ + char dir[PATH_MAX], *base; + int len; + + strncpy(dir, path, sizeof(dir)); + dir[sizeof(dir)-1] = '\0'; + base = strrchr(dir, '/'); + if( !base ) + base = strrchr(dir, '\\'); + if( base ) + { + *base = '\0'; + len = base - dir; + } + else + return 0; + + + return DJBHash(dir, len); +} + int fill_playlists() { int rows, i, found, len; char **result; char *plpath, *plname, *fname, *last_dir; + unsigned int hash, last_hash = 0; char class[] = "playlistContainer"; struct song_metadata plist; struct stat file; @@ -111,6 +136,7 @@ fill_playlists() plname = result[++i]; plpath = result[++i]; last_dir = NULL; + last_hash = 0; strncpy(type, strrchr(plpath, '.')+1, 4); @@ -133,6 +159,7 @@ fill_playlists() found = 0; while( next_plist_track(&plist, &file, NULL, type) == 0 ) { + hash = gen_dir_hash(plist.path); if( sql_get_int_field(db, "SELECT 1 from OBJECTS where OBJECT_ID = '%s$%llX$%d'", MUSIC_PLIST_ID, plID, plist.track) == 1 ) { @@ -143,8 +170,13 @@ fill_playlists() } if( last_dir ) { - fname = basename(plist.path); - detailID = sql_get_int_field(db, "SELECT ID from DETAILS where PATH = '%q/%q'", last_dir, fname); + if( hash == last_hash ) + { + fname = basename(plist.path); + detailID = sql_get_int_field(db, "SELECT ID from DETAILS where PATH = '%q/%q'", last_dir, fname); + } + else + detailID = -1; if( detailID <= 0 ) { sqlite3_free(last_dir); @@ -192,6 +224,7 @@ found: fname = strrchr(last_dir, '/'); if( fname ) *fname = '\0'; + last_hash = hash; } found++; } diff --git a/utils.c b/utils.c index 3c684d5..cda4c3d 100644 --- a/utils.c +++ b/utils.c @@ -253,6 +253,21 @@ make_dir(char * path, mode_t mode) } while (1); } +/* Simple, efficient hash function from Daniel J. Bernstein */ +unsigned int +DJBHash(const char *str, int len) +{ + unsigned int hash = 5381; + unsigned int i = 0; + + for(i = 0; i < len; str++, i++) + { + hash = ((hash << 5) + hash) + (*str); + } + + return hash; +} + int is_video(const char * file) { diff --git a/utils.h b/utils.h index 5a4e8c3..67790b5 100644 --- a/utils.h +++ b/utils.h @@ -51,6 +51,9 @@ strip_ext(char * name); int make_dir(char * path, mode_t mode); +unsigned int +DJBHash(const char *str, int len); + int is_video(const char * file);