Commit d9db85c3 authored by François Cartegnie's avatar François Cartegnie 🤞

epg: do ordered inserts and optimize merging

allows updating existing entries through merge
parent e6170424
......@@ -87,7 +87,58 @@ void vlc_epg_AddEvent( vlc_epg_t *p_epg, int64_t i_start, int i_duration,
vlc_epg_event_t *p_evt = vlc_epg_Event_New( i_start, i_duration,
psz_name, psz_short_description,
psz_description, i_rating );
if( likely(p_evt) )
if( unlikely(!p_evt) )
return;
int i_pos = -1;
/* Insertions are supposed in sequential order first */
if( p_epg->i_event )
{
if( p_epg->pp_event[0]->i_start > i_start )
{
i_pos = 0;
}
else if ( p_epg->pp_event[p_epg->i_event - 1]->i_start >= i_start )
{
/* Do bisect search lower start time entry */
int i_lower = 0;
int i_upper = p_epg->i_event - 1;
while( i_lower < i_upper )
{
int i_split = ( (size_t)i_lower + i_upper ) / 2;
vlc_epg_event_t *p_cur = p_epg->pp_event[i_split];
if( p_cur->i_start < i_start )
{
i_lower = i_split + 1;
}
else if ( p_cur->i_start >= i_start )
{
i_upper = i_split;
}
}
i_pos = i_lower;
}
}
if( i_pos != -1 )
{
if( p_epg->pp_event[i_pos]->i_start == i_start )/* There can be only one event at same time */
{
vlc_epg_Event_Delete( p_epg->pp_event[i_pos] );
if( p_epg->p_current == p_epg->pp_event[i_pos] )
p_epg->p_current = p_evt;
p_epg->pp_event[i_pos] = p_evt;
return;
}
else
{
TAB_INSERT( p_epg->i_event, p_epg->pp_event, p_evt, i_pos );
}
}
else
TAB_APPEND( p_epg->i_event, p_epg->pp_event, p_evt );
}
......@@ -122,46 +173,76 @@ void vlc_epg_SetCurrent( vlc_epg_t *p_epg, int64_t i_start )
}
}
void vlc_epg_Merge( vlc_epg_t *p_dst, const vlc_epg_t *p_src )
static void vlc_epg_Prune( vlc_epg_t *p_dst )
{
int i;
/* Keep only 1 old event */
if( p_dst->p_current )
{
while( p_dst->i_event > 1 && p_dst->pp_event[0] != p_dst->p_current && p_dst->pp_event[1] != p_dst->p_current )
{
vlc_epg_Event_Delete( p_dst->pp_event[0] );
TAB_ERASE( p_dst->i_event, p_dst->pp_event, 0 );
}
}
}
void vlc_epg_Merge( vlc_epg_t *p_dst_epg, const vlc_epg_t *p_src_epg )
{
if( p_src_epg->i_event == 0 )
return;
/* Add new event */
for( i = 0; i < p_src->i_event; i++ )
int i_dst=0;
int i_src=0;
for( ; i_src < p_src_epg->i_event; i_src++ )
{
vlc_epg_event_t *p_evt = p_src->pp_event[i];
bool b_add = true;
int j;
const bool b_current = ( p_src_epg->pp_event[i_src] == p_src_epg->p_current );
for( j = 0; j < p_dst->i_event; j++ )
vlc_epg_event_t *p_src = vlc_epg_Event_Duplicate( p_src_epg->pp_event[i_src] );
if( unlikely(!p_src) )
return;
const int64_t i_src_end = p_src->i_start + p_src->i_duration;
while( i_dst < p_dst_epg->i_event )
{
if( p_dst->pp_event[j]->i_start == p_evt->i_start && p_dst->pp_event[j]->i_duration == p_evt->i_duration )
vlc_epg_event_t *p_dst = p_dst_epg->pp_event[i_dst];
const int64_t i_dst_end = p_dst->i_start + p_dst->i_duration;
/* appended is before current, no overlap */
if( p_dst->i_start >= i_src_end )
{
b_add = false;
break;
}
if( p_dst->pp_event[j]->i_start > p_evt->i_start )
break;
}
if( b_add )
{
vlc_epg_event_t *p_copy = vlc_epg_Event_Duplicate( p_evt );
if( likely(p_copy) )
TAB_INSERT( p_dst->i_event, p_dst->pp_event, p_copy, j );
/* overlap case: appended would contain current's start (or are identical) */
else if( ( p_dst->i_start >= p_src->i_start && p_dst->i_start < i_src_end ) ||
/* overlap case: appended would contain current's end */
( i_dst_end > p_src->i_start && i_dst_end <= i_src_end ) )
{
vlc_epg_Event_Delete( p_dst );
if( p_dst_epg->p_current )
p_dst_epg->p_current = NULL;
TAB_ERASE( p_dst_epg->i_event, p_dst_epg->pp_event, i_dst );
}
else
{
i_dst++;
}
}
TAB_INSERT( p_dst_epg->i_event, p_dst_epg->pp_event, p_src, i_dst );
if( b_current )
p_dst_epg->p_current = p_src;
}
/* Update current */
if( p_src->p_current )
vlc_epg_SetCurrent( p_dst, p_src->p_current->i_start );
/* Keep only 1 old event */
if( p_dst->p_current )
/* Remaining/trailing ones */
for( ; i_src < p_src_epg->i_event; i_src++ )
{
while( p_dst->i_event > 1 && p_dst->pp_event[0] != p_dst->p_current && p_dst->pp_event[1] != p_dst->p_current )
{
vlc_epg_Event_Delete( p_dst->pp_event[0] );
TAB_REMOVE( p_dst->i_event, p_dst->pp_event, p_dst->pp_event[0] );
}
vlc_epg_event_t *p_src = vlc_epg_Event_Duplicate( p_src_epg->pp_event[i_src] );
if( unlikely(!p_src) )
return;
TAB_APPEND( p_dst_epg->i_event, p_dst_epg->pp_event, p_src );
if( p_src_epg->pp_event[i_src] == p_src_epg->p_current )
p_dst_epg->p_current = p_src;
}
}
vlc_epg_Prune( p_dst_epg );
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment