vlc | branch: master | Francois Cartegnie <[email protected]> | Fri Feb 12 20:30:06 2016 +0100| [d9db85c3b8e48e74f393ba83577cc0873e85e1b9] | committer: Francois Cartegnie
epg: do ordered inserts and optimize merging allows updating existing entries through merge > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=d9db85c3b8e48e74f393ba83577cc0873e85e1b9 --- src/misc/epg.c | 141 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 111 insertions(+), 30 deletions(-) diff --git a/src/misc/epg.c b/src/misc/epg.c index 522d366..2541a5a 100644 --- a/src/misc/epg.c +++ b/src/misc/epg.c @@ -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 ); +} _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
