From cd43adac926d60203754515b0eaf0bb3ac2d1399 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sat, 14 Jan 2006 15:52:40 +0100 Subject: [PATCH] Made the "What's on now/next?" menus a lot faster by storing a pointer to each channel's schedule in the cChannel data --- HISTORY | 2 ++ channels.c | 9 ++++++++- channels.h | 6 +++++- eit.c | 8 ++------ epg.c | 18 +++++++++++++++++- epg.h | 3 ++- menu.c | 12 ++++++------ svdrp.c | 4 ++-- timers.c | 4 ++-- 9 files changed, 46 insertions(+), 20 deletions(-) diff --git a/HISTORY b/HISTORY index 78c1fac7..a59aabed 100644 --- a/HISTORY +++ b/HISTORY @@ -4170,3 +4170,5 @@ Video Disk Recorder Revision History names (thanks to Stefan Huelswitt). - Added a missing '-' to the example for viewing a grabbed image on a remote host (reported by Philippe Gramoullé). +- Made the "What's on now/next?" menus a lot faster by storing a pointer to each + channel's schedule in the cChannel data. diff --git a/channels.c b/channels.c index a4f84491..bf1230bd 100644 --- a/channels.c +++ b/channels.c @@ -4,13 +4,14 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: channels.c 1.47 2005/12/30 15:41:24 kls Exp $ + * $Id: channels.c 1.48 2006/01/14 15:51:02 kls Exp $ */ #include "channels.h" #include #include #include "device.h" +#include "epg.h" // IMPORTANT NOTE: in the 'sscanf()' calls there is a blank after the '%d' // format characters in order to allow any number of blanks after a numeric @@ -174,6 +175,7 @@ cChannel::cChannel(void) guard = GUARD_INTERVAL_AUTO; hierarchy = HIERARCHY_AUTO; modification = CHANNELMOD_NONE; + schedule = NULL; linkChannels = NULL; refChannel = NULL; } @@ -184,6 +186,7 @@ cChannel::cChannel(const cChannel &Channel) shortName = NULL; provider = NULL; portalName = NULL; + schedule = NULL; linkChannels = NULL; refChannel = NULL; *this = Channel; @@ -293,6 +296,7 @@ bool cChannel::SetSatTransponderData(int Source, int Frequency, char Polarizatio srate = Srate; coderateH = CoderateH; modulation = QPSK; + schedule = NULL; } return true; } @@ -310,6 +314,7 @@ bool cChannel::SetCableTransponderData(int Source, int Frequency, int Modulation modulation = Modulation; srate = Srate; coderateH = CoderateH; + schedule = NULL; } return true; } @@ -331,6 +336,7 @@ bool cChannel::SetTerrTransponderData(int Source, int Frequency, int Bandwidth, coderateL = CoderateL; guard = Guard; transmission = Transmission; + schedule = NULL; } return true; } @@ -350,6 +356,7 @@ void cChannel::SetId(int Nid, int Tid, int Sid, int Rid) rid = Rid; if (Number()) Channels.HashChannel(this); + schedule = NULL; } } diff --git a/channels.h b/channels.h index b4882522..22dc6feb 100644 --- a/channels.h +++ b/channels.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: channels.h 1.37 2006/01/07 13:00:43 kls Exp $ + * $Id: channels.h 1.38 2006/01/14 15:51:26 kls Exp $ */ #ifndef __CHANNELS_H @@ -103,7 +103,10 @@ public: class cLinkChannels : public cList { }; +class cSchedule; + class cChannel : public cListObject { + friend class cSchedules; friend class cMenuEditChannel; private: static cString ToText(const cChannel *Channel); @@ -142,6 +145,7 @@ private: int hierarchy; int __EndData__; int modification; + mutable const cSchedule *schedule; cLinkChannels *linkChannels; cChannel *refChannel; cString ParametersToString(void) const; diff --git a/eit.c b/eit.c index a343a696..4a0f59de 100644 --- a/eit.c +++ b/eit.c @@ -8,7 +8,7 @@ * Robert Schneider and Rolf Hakenes . * Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg . * - * $Id: eit.c 1.113 2005/12/26 11:50:09 kls Exp $ + * $Id: eit.c 1.114 2006/01/14 15:41:21 kls Exp $ */ #include "eit.h" @@ -35,11 +35,7 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data) if (!channel) return; // only collect data for known channels - cSchedule *pSchedule = (cSchedule *)Schedules->GetSchedule(channelID); - if (!pSchedule) { - pSchedule = new cSchedule(channelID); - Schedules->Add(pSchedule); - } + cSchedule *pSchedule = (cSchedule *)Schedules->GetSchedule(channel, true); bool Empty = true; bool Modified = false; diff --git a/epg.c b/epg.c index 7b2cb0ea..615941f2 100644 --- a/epg.c +++ b/epg.c @@ -7,7 +7,7 @@ * Original version (as used in VDR before 1.3.0) written by * Robert Schneider and Rolf Hakenes . * - * $Id: epg.c 1.47 2005/12/30 15:41:59 kls Exp $ + * $Id: epg.c 1.48 2006/01/14 15:46:50 kls Exp $ */ #include "epg.h" @@ -997,3 +997,19 @@ const cSchedule *cSchedules::GetSchedule(tChannelID ChannelID) const return NULL; } +const cSchedule *cSchedules::GetSchedule(const cChannel *Channel, bool AddIfMissing) const +{ + // This is not very beautiful, but it dramatically speeds up the + // "What's on now/next?" menus. + static cSchedule DummySchedule(tChannelID::InvalidID); + if (!Channel->schedule) + Channel->schedule = GetSchedule(Channel->GetChannelID()); + if (!Channel->schedule) + Channel->schedule = &DummySchedule; + if (Channel->schedule == &DummySchedule && AddIfMissing) { + cSchedule *Schedule = new cSchedule(Channel->GetChannelID()); + ((cSchedules *)this)->Add(Schedule); + Channel->schedule = Schedule; + } + return Channel->schedule != &DummySchedule? Channel->schedule : NULL; +} diff --git a/epg.h b/epg.h index 04b63bfb..443b5600 100644 --- a/epg.h +++ b/epg.h @@ -7,7 +7,7 @@ * Original version (as used in VDR before 1.3.0) written by * Robert Schneider and Rolf Hakenes . * - * $Id: epg.h 1.28 2005/12/27 14:31:24 kls Exp $ + * $Id: epg.h 1.29 2006/01/14 15:45:24 kls Exp $ */ #ifndef __EPG_H @@ -179,6 +179,7 @@ public: static bool Read(FILE *f = NULL); cSchedule *AddSchedule(tChannelID ChannelID); const cSchedule *GetSchedule(tChannelID ChannelID) const; + const cSchedule *GetSchedule(const cChannel *Channel, bool AddIfMissing = false) const; }; void ReportEpgBugFixStats(bool Reset = false); diff --git a/menu.c b/menu.c index b59aabff..8a1bab13 100644 --- a/menu.c +++ b/menu.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.392 2006/01/13 15:17:53 kls Exp $ + * $Id: menu.c 1.393 2006/01/14 14:53:43 kls Exp $ */ #include "menu.h" @@ -1029,7 +1029,7 @@ cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentCha helpKeys = -1; for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) { if (!Channel->GroupSep()) { - const cSchedule *Schedule = Schedules->GetSchedule(Channel->GetChannelID()); + const cSchedule *Schedule = Schedules->GetSchedule(Channel); if (Schedule) { const cEvent *Event = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent(); if (Event) @@ -1202,7 +1202,7 @@ void cMenuSchedule::PrepareSchedule(cChannel *Channel) SetTitle(buffer); free(buffer); if (schedules) { - const cSchedule *Schedule = schedules->GetSchedule(Channel->GetChannelID()); + const cSchedule *Schedule = schedules->GetSchedule(Channel); if (Schedule) { const cEvent *PresentEvent = Schedule->GetPresentEvent(Channel->Number() == cDevice::CurrentChannel()); time_t now = time(NULL) - Setup.EPGLinger * 60; @@ -2833,7 +2833,7 @@ static void SetTrackDescriptions(bool Live) if (Channel) { const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock); if (Schedules) { - const cSchedule *Schedule = Schedules->GetSchedule(Channel->GetChannelID()); + const cSchedule *Schedule = Schedules->GetSchedule(Channel); if (Schedule) { const cEvent *Present = Schedule->GetPresentEvent(true); if (Present) @@ -2916,7 +2916,7 @@ void cDisplayChannel::DisplayInfo(void) cSchedulesLock SchedulesLock; const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock); if (Schedules) { - const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID()); + const cSchedule *Schedule = Schedules->GetSchedule(channel); if (Schedule) { const cEvent *Present = Schedule->GetPresentEvent(true); const cEvent *Following = Schedule->GetFollowingEvent(true); @@ -3346,7 +3346,7 @@ bool cRecordControl::GetEvent(void) cSchedulesLock SchedulesLock; const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock); if (Schedules) { - const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID()); + const cSchedule *Schedule = Schedules->GetSchedule(channel); if (Schedule) { event = Schedule->GetEventAround(Time); if (event) { diff --git a/svdrp.c b/svdrp.c index 01e156d2..a346506d 100644 --- a/svdrp.c +++ b/svdrp.c @@ -10,7 +10,7 @@ * and interact with the Video Disk Recorder - or write a full featured * graphical interface that sits on top of an SVDRP connection. * - * $Id: svdrp.c 1.91 2006/01/14 11:42:52 kls Exp $ + * $Id: svdrp.c 1.92 2006/01/14 14:55:52 kls Exp $ */ #include "svdrp.h" @@ -936,7 +936,7 @@ void cSVDRP::CmdLSTE(const char *Option) else Channel = Channels.GetByChannelID(tChannelID::FromString(Option)); if (Channel) { - Schedule = Schedules->GetSchedule(Channel->GetChannelID()); + Schedule = Schedules->GetSchedule(Channel); if (!Schedule) { Reply(550, "No schedule found"); return; diff --git a/timers.c b/timers.c index 906efbbc..19672672 100644 --- a/timers.c +++ b/timers.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: timers.c 1.41 2006/01/08 11:40:29 kls Exp $ + * $Id: timers.c 1.42 2006/01/14 14:56:11 kls Exp $ */ #include "timers.h" @@ -596,7 +596,7 @@ void cTimers::SetEvents(void) if (Schedules) { if (!lastSetEvents || Schedules->Modified() >= lastSetEvents) { for (cTimer *ti = First(); ti; ti = Next(ti)) { - const cSchedule *Schedule = Schedules->GetSchedule(ti->Channel()->GetChannelID()); + const cSchedule *Schedule = Schedules->GetSchedule(ti->Channel()); if (Schedule) { if (!lastSetEvents || Schedule->Modified() >= lastSetEvents) { const cEvent *Event = NULL;