]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
idnode set: add sorted insert / lookup for bouquets
authorJaroslav Kysela <perex@perex.cz>
Wed, 5 Nov 2014 11:43:47 +0000 (12:43 +0100)
committerJaroslav Kysela <perex@perex.cz>
Sat, 8 Nov 2014 20:05:38 +0000 (21:05 +0100)
src/api/api_input.c
src/bouquet.c
src/idnode.c
src/idnode.h
src/input/mpegts/linuxdvb/linuxdvb_adapter.c
src/input/mpegts/linuxdvb/linuxdvb_frontend.c
src/input/mpegts/linuxdvb/linuxdvb_satconf.c
src/input/mpegts/satip/satip.c
src/input/mpegts/satip/satip_frontend.c
src/input/mpegts/satip/satip_satconf.c
src/input/mpegts/tvhdhomerun/tvhdhomerun.c

index 4152dbc6c229e7786fec83dca30a1605cefde368..a892c4b5497b97e2a62545a29deb180722d76465 100644 (file)
@@ -30,7 +30,7 @@ static idnode_set_t *
 api_input_hw_tree ( void )
 {
   tvh_hardware_t *th;
-  idnode_set_t *is = idnode_set_create();
+  idnode_set_t *is = idnode_set_create(0);
   TVH_HARDWARE_FOREACH(th)
     idnode_set_add(is, &th->th_id, NULL);
   return is;
index 5367131a432a1132ec8455e32382814345fa6a38..5308627b8f427312c9be88905d1614add3f5568f 100644 (file)
@@ -48,8 +48,8 @@ bouquet_create(const char *uuid, htsmsg_t *conf,
   lock_assert(&global_lock);
 
   bq = calloc(1, sizeof(bouquet_t));
-  bq->bq_services = idnode_set_create();
-  bq->bq_active_services = idnode_set_create();
+  bq->bq_services = idnode_set_create(1);
+  bq->bq_active_services = idnode_set_create(1);
 
   if (idnode_insert(&bq->bq_id, uuid, &bouquet_class, 0)) {
     if (uuid)
@@ -329,7 +329,7 @@ bouquet_completed(bouquet_t *bq)
             bq->bq_services->is_count);
 
   /* Add/Remove services */
-  remove = idnode_set_create();
+  remove = idnode_set_create(0);
   for (z = 0; z < bq->bq_services->is_count; z++)
     if (!idnode_set_exists(bq->bq_active_services, bq->bq_services->is_array[z]))
       idnode_set_add(remove, bq->bq_services->is_array[z], NULL);
@@ -354,7 +354,7 @@ bouquet_completed(bouquet_t *bq)
 
 
   idnode_set_free(bq->bq_active_services);
-  bq->bq_active_services = idnode_set_create();
+  bq->bq_active_services = idnode_set_create(1);
 
   if (bq->bq_saveflag)
     bouquet_save(bq, 1);
@@ -448,7 +448,7 @@ bouquet_class_delete(idnode_t *self)
     bouquet_destroy(bq);
   } else {
     idnode_set_free(bq->bq_services);
-    bq->bq_services = idnode_set_create();
+    bq->bq_services = idnode_set_create(1);
     bouquet_save(bq, 1);
   }
 }
index bf60af443815c63a51f6033d16c5ea787286cd85..a6672faf37970f2209d2f0055f75ad9db35ab463 100644 (file)
@@ -955,33 +955,54 @@ idnode_set_add
     is->is_alloc = MAX(100, is->is_alloc * 2);
     is->is_array = realloc(is->is_array, is->is_alloc * sizeof(idnode_t*));
   }
-  is->is_array[is->is_count++] = in;
+  if (is->is_sorted) {
+    size_t i;
+    idnode_t **a = is->is_array;
+    for (i = is->is_count++; i > 0 && a[i - 1] > in; i--)
+      a[i] = a[i - 1];
+    a[i] = in;
+  } else {
+    is->is_array[is->is_count++] = in;
+  }
 }
 
-void
-idnode_set_remove
+ssize_t
+idnode_set_find_index
   ( idnode_set_t *is, idnode_t *in )
 {
-  size_t z;
-
-  for (z = 0; z < is->is_count; z++)
-    if (is->is_array[z] == in) {
-      memmove(&is->is_array[z], &is->is_array[z+1],
-              (is->is_count - z - 1) * sizeof(idnode_t *));
-      is->is_count--;
-      break;
+  ssize_t i;
+
+  if (is->is_sorted) {
+    idnode_t **a = is->is_array;
+    ssize_t first = 0, last = is->is_count - 1;
+    i = last / 2;
+    while (first <= last) {
+      if (a[i] < in)
+        first = i + 1;
+      else if (a[i] == in)
+        return i;
+      else
+        last = i - 1;
+      i = (first + last) / 2;
     }
+  } else {
+    for (i = 0; i < is->is_count; i++)
+      if (is->is_array[i] == in)
+        return 1;
+  }
+  return -1;
 }
 
-int
-idnode_set_exists
-  ( idnode_set_t *is, idnode_t * in )
+void
+idnode_set_remove
+  ( idnode_set_t *is, idnode_t *in )
 {
-  int i;
-  for (i = 0; i < is->is_count; i++)
-    if (memcmp(is->is_array[i]->in_uuid, in->in_uuid, sizeof(in->in_uuid)) == 0)
-      return 1;
-  return 0;
+  ssize_t i = idnode_set_find_index(is, in);
+  if (i >= 0) {
+    memmove(&is->is_array[i], &is->is_array[i+1],
+            (is->is_count - i - 1) * sizeof(idnode_t *));
+    is->is_count--;
+  }
 }
 
 void
index 544e6f91e8cd881eb8ba9a03eb2e4017427dbbce..e59366fae2e20bb0958707eb2dd5083b51f2875b 100644 (file)
@@ -37,6 +37,7 @@ typedef struct idnode_set
   idnode_t **is_array;  ///< Array of nodes
   size_t     is_alloc;  ///< Size of is_array
   size_t     is_count;  ///< Current usage of is_array
+  uint8_t    is_sorted; ///< Sorted array of nodes
 } idnode_set_t;
 
 /*
@@ -197,11 +198,15 @@ void idnode_filter_clear
   (idnode_filter_t *f);
 int  idnode_filter
   ( idnode_t *in, idnode_filter_t *filt );
-#define idnode_set_create() calloc(1, sizeof(idnode_set_t))
+static inline idnode_set_t * idnode_set_create(int sorted)
+  { idnode_set_t *is = calloc(1, sizeof(idnode_set_t));
+    is->is_sorted = sorted; return is; }
 void idnode_set_add
   ( idnode_set_t *is, idnode_t *in, idnode_filter_t *filt );
 void idnode_set_remove ( idnode_set_t *is, idnode_t *in );
-int idnode_set_exists ( idnode_set_t *is, idnode_t *in );
+ssize_t idnode_set_find_index( idnode_set_t *is, idnode_t *in );
+static inline int idnode_set_exists ( idnode_set_t *is, idnode_t *in )
+  { return idnode_set_find_index(is, in) >= 0; }
 void idnode_set_sort ( idnode_set_t *is, idnode_sort_t *s );
 void idnode_set_sort_by_title ( idnode_set_t *is );
 htsmsg_t *idnode_set_as_htsmsg ( idnode_set_t *is );
index 9f64978346d4636efae21178a8fd920a9539d2b8..1e58c83d8656f653b2601f990dc7c07a02eb79bf 100644 (file)
@@ -55,7 +55,7 @@ linuxdvb_adapter_class_get_childs ( idnode_t *in )
 {
   linuxdvb_frontend_t *lfe;
   linuxdvb_adapter_t *la = (linuxdvb_adapter_t*)in;
-  idnode_set_t *is = idnode_set_create();
+  idnode_set_t *is = idnode_set_create(0);
   LIST_FOREACH(lfe, &la->la_frontends, lfe_link)
     idnode_set_add(is, &lfe->ti_id, NULL);
   return is;
index b8c51ad9bc75183e6113587bd81f223e55126613..a25968c2d2b84b71e60e1cd378ae0651ae7d7976 100644 (file)
@@ -109,7 +109,7 @@ static idnode_set_t *
 linuxdvb_frontend_dvbs_class_get_childs ( idnode_t *self )
 {
   linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)self;
-  idnode_set_t        *is  = idnode_set_create();
+  idnode_set_t        *is  = idnode_set_create(0);
   idnode_set_add(is, &lfe->lfe_satconf->ls_id, NULL);
   return is;
 }
index d5e0903a7e7fed39a34e7345b55c85986a6680b6..47291a56bcd6be15f622a98086fb06e9a4c66fff 100644 (file)
@@ -198,7 +198,7 @@ linuxdvb_satconf_class_get_childs ( idnode_t *o )
 {
   linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)o;
   linuxdvb_satconf_ele_t *lse;
-  idnode_set_t *is = idnode_set_create();
+  idnode_set_t *is = idnode_set_create(0);
   TAILQ_FOREACH(lse, &ls->ls_elements, lse_link)
     idnode_set_add(is, &lse->lse_id, NULL);
   return is;
@@ -869,7 +869,7 @@ linuxdvb_satconf_ele_class_network_set( void *o, const void *p )
   linuxdvb_satconf_ele_t *ls  = o;
   const htsmsg_t *msg = p;
   mpegts_network_t *mn;
-  idnode_set_t *n = idnode_set_create();
+  idnode_set_t *n = idnode_set_create(0);
   htsmsg_field_t *f;
   const char *str;
   int i, save;
@@ -1019,7 +1019,7 @@ static idnode_set_t *
 linuxdvb_satconf_ele_class_get_childs ( idnode_t *o )
 {
   linuxdvb_satconf_ele_t *ls = (linuxdvb_satconf_ele_t*)o;
-  idnode_set_t *is = idnode_set_create();
+  idnode_set_t *is = idnode_set_create(0);
   if (ls->lse_lnb)
     idnode_set_add(is, &ls->lse_lnb->ld_id, NULL);
   if (ls->lse_switch)
@@ -1145,7 +1145,7 @@ linuxdvb_satconf_ele_create0
     free(lse);
     return NULL;
   }
-  lse->lse_networks = idnode_set_create();
+  lse->lse_networks = idnode_set_create(0);
   lse->lse_parent = ls;
   TAILQ_INSERT_TAIL(&ls->ls_elements, lse, lse_link);
   if (conf)
index 694a318dc66487a8b91c3488e6603be924d509d2..9962c424603b509ae5c0ba46871f64a82b880da9 100644 (file)
@@ -112,7 +112,7 @@ static idnode_set_t *
 satip_device_class_get_childs ( idnode_t *in )
 {
   satip_device_t *sd = (satip_device_t *)in;
-  idnode_set_t *is = idnode_set_create();
+  idnode_set_t *is = idnode_set_create(0);
   satip_frontend_t *lfe;
 
   TAILQ_FOREACH(lfe, &sd->sd_frontends, sf_link)
index 56bab05d30237f10ce15e85a83eebe9db72e82f3..703d49a04e79e418d181805c3b6f70f5204de91a 100644 (file)
@@ -167,7 +167,7 @@ static idnode_set_t *
 satip_frontend_dvbs_class_get_childs ( idnode_t *self )
 {
   satip_frontend_t   *lfe = (satip_frontend_t*)self;
-  idnode_set_t        *is  = idnode_set_create();
+  idnode_set_t        *is  = idnode_set_create(0);
   satip_satconf_t *sfc;
   TAILQ_FOREACH(sfc, &lfe->sf_satconf, sfc_link)
     idnode_set_add(is, &sfc->sfc_id, NULL);
index ea1ece1cd9ae9ed2b5fd0ac016e443214bd456b8..682d8c804a843402df6c58ab280bd1548bb5b578 100644 (file)
@@ -82,7 +82,7 @@ satip_satconf_class_network_set( void *o, const void *p )
   satip_satconf_t *sfc  = o;
   const htsmsg_t *msg = p;
   mpegts_network_t *mn;
-  idnode_set_t *n = idnode_set_create();
+  idnode_set_t *n = idnode_set_create(0);
   htsmsg_field_t *f;
   const char *str;
   int i, save;
@@ -238,7 +238,7 @@ satip_satconf_create0
     free(sfc);
     return NULL;
   }
-  sfc->sfc_networks = idnode_set_create();
+  sfc->sfc_networks = idnode_set_create(0);
   sfc->sfc_lfe      = lfe;
   sfc->sfc_position = position + 1;
   TAILQ_INSERT_TAIL(&lfe->sf_satconf, sfc, sfc_link);
index 5ee36b63112909422ac4c40b9fe4a8eea38754d3..c75c3a14888bb8d936b4d86ee888104400fa1305 100644 (file)
@@ -39,7 +39,7 @@ static idnode_set_t *
 tvhdhomerun_device_class_get_childs ( idnode_t *in )
 {
   tvhdhomerun_device_t *hd = (tvhdhomerun_device_t *)in;
-  idnode_set_t *is = idnode_set_create();
+  idnode_set_t *is = idnode_set_create(0);
   tvhdhomerun_frontend_t *lfe;
 
   TAILQ_FOREACH(lfe, &hd->hd_frontends, hf_link)