Revision: 2263
http://gtkpod.svn.sourceforge.net/gtkpod/?rev=2263&view=rev
Author: teuf
Date: 2009-02-28 10:40:22 +0000 (Sat, 28 Feb 2009)
Log Message:
-----------
Avoid linked list scans in get_playlist/get_mhip.
Replaced code that scanned the linked list twice on each insertion (once for
sorting, once for finding the previous insert position) by a single sort and
scan at the end.
As a side-effect removed dependency of get_mhip on Itdb structures (easier to
unittest, etc.).
Modified Paths:
--------------
libgpod/trunk/ChangeLog
libgpod/trunk/src/itdb_itunesdb.c
libgpod/trunk/src/itdb_private.h
Modified: libgpod/trunk/ChangeLog
===================================================================
--- libgpod/trunk/ChangeLog 2009-02-28 10:39:39 UTC (rev 2262)
+++ libgpod/trunk/ChangeLog 2009-02-28 10:40:22 UTC (rev 2263)
@@ -1,5 +1,17 @@
2009-02-28 Javier Kohen <[email protected]>
+ * src/itdb_itunesdb.c:
+ * src/itdb_private.h: avoid linked list scans in get_playlist/get_mhip.
+
+ Replaced code that scanned the linked list twice on each
+ insertion (once for sorting, once for finding the previous
+ insert position) by a single sort and scan at the end.
+
+ As a side-effect removed dependency of get_mhip on Itdb
+ structures (easier to unittest, etc.).
+
+2009-02-28 Javier Kohen <[email protected]>
+
* src/db-artwork-parser: replace linear look-up of songs with
local hashtable.
Modified: libgpod/trunk/src/itdb_itunesdb.c
===================================================================
--- libgpod/trunk/src/itdb_itunesdb.c 2009-02-28 10:39:39 UTC (rev 2262)
+++ libgpod/trunk/src/itdb_itunesdb.c 2009-02-28 10:40:22 UTC (rev 2263)
@@ -286,6 +286,13 @@
typedef struct _MHODData MHODData;
+struct _PosEntry {
+ guint32 trackid;
+ gint32 track_pos;
+};
+
+typedef struct _PosEntry PosEntry;
+
/* Declarations */
static gboolean itdb_create_directories (Itdb_Device *device, GError **error);
@@ -1861,31 +1868,34 @@
}
+static gint pos_comp (gconstpointer a, gconstpointer b)
+{
+ const PosEntry *pa = (const PosEntry*)a;
+ const PosEntry *pb = (const PosEntry*)b;
-static gint pos_comp (gpointer a, gpointer b);
-static gint pos_comp (gpointer a, gpointer b)
-{
- return (GPOINTER_TO_UINT(a) - GPOINTER_TO_UINT(b));
+ if (pa->track_pos < pb->track_pos)
+ return -1;
+ else if (pa->track_pos > pb->track_pos)
+ return 1;
+ else
+ return 0;
}
/* Read and process the mhip at @seek. Return a pointer to the next
possible mhip. */
/* Return value: -1 if no mhip is present at @seek */
-static glong get_mhip (FImport *fimp, Itdb_Playlist *plitem,
- glong mhip_seek)
+static glong get_mhip (FImport *fimp, glong mhip_seek)
{
gboolean first_entry = TRUE;
FContents *cts;
guint32 mhip_hlen, mhip_len, mhod_num, mhod_seek;
- Itdb_Track *tr;
- gint32 i, pos=-1;
+ gint32 i;
gint32 mhod_type;
guint32 trackid;
g_return_val_if_fail (fimp, -1);
- g_return_val_if_fail (plitem, -1);
cts = fimp->fcontents;
@@ -1934,23 +1944,12 @@
MHODData mhod;
mhod = get_mhod (fimp, mhod_seek, &mhod_len);
CHECK_ERROR (fimp, -1);
- pos = -1;
if (mhod.valid && first_entry)
{
- /* The posids don't have to be in numeric order, but our
- database depends on the playlist members being sorted
- according to the order they appear in the
- playlist. Therefore we need to find out at which
- position to insert the track */
- fimp->pos_glist = g_list_insert_sorted (
- fimp->pos_glist,
- GUINT_TO_POINTER(mhod.data.track_pos),
- (GCompareFunc)pos_comp);
- pos = g_list_index (
- fimp->pos_glist,
- GUINT_TO_POINTER(mhod.data.track_pos));
- /* for speedup: pos==-1 is appending at the end */
- if (pos == fimp->pos_len) pos = -1;
+ PosEntry *entry = g_new(PosEntry, 1);
+ entry->trackid = trackid;
+ entry->track_pos = mhod.data.track_pos;
+ fimp->pos_glist = g_list_prepend (fimp->pos_glist, entry);
/* don't call this section more than once (it never
should happen except in the case of corrupted
iTunesDBs...) */
@@ -1969,20 +1968,6 @@
mhod_seek += mhod_len;
}
- tr = itdb_track_id_tree_by_id (fimp->idtree, trackid);
- if (tr)
- {
- itdb_playlist_add_track (plitem, tr, pos);
- ++fimp->pos_len;
- }
- else
- {
- if (plitem->podcastflag == ITDB_PL_FLAG_NORM)
- {
- g_warning (_("Itdb_Track ID '%d' not found.\n"), trackid);
- }
- }
-
/* Up to iTunesd V4.7 or so the mhip_len was set incorrectly
(mhip_len == mhip_hlen). In that case we need to find the seek
to the next mhip by going through all mhods.
@@ -2007,6 +1992,8 @@
guint32 header_len;
Itdb_Playlist *plitem = NULL;
FContents *cts;
+ GList *gl;
+ gint32 pos_len = 0;
#if ITUNESDB_DEBUG
fprintf(stderr, "mhyp seek: %x\n", (int)mhyp_seek);
@@ -2014,7 +2001,6 @@
g_return_val_if_fail (fimp, -1);
g_return_val_if_fail (fimp->idtree, -1);
g_return_val_if_fail (fimp->pos_glist == NULL, -1);
- g_return_val_if_fail (fimp->pos_len == 0, -1);
cts = fimp->fcontents;
@@ -2184,7 +2170,7 @@
i=0; /* tracks read */
for (i=0; i < mhipnum; ++i)
{
- mhip_seek = get_mhip (fimp, plitem, mhip_seek);
+ mhip_seek = get_mhip (fimp, mhip_seek);
if (mhip_seek == -1)
{
g_set_error (&fimp->error,
@@ -2196,10 +2182,28 @@
}
}
+ fimp->pos_glist = g_list_sort (fimp->pos_glist, pos_comp);
+ for (gl = fimp->pos_glist; gl; gl = g_list_next (gl))
+ {
+ PosEntry* entry = (PosEntry*)gl->data;
+ Itdb_Track *tr = itdb_track_id_tree_by_id (fimp->idtree, entry->trackid);
+ if (tr)
+ {
+ itdb_playlist_add_track (plitem, tr, pos_len);
+ ++pos_len;
+ }
+ else
+ {
+ if (plitem->podcastflag == ITDB_PL_FLAG_NORM)
+ {
+ g_warning (_("Itdb_Track ID '%d' not found.\n"), entry->trackid);
+ }
+ }
+ g_free(entry);
+ }
g_list_free (fimp->pos_glist);
fimp->pos_glist = NULL;
- fimp->pos_len = 0;
return nextseek;
}
Modified: libgpod/trunk/src/itdb_private.h
===================================================================
--- libgpod/trunk/src/itdb_private.h 2009-02-28 10:39:39 UTC (rev 2262)
+++ libgpod/trunk/src/itdb_private.h 2009-02-28 10:40:22 UTC (rev 2263)
@@ -71,7 +71,6 @@
Itdb_iTunesDB *itdb;
FContents *fcontents;
GList *pos_glist; /* temporary list to store position indicators */
- gint32 pos_len; /* current length of above list */
GList *playcounts; /* contents of Play Counts file */
GTree *idtree; /* temporary tree with track id tree */
GError *error; /* where to report errors to */
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
gtkpod-cvs2 mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2