From 13b67c5da50c2d6c6b5b509fa9da9b008a2c1fe0 Mon Sep 17 00:00:00 2001 From: seife Date: Sun, 10 Apr 2011 18:10:27 +0000 Subject: [PATCH] sectionsd: remove duplicate events with different eventIDs Sometimes the playout centers seem to "renumber" the events, leading to duplicates. This "removeDupEvents()" checks for events from the same service, with identical start time and duration. If it finds such events, it keeps the one with the lower (== more recent) table_id. This check is run from the hosekeeping thread. It could be extended to also remove overlapping events, but this is potentially more dangerous and can be implemented later still. As this code is experimental, it is pretty noisy for now. The debugging output should be toned down later. git-svn-id: file:///home/bas/coolstream_public_svn/THIRDPARTY/applications/neutrino-experimental@1384 e54a6e83-5905-42d5-8d5c-058d10e6a962 --- src/sectionsd/sectionsd.cpp | 60 +++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/sectionsd/sectionsd.cpp b/src/sectionsd/sectionsd.cpp index b08669290..e261b38d0 100644 --- a/src/sectionsd/sectionsd.cpp +++ b/src/sectionsd/sectionsd.cpp @@ -1203,6 +1203,61 @@ static void removeOldEvents(const long seconds) return; } + +/* Remove duplicate events (same Service, same start and endtime) + * with different eventID. Use the one from the lower table_id. + * This routine could be extended to remove overlapping events also, + * but let's keep that for later + */ +static void removeDupEvents(void) +{ + MySIeventsOrderFirstEndTimeServiceIDEventUniqueKey::iterator e1, e2, del; + + readLockEvents(); + e1 = mySIeventsOrderFirstEndTimeServiceIDEventUniqueKey.begin(); + + while ((e1 != mySIeventsOrderFirstEndTimeServiceIDEventUniqueKey.end()) && !messaging_zap_detected) + { + e2 = e1; + e1++; + if (e1 == mySIeventsOrderFirstEndTimeServiceIDEventUniqueKey.end()) + break; + + /* check for the same service */ + if ((*e1)->get_channel_id() != (*e2)->get_channel_id()) + continue; + /* check for same time */ + if (((*e1)->times.begin()->startzeit != (*e2)->times.begin()->startzeit) || + ((*e1)->times.begin()->dauer != (*e2)->times.begin()->dauer)) + continue; + + if ((*e1)->table_id == (*e2)->table_id) + { + xprintf("%s: not removing events %llx %llx, t:%02x '%s'\n", __func__, + (*e1)->uniqueKey(), (*e2)->uniqueKey(), (*e1)->table_id, (*e1)->getName().c_str()); + continue; + } + + del = mySIeventsOrderFirstEndTimeServiceIDEventUniqueKey.end(); + if ((*e1)->table_id > (*e2)->table_id) + del = e1; + if ((*e1)->table_id < (*e2)->table_id) + del = e2; + + /* can not happen. This check is pure paranoia :) */ + if (del == mySIeventsOrderFirstEndTimeServiceIDEventUniqueKey.end()) + continue; + + xprintf("%s: removing event %llx.%02x '%s'\n", __func__, + (*del)->uniqueKey(), (*del)->table_id, (*del)->getName().c_str()); + unlockEvents(); + deleteEvent((*del)->uniqueKey()); + readLockEvents(); + } + unlockEvents(); + return; +} + #ifdef UPDATE_NETWORKS static void removeWasteEvents() { @@ -8234,10 +8289,15 @@ printf("[sectionsd] Removed %d old events.\n", anzEventsAlt - mySIeventsOrderUni print_meminfo(); dprintf("Removed %d old events.\n", anzEventsAlt - mySIeventsOrderUniqueKey.size()); } + anzEventsAlt = mySIeventsOrderUniqueKey.size(); unlockEvents(); // usleep(100); // lockEvents(); + removeDupEvents(); + readLockEvents(); +printf("[sectionsd] Removed %d dup events.\n", anzEventsAlt - mySIeventsOrderUniqueKey.size()); anzEventsAlt = mySIeventsOrderUniqueKey.size(); + unlockEvents(); dprintf("before removewasteepg\n"); #ifdef UPDATE_NETWORKS removeWasteEvents(); // Events for channels not in services.xml