diff --git a/src/api/api_input.c b/src/api/api_input.c index 4152dbc6..a892c4b5 100644 --- a/src/api/api_input.c +++ b/src/api/api_input.c @@ -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; diff --git a/src/bouquet.c b/src/bouquet.c index 5367131a..5308627b 100644 --- a/src/bouquet.c +++ b/src/bouquet.c @@ -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); } } diff --git a/src/idnode.c b/src/idnode.c index bf60af44..a6672faf 100644 --- a/src/idnode.c +++ b/src/idnode.c @@ -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; + } +} + +ssize_t +idnode_set_find_index + ( idnode_set_t *is, idnode_t *in ) +{ + 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; } void idnode_set_remove ( 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; - } -} - -int -idnode_set_exists - ( 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 diff --git a/src/idnode.h b/src/idnode.h index 544e6f91..e59366fa 100644 --- a/src/idnode.h +++ b/src/idnode.h @@ -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 ); diff --git a/src/input/mpegts/linuxdvb/linuxdvb_adapter.c b/src/input/mpegts/linuxdvb/linuxdvb_adapter.c index 9f649783..1e58c83d 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_adapter.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_adapter.c @@ -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; diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c index b8c51ad9..a25968c2 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c @@ -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; } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c index d5e0903a..47291a56 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c @@ -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) diff --git a/src/input/mpegts/satip/satip.c b/src/input/mpegts/satip/satip.c index 694a318d..9962c424 100644 --- a/src/input/mpegts/satip/satip.c +++ b/src/input/mpegts/satip/satip.c @@ -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) diff --git a/src/input/mpegts/satip/satip_frontend.c b/src/input/mpegts/satip/satip_frontend.c index 56bab05d..703d49a0 100644 --- a/src/input/mpegts/satip/satip_frontend.c +++ b/src/input/mpegts/satip/satip_frontend.c @@ -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); diff --git a/src/input/mpegts/satip/satip_satconf.c b/src/input/mpegts/satip/satip_satconf.c index ea1ece1c..682d8c80 100644 --- a/src/input/mpegts/satip/satip_satconf.c +++ b/src/input/mpegts/satip/satip_satconf.c @@ -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); diff --git a/src/input/mpegts/tvhdhomerun/tvhdhomerun.c b/src/input/mpegts/tvhdhomerun/tvhdhomerun.c index 5ee36b63..c75c3a14 100644 --- a/src/input/mpegts/tvhdhomerun/tvhdhomerun.c +++ b/src/input/mpegts/tvhdhomerun/tvhdhomerun.c @@ -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)