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

Reply via email to