]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Partial revert of previous multi-key update. I have decided to leave it to the upstre...
authorAdam Sutton <dev@adamsutton.me.uk>
Tue, 12 Jun 2012 12:05:39 +0000 (13:05 +0100)
committerAdam Sutton <dev@adamsutton.me.uk>
Mon, 30 Jul 2012 14:47:54 +0000 (15:47 +0100)
src/epg.c
src/epg.h
src/queue.h

index 6c0b4ca6dccc2181078bce0aca09b9519830b0c4..39625783bd8e5b7b582d40a5f41e8ca5aef9b1f6 100644 (file)
--- a/src/epg.c
+++ b/src/epg.c
 #define EPG_HASH_MASK  (EPG_HASH_WIDTH - 1)
 
 /* URI lists */
-epg_object_key_tree_t epg_brands;
-epg_object_key_tree_t epg_seasons;
-epg_object_key_tree_t epg_episodes;
+epg_object_tree_t epg_brands;
+epg_object_tree_t epg_seasons;
+epg_object_tree_t epg_episodes;
 
 /* Other special case lists */
-epg_object_list_t     epg_objects[EPG_HASH_WIDTH];
-epg_object_list_t     epg_object_unref;
-epg_object_list_t     epg_object_updated;
+epg_object_list_t epg_objects[EPG_HASH_WIDTH];
+epg_object_list_t epg_object_unref;
+epg_object_list_t epg_object_updated;
 
 /* Global counter */
 static uint64_t _epg_object_idx    = 0;
@@ -61,11 +61,6 @@ static int _uri_cmp ( const void *a, const void *b )
   return strcmp(((epg_object_t*)a)->uri, ((epg_object_t*)b)->uri);
 }
 
-static int _key_cmp ( const void *a, const void *b )
-{
-  return _uri_cmp(((epg_object_key_t*)a)->obj, ((epg_object_key_t*)b)->obj);
-}
-
 static int _ebc_start_cmp ( const void *a, const void *b )
 {
   return ((epg_broadcast_t*)a)->start - ((epg_broadcast_t*)b)->start;
@@ -99,44 +94,46 @@ static int _epg_write ( int fd, htsmsg_t *m )
   return ret;
 }
 
-#define _epg_write_sect(_fd, _total, _sect, _type, _type2, _pack)\
-{\
-  int i;\
-  epg_object_t *eo;\
-  htsmsg_t *m = htsmsg_create_map();\
-  htsmsg_add_str(m, "__section__", _sect);\
-  if (_epg_write(_fd, m)) return;\
-  for ( i = 0; i < EPG_HASH_WIDTH; i++ ) {\
-    LIST_FOREACH(eo, &epg_objects[i], hlink) {\
-      if (eo->type == _type) {\
-        if (_epg_write(_fd, _pack((_type2*)eo))) return;\
-        _total++;\
-      }\
-    }\
-  }\
+static int _epg_write_sect ( int fd, const char *sect )
+{
+  htsmsg_t *m = htsmsg_create_map();
+  htsmsg_add_str(m, "__section__", sect);
+  return _epg_write(fd, m);
 }
 
 void epg_save ( void )
 {
   int fd;
+  epg_object_t *eo;
+  epg_broadcast_t *ebc;
+  channel_t *ch;
   epggrab_stats_t stats;
   
   fd = hts_settings_open_file(1, "epgdb");
-  memset(&stats, 0, sizeof(stats));
 
-  /* Write each object type:
-   * Note: this is slightly inefficient (due to excessive looping)
-   *       but should be ok */
-  _epg_write_sect(fd, stats.brands.total, "brands", EPG_BRAND,
-                  epg_brand_t, epg_brand_serialize);
-  _epg_write_sect(fd, stats.seasons.total, "seasons", EPG_SEASON,
-                  epg_season_t, epg_season_serialize);
-  _epg_write_sect(fd, stats.episodes.total, "episodes", EPG_EPISODE,
-                  epg_episode_t, epg_episode_serialize);
-  _epg_write_sect(fd, stats.broadcasts.total, "broadcasts", EPG_BROADCAST,
-                  epg_broadcast_t, epg_broadcast_serialize);
-  // TODO: as I include the URI in the object I could use that to allow
-  //       me to only loop over the type lists
+  memset(&stats, 0, sizeof(stats));
+  if ( _epg_write_sect(fd, "brands") ) return;
+  RB_FOREACH(eo,  &epg_brands, glink) {
+    if (_epg_write(fd, epg_brand_serialize((epg_brand_t*)eo))) return;
+    stats.brands.total++;
+  }
+  if ( _epg_write_sect(fd, "seasons") ) return;
+  RB_FOREACH(eo,  &epg_seasons, glink) {
+    if (_epg_write(fd, epg_season_serialize((epg_season_t*)eo))) return;
+    stats.seasons.total++;
+  }
+  if ( _epg_write_sect(fd, "episodes") ) return;
+  RB_FOREACH(eo,  &epg_episodes, glink) {
+    if (_epg_write(fd, epg_episode_serialize((epg_episode_t*)eo))) return;
+    stats.episodes.total++;
+  }
+  if ( _epg_write_sect(fd, "broadcasts") ) return;
+  RB_FOREACH(ch, &channel_name_tree, ch_name_link) {
+    RB_FOREACH(ebc, &ch->ch_epg_schedule, glink) {
+      if (_epg_write(fd, epg_broadcast_serialize(ebc))) return;
+      stats.broadcasts.total++;
+    }
+  }
 
   /* Stats */
   tvhlog(LOG_INFO, "epg", "database saved");
@@ -274,16 +271,11 @@ void epg_updated ( void )
  * *************************************************************************/
 
 static void _epg_object_destroy 
-  ( epg_object_t *eo, epg_object_key_tree_t *tree )
+  ( epg_object_t *eo, epg_object_tree_t *tree )
 {
-  epg_object_key_t *ek;
   assert(eo->refcount == 0);
   if (eo->uri) free(eo->uri);
-  if (tree) {
-    LIST_FOREACH(ek, &eo->aliases, olink) {
-      RB_REMOVE(tree, ek, glink);
-    }
-  }
+  if (tree) RB_REMOVE(tree, eo, glink);
   if (eo->_updated) LIST_REMOVE(eo, uplink);
   LIST_REMOVE(eo, hlink);
 }
@@ -322,37 +314,31 @@ static void _epg_object_create ( epg_object_t *eo )
 
 static epg_object_t *_epg_object_find_by_uri 
   ( const char *uri, int create, int *save,
-    epg_object_key_tree_t *tree, epg_object_t **skel )
+    epg_object_tree_t *tree, epg_object_t **skel )
 {
-  static epg_object_key_t *ekskel = NULL;
-  epg_object_key_t *ek;
-  
+  epg_object_t *eo;
+
   assert(skel != NULL);
   lock_assert(&global_lock);
 
-  if (!ekskel) ekskel = calloc(1, sizeof(epg_object_key_t));
-  ekskel->uri = (char*)uri;
+  (*skel)->uri = (char*)uri;
 
   /* Find only */
   if ( !create ) {
-    ek = RB_FIND(tree, ekskel, glink, _key_cmp);
+    eo = RB_FIND(tree, *skel, glink, _uri_cmp);
   
   /* Find/create */
   } else {
-    ek = RB_INSERT_SORTED(tree, ekskel, glink, _key_cmp);
-    if ( !ek ) {
+    eo = RB_INSERT_SORTED(tree, *skel, glink, _uri_cmp);
+    if ( !eo ) {
       *save        = 1;
-      ek           = ekskel;
-      ek->uri      = strdup(uri);
-      ek->obj      = *skel;
-      ek->obj->uri = strdup(uri); // TODO: could not dup this!
-      LIST_INSERT_HEAD(&ek->obj->aliases, ek, olink);
-      _epg_object_create(ek->obj);
+      eo           = *skel;
       *skel        = NULL;
-      ekskel       = NULL;
+      eo->uri      = strdup(uri);
+      _epg_object_create(eo);
     }
   }
-  return ek ? ek->obj : NULL;
+  return eo;
 }
 
 static epg_object_t *_epg_object_find_by_id ( uint64_t id )
index a15c293eb687dadd4a8f8aa184ddee058a6112dd..3bcfdb53064acec4a6e4b32850b89db19a8f4187 100644 (file)
--- a/src/epg.h
+++ b/src/epg.h
@@ -31,8 +31,7 @@ struct channel_tag;
  * Map types
  */
 LIST_HEAD(epg_object_list,     epg_object);
-LIST_HEAD(epg_object_key_list, epg_object_key);
-RB_HEAD  (epg_object_key_tree, epg_object_key);
+RB_HEAD  (epg_object_tree,     epg_object);
 LIST_HEAD(epg_brand_list,      epg_brand);
 LIST_HEAD(epg_season_list,     epg_season);
 LIST_HEAD(epg_episode_list,    epg_episode);
@@ -43,7 +42,6 @@ RB_HEAD  (epg_broadcast_tree,  epg_broadcast);
  * Typedefs (most are redundant!)
  */
 typedef struct epg_object          epg_object_t;
-typedef struct epg_object_key      epg_object_key_t;
 typedef struct epg_brand           epg_brand_t;
 typedef struct epg_season          epg_season_t;
 typedef struct epg_episode         epg_episode_t;
@@ -53,25 +51,13 @@ typedef struct epg_episode_list    epg_episode_list_t;
 typedef struct epg_broadcast_list  epg_broadcast_list_t;
 typedef struct epg_broadcast_tree  epg_broadcast_tree_t;
 typedef struct epg_object_list     epg_object_list_t;
-typedef struct epg_object_key_tree epg_object_key_tree_t;
-typedef struct epg_object_key_list epg_object_key_list_t;
+typedef struct epg_object_tree     epg_object_tree_t;
 
 
 /* ************************************************************************
  * Generic Object
  * ***********************************************************************/
 
-/* Used to allow multiple keys per object */
-typedef struct epg_object_key
-{
-  LIST_ENTRY(epg_object_key) olink; ///< Link to object's list
-  RB_ENTRY(epg_object_key)   glink; ///< Link to global list
-
-  epg_object_t               *obj;  ///< Object we're wrapping
-  const char                 *uri;  ///< Object URI
-  // TODO: could make this union?
-} epg_object_key_t;
-
 /* Object type */
 typedef enum epg_object_type
 {
@@ -85,6 +71,7 @@ typedef enum epg_object_type
 /* Object */
 struct epg_object
 {
+  RB_ENTRY(epg_object)    glink;      ///< Global URI link
   LIST_ENTRY(epg_object)  hlink;      ///< Global (ID) link
   LIST_ENTRY(epg_object)  ulink;      ///< Global unref'd link
   LIST_ENTRY(epg_object)  uplink;     ///< Global updated link
@@ -92,7 +79,6 @@ struct epg_object
   epg_object_type_t       type;       ///< Specific object type
   uint64_t                id;         ///< Internal ID
   char                   *uri;        ///< Unique ID (from grabber)
-  epg_object_key_list_t   aliases;    ///< URI aliases (inc primary)
 
   int                     _updated;   ///< Flag to indicate updated
   int                     refcount;   ///< Reference counting
index fdb78e909c5dfa0281972489545688582b83872c..bf5a4de0679665573f9cfebdee10e66bcb6c7557 100644 (file)
         }                                                      \
 } while(0)
 
-#define LIST_FIND(head, skel, field, cmpfunc)\
-({\
-  typeof(skel) a, b = NULL;\
-  LIST_FOREACH(a, head, field) {\
-    if (!cmpfunc(skel, a)) {\
-      b = a;\
-      break;\
-    }\
-  }\
-  b;\
-})
-  
 #define TAILQ_INSERT_SORTED(head, elm, field, cmpfunc) do {    \
         if(TAILQ_FIRST(head) == NULL) {                                \
            TAILQ_INSERT_HEAD(head, elm, field);                        \