Add global object hash similar to that used by andoma in original code. Although mine includes ALL objects, its currently only used for broadcast lookup as generally the others will probably be quicker (episodes?) to go via the normal URI based maps.
This commit is contained in:
parent
6871fa8b68
commit
edbc12015d
2 changed files with 43 additions and 24 deletions
45
src/epg.c
45
src/epg.c
|
@ -45,12 +45,16 @@
|
|||
#include "htsmsg_binary.h"
|
||||
#include "epggrab.h"
|
||||
|
||||
/* Broadcast hashing */
|
||||
#define EPG_HASH_WIDTH 1024
|
||||
#define EPG_HASH_MASK (EPG_HASH_WIDTH - 1)
|
||||
|
||||
/* Element lists */
|
||||
struct epg_object_tree epg_brands;
|
||||
struct epg_object_tree epg_seasons;
|
||||
struct epg_object_tree epg_episodes;
|
||||
struct epg_object_tree epg_channels;
|
||||
struct epg_object_tree epg_broadcasts;
|
||||
epg_object_list_t epg_objects[EPG_HASH_WIDTH];
|
||||
epg_object_tree_t epg_brands;
|
||||
epg_object_tree_t epg_seasons;
|
||||
epg_object_tree_t epg_episodes;
|
||||
epg_object_tree_t epg_channels;
|
||||
|
||||
/* Unmapped */
|
||||
LIST_HEAD(epg_channel_unmapped_list, epg_channel);
|
||||
|
@ -59,10 +63,9 @@ struct epg_channel_unmapped_list epg_channel_unmapped;
|
|||
struct channel_unmapped_list channel_unmapped;
|
||||
|
||||
/* Unreferenced */
|
||||
LIST_HEAD(epg_object_unref_list, epg_object);
|
||||
struct epg_object_unref_list epg_object_unref;
|
||||
epg_object_list_t epg_object_unref;
|
||||
|
||||
/* Global counters */
|
||||
/* Global counter */
|
||||
static uint64_t _epg_object_idx = 0;
|
||||
|
||||
/* **************************************************************************
|
||||
|
@ -332,6 +335,7 @@ static epg_object_t *_epg_object_find
|
|||
if (!eo->putref) eo->putref = _epg_object_putref;
|
||||
_epg_object_idx++;
|
||||
LIST_INSERT_HEAD(&epg_object_unref, eo, ulink);
|
||||
LIST_INSERT_HEAD(&epg_objects[eo->id & EPG_HASH_WIDTH], eo, hlink);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -359,11 +363,20 @@ static epg_object_t *_epg_object_find_by_uri
|
|||
return eo;
|
||||
}
|
||||
|
||||
static epg_object_t *_epg_object_find_by_id
|
||||
static epg_object_t *_epg_object_find_by_id2 ( uint64_t id )
|
||||
{
|
||||
epg_object_t *eo;
|
||||
LIST_FOREACH(eo, &epg_objects[id & EPG_HASH_WIDTH], hlink) {
|
||||
if (eo->id == id) return eo;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static epg_object_t *_epg_object_find_by_id
|
||||
( uint64_t id, epg_object_tree_t *tree )
|
||||
{
|
||||
epg_object_t *eo;
|
||||
if (!tree) return NULL;
|
||||
if (!tree) return _epg_object_find_by_id2(id);
|
||||
RB_FOREACH(eo, tree, glink) {
|
||||
if ( eo->id == id ) return eo;
|
||||
}
|
||||
|
@ -755,13 +768,12 @@ int epg_episode_set_number ( epg_episode_t *episode, uint16_t number )
|
|||
int epg_episode_set_part ( epg_episode_t *episode, uint16_t part, uint16_t count )
|
||||
{
|
||||
int save = 0;
|
||||
// TODO: could treat part/count independently
|
||||
if ( !episode || !part || !count ) return 0;
|
||||
if ( !episode || !part ) return 0;
|
||||
if ( episode->part_number != part ) {
|
||||
episode->part_number = part;
|
||||
save |= 1;
|
||||
}
|
||||
if ( episode->part_count != count ) {
|
||||
if ( count && episode->part_count != count ) {
|
||||
episode->part_count = count;
|
||||
save |= 1;
|
||||
}
|
||||
|
@ -925,14 +937,11 @@ epg_broadcast_t* epg_broadcast_find_by_time
|
|||
// TODO: allow optional channel parameter?
|
||||
epg_broadcast_t *epg_broadcast_find_by_id ( uint64_t id, epg_channel_t *ec )
|
||||
{
|
||||
epg_object_t *eo = NULL, *eoc;
|
||||
epg_object_t *eo = NULL;
|
||||
if ( ec ) {
|
||||
eo = _epg_object_find_by_id(id, &((epg_channel_t*)ec)->schedule);
|
||||
} else {
|
||||
RB_FOREACH(eoc, &epg_channels, glink) {
|
||||
eo = _epg_object_find_by_id(id, &((epg_channel_t*)eoc)->schedule);
|
||||
if (eo) break;
|
||||
}
|
||||
eo = _epg_object_find_by_id2(id);
|
||||
}
|
||||
return (epg_broadcast_t*)eo;
|
||||
}
|
||||
|
|
22
src/epg.h
22
src/epg.h
|
@ -32,6 +32,7 @@
|
|||
/*
|
||||
* Map types
|
||||
*/
|
||||
LIST_HEAD(epg_object_list, epg_object);
|
||||
RB_HEAD(epg_object_tree, epg_object);
|
||||
RB_HEAD(epg_brand_tree, epg_brand);
|
||||
RB_HEAD(epg_season_tree, epg_season);
|
||||
|
@ -48,6 +49,7 @@ typedef struct epg_season epg_season_t;
|
|||
typedef struct epg_episode epg_episode_t;
|
||||
typedef struct epg_broadcast epg_broadcast_t;
|
||||
typedef struct epg_channel epg_channel_t;
|
||||
typedef struct epg_object_list epg_object_list_t;
|
||||
typedef struct epg_object_tree epg_object_tree_t;
|
||||
typedef struct epg_brand_tree epg_brand_tree_t;
|
||||
typedef struct epg_season_tree epg_season_tree_t;
|
||||
|
@ -62,7 +64,8 @@ typedef struct epg_broadcast_tree epg_broadcast_tree_t;
|
|||
/* Object */
|
||||
typedef struct epg_object
|
||||
{
|
||||
RB_ENTRY(epg_object) glink; ///< Global list link
|
||||
RB_ENTRY(epg_object) glink; ///< Global (URI) list link
|
||||
LIST_ENTRY(epg_object) hlink; ///< Global (ID) hash link
|
||||
LIST_ENTRY(epg_object) ulink; ///< Global unref'd link
|
||||
|
||||
char *uri; ///< Unique ID (from grabber)
|
||||
|
@ -150,8 +153,6 @@ epg_season_t *epg_season_deserialize ( htsmsg_t *m, int create, int *save );
|
|||
|
||||
/* ************************************************************************
|
||||
* Episode
|
||||
*
|
||||
* TODO: ee_genre needs to be a list
|
||||
* ***********************************************************************/
|
||||
|
||||
/* Object */
|
||||
|
@ -192,6 +193,8 @@ int epg_episode_set_description ( epg_episode_t *e, const char *description )
|
|||
__attribute__((warn_unused_result));
|
||||
int epg_episode_set_number ( epg_episode_t *e, uint16_t number )
|
||||
__attribute__((warn_unused_result));
|
||||
int epg_episode_set_onscreen ( epg_episode_t *e, const char *onscreen )
|
||||
__attribute__((warn_unused_result));
|
||||
int epg_episode_set_part ( epg_episode_t *e,
|
||||
uint16_t number, uint16_t count )
|
||||
__attribute__((warn_unused_result));
|
||||
|
@ -199,6 +202,10 @@ int epg_episode_set_brand ( epg_episode_t *e, epg_brand_t *b )
|
|||
__attribute__((warn_unused_result));
|
||||
int epg_episode_set_season ( epg_episode_t *e, epg_season_t *s )
|
||||
__attribute__((warn_unused_result));
|
||||
int epg_episode_set_genre ( epg_episode_t *e, uint8_t g )
|
||||
__attribute__((warn_unused_result));
|
||||
int epg_episode_set_genre_str ( epg_episode_t *e, const char *s )
|
||||
__attribute__((warn_unused_result));
|
||||
|
||||
/* EpNum format helper */
|
||||
// output string will be:
|
||||
|
@ -248,9 +255,9 @@ typedef struct epg_broadcast
|
|||
uint8_t is_new; ///< New series / file premiere
|
||||
uint8_t is_repeat; ///< Repeat screening
|
||||
|
||||
RB_ENTRY(epg_broadcast) elink; ///< Episode link
|
||||
epg_episode_t *episode; ///< Episode shown
|
||||
epg_channel_t *channel; ///< Channel being broadcast on
|
||||
RB_ENTRY(epg_broadcast) elink; ///< Episode link
|
||||
epg_episode_t *episode; ///< Episode shown
|
||||
epg_channel_t *channel; ///< Channel being broadcast on
|
||||
|
||||
} epg_broadcast_t;
|
||||
|
||||
|
@ -281,6 +288,7 @@ typedef struct epg_channel
|
|||
epg_object_t _; ///< Parent object
|
||||
|
||||
char *name; ///< Channel name
|
||||
char *icon; ///< Channel icon
|
||||
char **sname; ///< DVB svc names (to map)
|
||||
int **sid; ///< DVB svc ids (to map)
|
||||
|
||||
|
@ -302,6 +310,8 @@ epg_channel_t *epg_channel_find_by_id ( uint64_t id );
|
|||
/* Mutators */
|
||||
int epg_channel_set_name ( epg_channel_t *c, const char *n )
|
||||
__attribute__((warn_unused_result));
|
||||
int epg_channel_set_icon ( epg_channel_t *c, const char *i )
|
||||
__attribute__((warn_unused_result));
|
||||
int epg_channel_set_channel ( epg_channel_t *c, channel_t *ch );
|
||||
|
||||
/* Accessors */
|
||||
|
|
Loading…
Add table
Reference in a new issue