From 94d43abecf01f203d9dc476c09717abbc3f34664 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 11 Sep 2005 13:23:49 +0200 Subject: [PATCH] Implemented a hash for the channels to reduce the system load in the EIT scanning thread --- CONTRIBUTORS | 1 + HISTORY | 4 +++- channels.c | 66 ++++++++++++++++++++++++++++++++++++---------------- channels.h | 10 +++++++- epg.h | 6 ++--- tools.c | 13 ++++++++--- tools.h | 4 +++- 7 files changed, 75 insertions(+), 29 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 1e6852a1..2b6b4e41 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1430,6 +1430,7 @@ Georg Acher for avoiding unnecessary calls to getLength() in libsi/si.c, and avoiding the '& 0xff' in CRC32::crc32() of libsi/util.c for suggesting to reduce the priority of the section handler threads + for a patch that was used to implement a hash for the channels Henrik Niehaus for reporting a problem with timers with a day given as MTWTF--@6, i.e. a repeating diff --git a/HISTORY b/HISTORY index a1ca5c26..f620da8f 100644 --- a/HISTORY +++ b/HISTORY @@ -3747,7 +3747,7 @@ Video Disk Recorder Revision History - The new SVDRP command EDIT can be used to start the editing process of a recording (based on the CUTR patch by Harald Milz). -2005-09-10: Version 1.3.32 +2005-09-11: Version 1.3.32 - Added some missing braces in remux.c (thanks to Wayne Keer for reporting this one). - Removed unused MAINMENUENTRY from svdrpdemo.c (thanks to Udo Richter for reporting @@ -3804,3 +3804,5 @@ Video Disk Recorder Revision History Rother for reporting this one). - Fixed converting summary.vdr files that would result in a very long 'short text' (thanks to Carsten Koch). +- Implemented a hash for the channels to reduce the system load in the EIT scanning + thread (based on a patch by Georg Acher). diff --git a/channels.c b/channels.c index 32770d64..3bb42f5d 100644 --- a/channels.c +++ b/channels.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: channels.c 1.45 2005/09/04 10:49:12 kls Exp $ + * $Id: channels.c 1.46 2005/09/11 11:17:19 kls Exp $ */ #include "channels.h" @@ -342,11 +342,14 @@ void cChannel::SetId(int Nid, int Tid, int Sid, int Rid) dsyslog("changing id of channel %d from %d-%d-%d-%d to %d-%d-%d-%d", Number(), nid, tid, sid, rid, Nid, Tid, Sid, Rid); modification |= CHANNELMOD_ID; Channels.SetModified(); + Channels.UnhashChannel(this); } nid = Nid; tid = Tid; sid = Sid; rid = Rid; + if (Number()) + Channels.HashChannel(this); } } @@ -868,6 +871,16 @@ bool cChannels::Load(const char *FileName, bool AllowComments, bool MustExist) return false; } +void cChannels::HashChannel(cChannel *Channel) +{ + channelsHashSid.Add(Channel, Channel->Sid()); +} + +void cChannels::UnhashChannel(cChannel *Channel) +{ + channelsHashSid.Del(Channel, Channel->Sid()); +} + int cChannels::GetNextGroup(int Idx) { cChannel *channel = Get(++Idx); @@ -894,6 +907,7 @@ int cChannels::GetNextNormal(int Idx) void cChannels::ReNumber( void ) { + channelsHashSid.Clear(); int Number = 1; for (cChannel *channel = First(); channel; channel = Next(channel)) { if (channel->GroupSep()) { @@ -901,6 +915,7 @@ void cChannels::ReNumber( void ) Number = channel->Number(); } else { + HashChannel(channel); maxNumber = Number; channel->SetNumber(Number++); } @@ -924,32 +939,43 @@ cChannel *cChannels::GetByNumber(int Number, int SkipGap) cChannel *cChannels::GetByServiceID(int Source, int Transponder, unsigned short ServiceID) { - for (cChannel *channel = First(); channel; channel = Next(channel)) { - if (!channel->GroupSep() && channel->Source() == Source && ISTRANSPONDER(channel->Transponder(), Transponder) && channel->Sid() == ServiceID) - return channel; - } + cList *list = channelsHashSid.GetList(ServiceID); + if (list) { + for (cHashObject *hobj = list->First(); hobj; hobj = list->Next(hobj)) { + cChannel *channel = (cChannel *)hobj->Object(); + if (channel->Sid() == ServiceID && channel->Source() == Source && ISTRANSPONDER(channel->Transponder(), Transponder)) + return channel; + } + } return NULL; } cChannel *cChannels::GetByChannelID(tChannelID ChannelID, bool TryWithoutRid, bool TryWithoutPolarization) { - for (cChannel *channel = First(); channel; channel = Next(channel)) { - if (!channel->GroupSep() && channel->GetChannelID() == ChannelID) - return channel; - } - if (TryWithoutRid) { - ChannelID.ClrRid(); - for (cChannel *channel = First(); channel; channel = Next(channel)) { - if (!channel->GroupSep() && channel->GetChannelID().ClrRid() == ChannelID) - return channel; - } - } - if (TryWithoutPolarization) { - ChannelID.ClrPolarization(); - for (cChannel *channel = First(); channel; channel = Next(channel)) { - if (!channel->GroupSep() && channel->GetChannelID().ClrPolarization() == ChannelID) + int sid = ChannelID.Sid(); + cList *list = channelsHashSid.GetList(sid); + if (list) { + for (cHashObject *hobj = list->First(); hobj; hobj = list->Next(hobj)) { + cChannel *channel = (cChannel *)hobj->Object(); + if (channel->Sid() == sid && channel->GetChannelID() == ChannelID) return channel; } + if (TryWithoutRid) { + ChannelID.ClrRid(); + for (cHashObject *hobj = list->First(); hobj; hobj = list->Next(hobj)) { + cChannel *channel = (cChannel *)hobj->Object(); + if (channel->Sid() == sid && channel->GetChannelID().ClrRid() == ChannelID) + return channel; + } + } + if (TryWithoutPolarization) { + ChannelID.ClrPolarization(); + for (cHashObject *hobj = list->First(); hobj; hobj = list->Next(hobj)) { + cChannel *channel = (cChannel *)hobj->Object(); + if (channel->Sid() == sid && channel->GetChannelID().ClrPolarization() == ChannelID) + return channel; + } + } } return NULL; } diff --git a/channels.h b/channels.h index 2742e350..c2e1efc2 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.34 2005/09/04 10:17:12 kls Exp $ + * $Id: channels.h 1.35 2005/09/11 11:17:19 kls Exp $ */ #ifndef __CHANNELS_H @@ -72,6 +72,11 @@ public: bool Valid(void) const { return (nid || tid) && sid; } // rid is optional and source may be 0//XXX source may not be 0??? tChannelID &ClrRid(void) { rid = 0; return *this; } tChannelID &ClrPolarization(void); + int Source(void) { return source; } + int Nid(void) { return nid; } + int Tid(void) { return tid; } + int Sid(void) { return sid; } + int Rid(void) { return rid; } static tChannelID FromString(const char *s); cString ToString(void) const; static const tChannelID InvalidID; @@ -203,10 +208,13 @@ private: int maxNumber; int modified; int beingEdited; + cHash channelsHashSid; void DeleteDuplicateChannels(void); public: cChannels(void); bool Load(const char *FileName, bool AllowComments = false, bool MustExist = false); + void HashChannel(cChannel *Channel); + void UnhashChannel(cChannel *Channel); int GetNextGroup(int Idx); // Get next channel group int GetPrevGroup(int Idx); // Get previous channel group int GetNextNormal(int Idx); // Get next normal channel (not group) diff --git a/epg.h b/epg.h index 83ae0d21..9cefcb27 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.25 2005/05/28 11:32:36 kls Exp $ + * $Id: epg.h 1.26 2005/09/11 12:54:30 kls Exp $ */ #ifndef __EPG_H @@ -132,8 +132,8 @@ public: void Cleanup(void); cEvent *AddEvent(cEvent *Event); void DelEvent(cEvent *Event); - void cSchedule::HashEvent(cEvent *Event); - void cSchedule::UnhashEvent(cEvent *Event); + void HashEvent(cEvent *Event); + void UnhashEvent(cEvent *Event); const cList *Events(void) const { return &events; } const cEvent *GetPresentEvent(bool CheckRunningStatus = false) const; const cEvent *GetFollowingEvent(bool CheckRunningStatus = false) const; diff --git a/tools.c b/tools.c index 46d3ce26..28b2bbed 100644 --- a/tools.c +++ b/tools.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.c 1.97 2005/08/27 14:43:55 kls Exp $ + * $Id: tools.c 1.98 2005/09/11 13:11:05 kls Exp $ */ #include "tools.h" @@ -1080,8 +1080,7 @@ cHashBase::cHashBase(int Size) cHashBase::~cHashBase(void) { - for (int i = 0; i < size; i++) - delete hashTable[i]; + Clear(); free(hashTable); } @@ -1106,6 +1105,14 @@ void cHashBase::Del(cListObject *Object, unsigned int Id) } } +void cHashBase::Clear(void) +{ + for (int i = 0; i < size; i++) { + delete hashTable[i]; + hashTable[i] = NULL; + } +} + cListObject *cHashBase::Get(unsigned int Id) const { cList *list = hashTable[hashfn(Id)]; diff --git a/tools.h b/tools.h index 41a00498..9d18d534 100644 --- a/tools.h +++ b/tools.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.h 1.75 2005/08/27 14:40:08 kls Exp $ + * $Id: tools.h 1.76 2005/09/11 13:04:03 kls Exp $ */ #ifndef __TOOLS_H @@ -259,6 +259,7 @@ private: cListObject *object; public: cHashObject(cListObject *Object, unsigned int Id) { object = Object; id = Id; } + cListObject *Object(void) { return object; } }; class cHashBase { @@ -272,6 +273,7 @@ public: virtual ~cHashBase(); void Add(cListObject *Object, unsigned int Id); void Del(cListObject *Object, unsigned int Id); + void Clear(void); cListObject *Get(unsigned int Id) const; cList *GetList(unsigned int Id) const; };