remove insertion sort for performance reasons
This commit is contained in:
parent
ceb2f8cfc9
commit
e600a30528
161
src/db-gdbm.c
161
src/db-gdbm.c
|
@ -23,6 +23,7 @@
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#undef WANT_SORT
|
||||||
#define _XOPEN_SOURCE 600
|
#define _XOPEN_SOURCE 600
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -125,7 +126,7 @@ typedef struct tag_mp3packed {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
MP3RECORD* root;
|
MP3RECORD* root;
|
||||||
MP3RECORD* next;
|
MP3RECORD* next;
|
||||||
} MP3HELPER;;
|
} MP3HELPER;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Globals
|
* Globals
|
||||||
|
@ -744,7 +745,9 @@ int db_unpackrecord(datum *pdatum, MP3FILE *pmp3) {
|
||||||
* add an MP3 file to the database.
|
* add an MP3 file to the database.
|
||||||
*
|
*
|
||||||
* FIXME: Like the playlist adds, this assumes that this will only be called
|
* FIXME: Like the playlist adds, this assumes that this will only be called
|
||||||
* during a db_update... that the writelock is already held
|
* during a db_update... that the writelock is already held. This wouldn't
|
||||||
|
* necessarily be that case if, say, we were doing an add from the web interface.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
int db_add(MP3FILE *pmp3) {
|
int db_add(MP3FILE *pmp3) {
|
||||||
int err;
|
int err;
|
||||||
|
@ -842,6 +845,8 @@ int compare(MP3RECORD* a, MP3RECORD* b)
|
||||||
return a->mp3file.id - b->mp3file.id;
|
return a->mp3file.id - b->mp3file.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WANT_SORT
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* db_enum_begin
|
* db_enum_begin
|
||||||
*
|
*
|
||||||
|
@ -857,13 +862,19 @@ int compare(MP3RECORD* a, MP3RECORD* b)
|
||||||
*
|
*
|
||||||
* this should be done quickly, as we'll be holding
|
* this should be done quickly, as we'll be holding
|
||||||
* a reader lock on the db
|
* a reader lock on the db
|
||||||
|
*
|
||||||
|
* RP: Changed the read lock to a write lock, to serialize
|
||||||
|
* enums. On a background scan with multiple clients, the
|
||||||
|
* cost of doing multiple insertion sorts on the database simultaneously
|
||||||
|
* is way too painful. Particularly on embedded device
|
||||||
|
* like the NSLU2.
|
||||||
*/
|
*/
|
||||||
ENUMHANDLE db_enum_begin(void) {
|
ENUMHANDLE db_enum_begin(void) {
|
||||||
int err;
|
int err;
|
||||||
MP3HELPER* helper;
|
MP3HELPER* helper;
|
||||||
datum key, next;
|
datum key, next;
|
||||||
|
|
||||||
db_readlock();
|
db_writelock();
|
||||||
|
|
||||||
helper = calloc(1, sizeof(MP3HELPER));
|
helper = calloc(1, sizeof(MP3HELPER));
|
||||||
|
|
||||||
|
@ -893,10 +904,106 @@ ENUMHANDLE db_enum_begin(void) {
|
||||||
free(key.dptr);
|
free(key.dptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db_unlock();
|
||||||
helper->next = helper->root;
|
helper->next = helper->root;
|
||||||
|
|
||||||
return helper;
|
return helper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* db_enum
|
||||||
|
*
|
||||||
|
* Walk to the next entry
|
||||||
|
*/
|
||||||
|
MP3FILE *db_enum(ENUMHANDLE *current) {
|
||||||
|
MP3HELPER* helper;
|
||||||
|
MP3RECORD* record;
|
||||||
|
|
||||||
|
if(!current)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
helper = *(MP3HELPER**) current;
|
||||||
|
record = helper->next;
|
||||||
|
|
||||||
|
if(helper->next == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
helper->next = helper->next->next;
|
||||||
|
|
||||||
|
return &record->mp3file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* db_enum_end
|
||||||
|
*
|
||||||
|
* dispose of the list we built up in db_enum_begin, the lock's
|
||||||
|
* already been released.
|
||||||
|
*/
|
||||||
|
int db_enum_end(ENUMHANDLE handle) {
|
||||||
|
MP3HELPER* helper = (MP3HELPER*) handle;
|
||||||
|
MP3RECORD* record;
|
||||||
|
|
||||||
|
while(helper->root)
|
||||||
|
{
|
||||||
|
MP3RECORD* record = helper->root;
|
||||||
|
|
||||||
|
helper->root = record->next;
|
||||||
|
|
||||||
|
db_freefile(&record->mp3file);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(helper);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else /* Don't WANT_SORT */
|
||||||
|
|
||||||
|
ENUMHANDLE db_enum_begin(void) {
|
||||||
|
int err;
|
||||||
|
datum *pkey;
|
||||||
|
|
||||||
|
pkey=(datum *)malloc(sizeof(datum));
|
||||||
|
if(!pkey)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
static datum key;
|
||||||
|
|
||||||
|
db_writelock();
|
||||||
|
|
||||||
|
*pkey=gdbm_firstkey(db_songs);
|
||||||
|
|
||||||
|
return (ENUMHANDLE)pkey;
|
||||||
|
}
|
||||||
|
|
||||||
|
MP3FILE *db_enum(ENUMHANDLE *current) {
|
||||||
|
datum *pkey = *current;
|
||||||
|
datum data;
|
||||||
|
static MP3FILE mp3;
|
||||||
|
|
||||||
|
if(pkey->dptr) {
|
||||||
|
data=gdbm_fetch(db_songs,*pkey);
|
||||||
|
if(!data.dptr)
|
||||||
|
DPRINTF(ERR_FATAL, "Cannot find item.... corrupt database?\n");
|
||||||
|
|
||||||
|
if(db_unpackrecord(&data,&mp3))
|
||||||
|
DPRINTF(ERR_FATAL,"Cannot unpack item... corrupt database?\n");
|
||||||
|
|
||||||
|
free(pkey->dptr);
|
||||||
|
*pkey = gdbm_nextkey(db_songs,*pkey);
|
||||||
|
|
||||||
|
return &mp3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int db_enum_end(ENUMHANDLE handle) {
|
||||||
|
db_unlock();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* WANT_SORT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* db_playlist_enum_begin
|
* db_playlist_enum_begin
|
||||||
*
|
*
|
||||||
|
@ -937,30 +1044,6 @@ ENUMHANDLE db_playlist_items_enum_begin(int playlistid) {
|
||||||
return current->nodes;
|
return current->nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* db_enum
|
|
||||||
*
|
|
||||||
* Walk to the next entry
|
|
||||||
*/
|
|
||||||
MP3FILE *db_enum(ENUMHANDLE *current) {
|
|
||||||
MP3HELPER* helper;
|
|
||||||
MP3RECORD* record;
|
|
||||||
|
|
||||||
if(!current)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
helper = *(MP3HELPER**) current;
|
|
||||||
record = helper->next;
|
|
||||||
|
|
||||||
if(helper->next == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
helper->next = helper->next->next;
|
|
||||||
|
|
||||||
return &record->mp3file;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* db_playlist_enum
|
* db_playlist_enum
|
||||||
*
|
*
|
||||||
|
@ -1007,30 +1090,6 @@ int db_playlist_items_enum(ENUMHANDLE* handle) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* db_enum_end
|
|
||||||
*
|
|
||||||
* dispose of the list we built up in db_enum_begin, the lock's
|
|
||||||
* already been released.
|
|
||||||
*/
|
|
||||||
int db_enum_end(ENUMHANDLE handle) {
|
|
||||||
MP3HELPER* helper = (MP3HELPER*) handle;
|
|
||||||
MP3RECORD* record;
|
|
||||||
|
|
||||||
while(helper->root)
|
|
||||||
{
|
|
||||||
MP3RECORD* record = helper->root;
|
|
||||||
|
|
||||||
helper->root = record->next;
|
|
||||||
|
|
||||||
db_freefile(&record->mp3file);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(helper);
|
|
||||||
|
|
||||||
db_unlock();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* db_playlist_enum_end
|
* db_playlist_enum_end
|
||||||
|
|
Loading…
Reference in New Issue