Ticket #1728: eitcache_db.diff
File eitcache_db.diff, 13.9 KB (added by , 19 years ago) |
---|
-
libs/libmythtv/dbcheck.cpp
old new using namespace std; 10 10 #include "mythdbcon.h" 11 11 12 12 /// This is the DB schema version expected by the running MythTV instance. 13 const QString currentDatabaseVersion = "113 8";13 const QString currentDatabaseVersion = "1139"; 14 14 15 15 static bool UpdateDBVersionNumber(const QString &newnumber); 16 16 static bool performActualUpdate(const QString updates[], QString version, … … static bool doUpgradeTVDatabaseSchema(vo 2213 2213 return false; 2214 2214 } 2215 2215 2216 if (dbver == "1138") 2217 { 2218 const QString updates[] = { 2219 "CREATE TABLE eit_cache (" 2220 " chanid INT(10) NOT NULL, " 2221 " eventid SMALLINT UNSIGNED NOT NULL, " 2222 " tableid TINYINT UNSIGNED NOT NULL, " 2223 " version TINYINT UNSIGNED NOT NULL, " 2224 " endtime INT UNSIGNED NOT NULL, " 2225 " PRIMARY KEY (chanid, eventid) " 2226 ");", 2227 "", 2228 }; 2229 2230 if (!performActualUpdate(updates, "1139", dbver)) 2231 return false; 2232 } 2233 2216 2234 //"ALTER TABLE capturecard DROP COLUMN dvb_recordts;" in 0.21 2217 2235 //"ALTER TABLE capturecard DROP COLUMN dvb_hw_decoder;" in 0.21 2218 2236 //"ALTER TABLE cardinput DROP COLUMN preference;" in 0.22 -
libs/libmythtv/eitcache.cpp
old new 10 10 11 11 #include "eitcache.h" 12 12 #include "mythcontext.h" 13 #include "mythdbcon.h" 13 14 14 15 #define LOC QString("EITCache: ") 15 16 … … 17 18 const uint EITCache::kVersionMax = 31; 18 19 19 20 EITCache::EITCache() 20 : accessCnt(0), hitCnt(0), tblChgCnt(0), 21 verChgCnt(0), pruneCnt(0), prunedHitCnt(0)21 : accessCnt(0), hitCnt(0), tblChgCnt(0), verChgCnt(0), 22 entryCnt(0), pruneCnt(0), prunedHitCnt(0), wrongChannelHitCnt(0) 22 23 { 23 24 // 24 hours ago 24 25 lastPruneTime = QDateTime::currentDateTime(Qt::UTC).toTime_t() - 86400; 25 26 } 26 27 28 EITCache::~EITCache() 29 { 30 WriteToDB(); 31 } 32 27 33 void EITCache::ResetStatistics(void) 28 34 { 29 35 accessCnt = 0; 30 36 hitCnt = 0; 31 37 tblChgCnt = 0; 32 38 verChgCnt = 0; 39 entryCnt = 0; 33 40 pruneCnt = 0; 34 41 prunedHitCnt = 0; 42 wrongChannelHitCnt = 0; 35 43 } 36 44 37 45 QString EITCache::GetStatistics(void) const … … QString EITCache::GetStatistics(void) co 40 48 return QString( 41 49 "EITCache::statistics: Accesses: %1, Hits: %2, " 42 50 "Table Upgrades %3, New Versions: %4, Entries: %5 " 43 "Pruned entries: %6, pruned Hits: %7.") 51 "Pruned entries: %6, pruned Hits: %7 Discard channel Hit %8 " 52 "Hit Ratio %9.") 44 53 .arg(accessCnt).arg(hitCnt).arg(tblChgCnt).arg(verChgCnt) 45 .arg(eventMap.size()).arg(pruneCnt).arg(prunedHitCnt); 54 .arg(entryCnt).arg(pruneCnt).arg(prunedHitCnt) 55 .arg(wrongChannelHitCnt) 56 .arg((hitCnt+prunedHitCnt+wrongChannelHitCnt)/(double)accessCnt); 57 } 58 59 static inline uint64_t construct_channel(uint networkid, uint tsid, uint serviceid) 60 { 61 return (((uint64_t) networkid << 32) | ((uint64_t) tsid << 16) | 62 ((uint64_t) serviceid)); 63 } 64 65 static inline uint extract_onid(uint64_t channel) 66 { 67 return (channel >> 32) & 0xffff; 68 } 69 70 static inline uint extract_tsid(uint64_t channel) 71 { 72 return (channel >> 16) & 0xffff; 46 73 } 47 74 48 static uint64_t construct_key(uint networkid, uint tsid, 49 uint serviceid, uint eventid) 75 static inline uint extrac_sid(uint64_t channel) 50 76 { 51 return (((uint64_t) networkid << 48) | ((uint64_t) tsid << 32) | 52 ((uint64_t) serviceid << 16) | ((uint64_t) eventid )); 77 return channel & 0xffff; 53 78 } 54 79 55 static uint64_t construct_sig(uint tableid, uint version, uint endtime) 80 static inline uint64_t construct_sig(uint tableid, uint version, uint endtime, 81 bool modified) 56 82 { 57 return (((uint64_t) tableid << 40) | ((uint64_t) version << 32) |58 ((uint64_t) endtime));83 return (((uint64_t) modified << 63) | ((uint64_t) tableid << 40) | 84 ((uint64_t) version << 32) | ((uint64_t) endtime)); 59 85 } 60 86 61 static uint extract_table_id(uint64_t sig)87 static inline uint extract_table_id(uint64_t sig) 62 88 { 63 89 return (sig >> 40) & 0xff; 64 90 } 65 91 66 static uint extract_version(uint64_t sig)92 static inline uint extract_version(uint64_t sig) 67 93 { 68 94 return (sig >> 32) & 0x1f; 69 95 } 70 96 71 static uint extract_endtime(uint64_t sig)97 static inline uint extract_endtime(uint64_t sig) 72 98 { 73 99 return sig & 0xffffffff; 74 100 } 75 101 102 static inline bool modified(uint64_t sig) 103 { 104 return sig >> 63; 105 } 106 107 static int get_chanid_from_db(uint networkid, uint tsid, uint serviceid) 108 { 109 MSqlQuery query(MSqlQuery::InitCon()); 110 111 // DVB Link to chanid 112 QString qstr = 113 "SELECT chanid, useonairguide" 114 "FROM channel, dtv_multiplex " 115 "WHERE serviceid = :SERVICEID AND " 116 " networkid = :NETWORKID AND " 117 " transportid = :TRANSPORTID AND " 118 " channel.mplexid = dtv_multiplex.mplexid"; 119 120 query.prepare(qstr); 121 query.bindValue(":SERVICEID", serviceid); 122 query.bindValue(":NETWORKID", networkid); 123 query.bindValue(":TRANSPORTID", tsid); 124 125 if (!query.exec() || !query.isActive()) 126 MythContext::DBError("Looking up chanID", query); 127 else if (query.next()) 128 { 129 bool useOnAirGuide = query.value(1).toBool(); 130 return (useOnAirGuide) ? query.value(0).toInt() : -1; 131 } 132 return -1; 133 } 134 135 static void replace_in_db(int chanid, uint eventid, uint64_t sig) 136 { 137 138 MSqlQuery query(MSqlQuery::InitCon()); 139 140 QString qstr = 141 "REPLACE INTO eit_cache " 142 " ( chanid, eventid, tableid, version, endtime) " 143 "VALUES (:CHANID, :EVENTID, :TABLEID, :VERSION, :ENDTIME)"; 144 145 query.prepare(qstr); 146 query.bindValue(":CHANID", chanid); 147 query.bindValue(":EVENTID", eventid); 148 query.bindValue(":TABLEID", extract_table_id(sig)); 149 query.bindValue(":VERSION", extract_version(sig)); 150 query.bindValue(":ENDTIME", extract_endtime(sig)); 151 152 if (!query.exec()) 153 MythContext::DBError("Error updating eitcache", query); 154 155 return; 156 } 157 158 159 event_map_t * EITCache::LoadChannel(uint networkid, uint tsid, uint serviceid) 160 { 161 int chanid = get_chanid_from_db(networkid, tsid, serviceid); 162 163 if (chanid < 1) 164 return NULL; 165 166 MSqlQuery query(MSqlQuery::InitCon()); 167 168 QString qstr = 169 "SELECT eventid,tableid,version,endtime " 170 "FROM eit_cache " 171 "WHERE chanid = :CHANID AND " 172 " endtime > :ENDTIME"; 173 174 query.prepare(qstr); 175 query.bindValue(":CHANID", chanid); 176 query.bindValue(":ENDTIME", lastPruneTime); 177 178 if (!query.exec() || !query.isActive()) 179 { 180 MythContext::DBError("Error loading eitcache", query); 181 return NULL; 182 } 183 184 event_map_t * eventMap = new event_map_t(); 185 186 while (query.next()) 187 { 188 uint eventid = query.value(0).toUInt(); 189 uint tableid = query.value(1).toUInt(); 190 uint version = query.value(2).toUInt(); 191 uint endtime = query.value(3).toUInt(); 192 193 (*eventMap)[eventid] = construct_sig(tableid, version, endtime, false); 194 } 195 196 VERBOSE(VB_EIT, LOC + QString("Loaded %1 entries for channel %2") 197 .arg(eventMap->size()).arg(chanid)); 198 199 entryCnt += eventMap->size(); 200 return eventMap; 201 } 202 203 204 void EITCache::DropChannel(uint64_t channel) 205 { 206 int chanid = get_chanid_from_db(extract_onid(channel), 207 extract_tsid(channel), 208 extrac_sid(channel)); 209 210 if (chanid < 1) 211 return; 212 213 event_map_t * eventMap = channelMap[channel]; 214 215 uint size = eventMap->size(); 216 uint written = 0; 217 218 event_map_t::iterator it = eventMap->begin(); 219 while (it != eventMap->end()) 220 { 221 if (modified(*it) && extract_endtime(*it) > lastPruneTime) 222 { 223 replace_in_db(chanid, it.key(), *it); 224 written++; 225 } 226 227 event_map_t::iterator tmp = it; 228 ++tmp; 229 eventMap->erase(it); 230 it = tmp; 231 } 232 channelMap.erase(channel); 233 234 VERBOSE(VB_EIT, LOC + QString("Writed %1 modified entries of %2 " 235 "for channel %3 to database.") 236 .arg(written).arg(size).arg(chanid)); 237 entryCnt -= size; 238 } 239 240 void EITCache::WriteToDB(void) 241 { 242 QMutexLocker locker(&eventMapLock); 243 244 key_map_t::iterator it = channelMap.begin(); 245 while (it != channelMap.end()) 246 { 247 key_map_t::iterator tmp = it; 248 ++tmp; 249 DropChannel(it.key()); 250 it = tmp; 251 } 252 entryCnt = 0; 253 } 254 255 256 76 257 bool EITCache::IsNewEIT(uint networkid, uint tsid, uint serviceid, 77 258 uint tableid, uint version, 78 259 uint eventid, uint endtime) 79 260 { 80 261 accessCnt++; 81 262 263 if (accessCnt % 500000 == 50000) 264 { 265 cerr << GetStatistics() << endl; 266 WriteToDB(); 267 } 268 82 269 // don't readd pruned entries 83 270 if (endtime < lastPruneTime) 84 271 { … … bool EITCache::IsNewEIT(uint networkid, 86 273 return false; 87 274 } 88 275 89 uint64_t key = construct_key(networkid, tsid, serviceid, eventid);276 uint64_t channel = construct_channel(networkid, tsid, serviceid); 90 277 91 278 QMutexLocker locker(&eventMapLock); 92 key_map_t::const_iterator it = eventMap.find(key); 279 if (!channelMap.contains(channel)) 280 { 281 channelMap[channel] = LoadChannel(networkid, tsid, serviceid); 282 } 93 283 94 if (it != eventMap.end()) 284 if (!channelMap[channel]) 285 { 286 wrongChannelHitCnt++; 287 return false; 288 } 289 290 event_map_t * eventMap = channelMap[channel]; 291 event_map_t::iterator it = eventMap->find(eventid); 292 if (it != eventMap->end()) 95 293 { 96 294 if (extract_table_id(*it) > tableid) 97 295 { … … bool EITCache::IsNewEIT(uint networkid, 113 311 return false; 114 312 } 115 313 } 116 117 e ventMap[key] = construct_sig(tableid, version, endtime);314 eventMap->insert(eventid, construct_sig(tableid, version, endtime, true)); 315 entryCnt++; 118 316 119 317 return true; 120 318 } … … uint EITCache::PruneOldEntries(uint time 133 331 tmptime.toString(Qt::ISODate)); 134 332 } 135 333 136 QMutexLocker locker(&eventMapLock);137 uint orig_size = eventMap.size();138 139 key_map_t::iterator it = eventMap.begin();140 while (it != eventMap.end())141 {142 if (extract_endtime(*it) < timestamp)143 {144 key_map_t::iterator tmp = it;145 ++tmp;146 eventMap.erase(it);147 it = tmp;148 continue;149 }150 ++it;151 }152 153 uint pruned = orig_size - eventMap.size();154 prunedHitCnt += pruned;155 334 lastPruneTime = timestamp; 335 //Write all modified entries to DB and start with a clean cache 336 WriteToDB(); 337 // TODO: prune old entries in the DB 156 338 157 return pruned;339 return 0; 158 340 } 159 341 160 342 /* vim: set expandtab tabstop=4 shiftwidth=4: */ -
libs/libmythtv/eitcache.h
old new 13 13 #include <qmutex.h> 14 14 #include <qstring.h> 15 15 16 typedef QMap<uint64_t, uint64_t> key_map_t; 16 typedef QMap<uint, uint64_t> event_map_t; 17 typedef QMap<uint64_t, event_map_t*> key_map_t; 17 18 18 19 class EITCache 19 20 { 20 21 public: 21 22 EITCache(); 22 ~EITCache() {};23 ~EITCache(); 23 24 24 25 bool IsNewEIT(uint networkid, uint tsid, uint serviceid, 25 26 uint tableid, uint version, … … class EITCache 31 32 QString GetStatistics(void) const; 32 33 33 34 private: 35 event_map_t * LoadChannel(uint networkid, uint tsid, uint serviceid); 36 void DropChannel(uint64_t channel); 37 void WriteToDB(void); 38 34 39 // event key cache 35 key_map_t eventMap;40 key_map_t channelMap; 36 41 37 42 mutable QMutex eventMapLock; 38 43 uint lastPruneTime; … … class EITCache 42 47 uint hitCnt; 43 48 uint tblChgCnt; 44 49 uint verChgCnt; 50 uint entryCnt; 45 51 uint pruneCnt; 46 52 uint prunedHitCnt; 53 uint wrongChannelHitCnt; 47 54 48 55 static const uint kVersionMax; 49 56 }; -
libs/libmythtv/eithelper.h
old new class EITHelper 69 69 70 70 void AddEIT(const DVBEventInformationTable *eit); 71 71 72 void PruneCache(uint timestamp); 73 72 74 private: 73 75 uint GetChanID(uint atscsrcid); 74 76 uint GetChanID(uint serviceid, uint networkid, uint transportid); -
libs/libmythtv/eitscanner.cpp
old new void EITScanner::RunEventLoop(void) 135 135 activeScanNextTrig = QDateTime::currentDateTime() 136 136 .addSecs(activeScanTrigTime); 137 137 activeScanNextChan++; 138 139 // 24 hours ago 140 eitHelper->PruneCache(activeScanNextTrig.toTime_t() - 86400); 138 141 } 139 142 140 143 exitThreadCond.wait(200); // sleep up to 200 ms. -
libs/libmythtv/eithelper.cpp
old new void EITHelper::AddEIT(const DVBEventInf 336 336 } 337 337 } 338 338 339 void EITHelper::PruneCache(uint timestamp) 340 { 341 eitcache->PruneOldEntries(timestamp); 342 } 343 339 344 ////////////////////////////////////////////////////////////////////// 340 345 // private methods and functions below this line // 341 346 //////////////////////////////////////////////////////////////////////