[vlc-commits] epg: do ordered inserts and optimize merging
Francois Cartegnie
git at videolan.org
Sat Feb 13 15:44:06 CET 2016
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | 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 );
+}
More information about the vlc-commits
mailing list