* Fix false positives in playlist caching optimization when we have duplicate file names in different directories.

This commit is contained in:
Justin Maggard 2012-02-10 23:35:11 +00:00
parent 6064099fb0
commit ab33ab34bc
5 changed files with 54 additions and 18 deletions

2
NEWS
View File

@ -3,7 +3,7 @@
- Add support for other operating systems. - Add support for other operating systems.
- Switch to autoconf from our little genconfig.sh. - 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. - Enable the subtitle menu on some Samsung TV's.
- Add subtitle support for Panasonic TV's. - Add subtitle support for Panasonic TV's.

View File

@ -90,21 +90,6 @@ error:
return NULL; 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 */ /* And our main album art functions */
void void
update_if_album_art(const char *path) update_if_album_art(const char *path)

View File

@ -20,6 +20,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <libgen.h> #include <libgen.h>
#include <limits.h>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
@ -84,12 +85,36 @@ insert_playlist(const char * path, char * name)
return 0; 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 int
fill_playlists() fill_playlists()
{ {
int rows, i, found, len; int rows, i, found, len;
char **result; char **result;
char *plpath, *plname, *fname, *last_dir; char *plpath, *plname, *fname, *last_dir;
unsigned int hash, last_hash = 0;
char class[] = "playlistContainer"; char class[] = "playlistContainer";
struct song_metadata plist; struct song_metadata plist;
struct stat file; struct stat file;
@ -111,6 +136,7 @@ fill_playlists()
plname = result[++i]; plname = result[++i];
plpath = result[++i]; plpath = result[++i];
last_dir = NULL; last_dir = NULL;
last_hash = 0;
strncpy(type, strrchr(plpath, '.')+1, 4); strncpy(type, strrchr(plpath, '.')+1, 4);
@ -133,6 +159,7 @@ fill_playlists()
found = 0; found = 0;
while( next_plist_track(&plist, &file, NULL, type) == 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'", if( sql_get_int_field(db, "SELECT 1 from OBJECTS where OBJECT_ID = '%s$%llX$%d'",
MUSIC_PLIST_ID, plID, plist.track) == 1 ) MUSIC_PLIST_ID, plID, plist.track) == 1 )
{ {
@ -143,8 +170,13 @@ fill_playlists()
} }
if( last_dir ) if( last_dir )
{ {
fname = basename(plist.path); if( hash == last_hash )
detailID = sql_get_int_field(db, "SELECT ID from DETAILS where PATH = '%q/%q'", last_dir, fname); {
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 ) if( detailID <= 0 )
{ {
sqlite3_free(last_dir); sqlite3_free(last_dir);
@ -192,6 +224,7 @@ found:
fname = strrchr(last_dir, '/'); fname = strrchr(last_dir, '/');
if( fname ) if( fname )
*fname = '\0'; *fname = '\0';
last_hash = hash;
} }
found++; found++;
} }

15
utils.c
View File

@ -253,6 +253,21 @@ make_dir(char * path, mode_t mode)
} while (1); } 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 int
is_video(const char * file) is_video(const char * file)
{ {

View File

@ -51,6 +51,9 @@ strip_ext(char * name);
int int
make_dir(char * path, mode_t mode); make_dir(char * path, mode_t mode);
unsigned int
DJBHash(const char *str, int len);
int int
is_video(const char * file); is_video(const char * file);