MythTV  master
programinfocache.cpp
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 // vim:set sw=4 ts=4 expandtab:
3 // Copyright (c) 2009, Daniel Thor Kristjansson
4 // Distributed as part of MythTV under GPL version 2
5 // (or at your option a later version)
6 
7 #include "programinfocache.h"
8 #include "mthreadpool.h"
9 #include "mythlogging.h"
10 #include "programinfo.h"
11 #include "remoteutil.h"
12 #include "mythevent.h"
13 
14 #include <QCoreApplication>
15 #include <QRunnable>
16 
17 #include <algorithm>
18 
19 using VPI_ptr = vector<ProgramInfo *> *;
20 static void free_vec(VPI_ptr &v)
21 {
22  if (v)
23  {
24  for (auto & it : *v)
25  delete it;
26  delete v;
27  v = nullptr;
28  }
29 }
30 
31 class ProgramInfoLoader : public QRunnable
32 {
33  public:
34  ProgramInfoLoader(ProgramInfoCache &c, const bool updateUI)
35  : m_cache(c), m_updateUI(updateUI) {}
36 
37  void run(void) override // QRunnable
38  {
40  }
41 
43  bool m_updateUI;
44 };
45 
47 {
48  QMutexLocker locker(&m_lock);
49 
50  while (m_loadsInProgress)
51  m_loadWait.wait(&m_lock);
52 
53  Clear();
55 }
56 
57 void ProgramInfoCache::ScheduleLoad(const bool updateUI)
58 {
59  QMutexLocker locker(&m_lock);
60  if (!m_loadIsQueued)
61  {
62  m_loadIsQueued = true;
65  new ProgramInfoLoader(*this, updateUI), "ProgramInfoLoader");
66  }
67 }
68 
69 void ProgramInfoCache::Load(const bool updateUI)
70 {
71  QMutexLocker locker(&m_lock);
72  m_loadIsQueued = false;
73 
74  locker.unlock();
75 
76  // Get an unsorted list (sort = 0) from RemoteGetRecordedList
77  // we sort the list later anyway.
78  vector<ProgramInfo*> *tmp = RemoteGetRecordedList(0);
79 
80  locker.relock();
81 
83  m_nextCache = tmp;
84 
85  if (updateUI)
86  QCoreApplication::postEvent(
87  m_listener, new MythEvent("UPDATE_UI_LIST"));
88 
90  m_loadWait.wakeAll();
91 }
92 
94 {
95  QMutexLocker locker(&m_lock);
96  return m_loadsInProgress != 0U;
97 }
98 
100 {
101  QMutexLocker locker(&m_lock);
102  while (m_loadsInProgress)
103  m_loadWait.wait(&m_lock);
104 }
105 
117 {
118  QMutexLocker locker(&m_lock);
119  if (m_nextCache)
120  {
121  Clear();
122  for (auto & it : *m_nextCache)
123  {
124  if (!it->GetChanID())
125  continue;
126 
127  m_cache[it->GetRecordingID()] = it;
128  }
129  delete m_nextCache;
130  m_nextCache = nullptr;
131  return;
132  }
133  locker.unlock();
134 
135  Cache::iterator it = m_cache.begin();
136  Cache::iterator nit = it;
137  for (; it != m_cache.end(); it = nit)
138  {
139  nit = it;
140  ++nit;
141 
142  if ((*it)->GetAvailableStatus() == asDeleted)
143  {
144  delete (*it);
145  m_cache.erase(it);
146  }
147  }
148 }
149 
155 {
156  QMutexLocker locker(&m_lock);
157 
158  Cache::iterator it = m_cache.find(pginfo.GetRecordingID());
159 
160  if (it != m_cache.end())
161  (*it)->clone(pginfo, true);
162 
163  return it != m_cache.end();
164 }
165 
170 bool ProgramInfoCache::UpdateFileSize(uint recordingID, uint64_t filesize)
171 {
172  QMutexLocker locker(&m_lock);
173 
174  Cache::iterator it = m_cache.find(recordingID);
175 
176  if (it != m_cache.end())
177  {
178  (*it)->SetFilesize(filesize);
179  if (filesize)
180  (*it)->SetAvailableStatus(asAvailable, "PIC::UpdateFileSize");
181  }
182 
183  return it != m_cache.end();
184 }
185 
189 QString ProgramInfoCache::GetRecGroup(uint recordingID) const
190 {
191  QMutexLocker locker(&m_lock);
192 
193  Cache::const_iterator it = m_cache.find(recordingID);
194 
195  QString recgroup;
196  if (it != m_cache.end())
197  recgroup = (*it)->GetRecordingGroup();
198 
199  return recgroup;
200 }
201 
206 {
207  if (!pginfo.GetRecordingID() || Update(pginfo))
208  return;
209 
210  m_cache[pginfo.GetRecordingID()] = new ProgramInfo(pginfo);
211 }
212 
219 {
220  Cache::iterator it = m_cache.find(recordingID);
221 
222  if (it != m_cache.end())
223  (*it)->SetAvailableStatus(asDeleted, "PIC::Remove");
224 
225  return it != m_cache.end();
226 }
227 
228 // two helper functions that are used only in this file
229 namespace {
230  // Sorting functions for ProgramInfoCache::GetOrdered()
231  bool PISort(const ProgramInfo *a, const ProgramInfo *b)
232  {
234  return a->GetChanID() < b->GetChanID();
235  return (a->GetRecordingStartTime() < b->GetRecordingStartTime());
236  }
237 
238  bool reversePISort(const ProgramInfo *a, const ProgramInfo *b)
239  {
241  return a->GetChanID() > b->GetChanID();
242  return (a->GetRecordingStartTime() > b->GetRecordingStartTime());
243  }
244 }
245 
246 void ProgramInfoCache::GetOrdered(vector<ProgramInfo*> &list, bool newest_first)
247 {
248  foreach (auto & pi, m_cache)
249  list.push_back(pi);
250 
251  if (newest_first)
252  std::sort(list.begin(), list.end(), reversePISort);
253  else
254  std::sort(list.begin(), list.end(), PISort);
255 
256 }
257 
259 {
260  Cache::const_iterator it = m_cache.find(recordingID);
261 
262  if (it != m_cache.end())
263  return *it;
264 
265  return nullptr;
266 }
267 
270 {
271  foreach (auto & pi, m_cache)
272  delete pi;
273  m_cache.clear();
274 }
void run(void) override
void ScheduleLoad(bool updateUI=true)
ProgramInfoCache & m_cache
void WaitForLoadToComplete(void) const
ProgramInfo * GetRecordingInfo(uint recordingID) const
void Refresh(void)
Refreshed the cache.
void Load(bool updateUI=true)
QWaitCondition m_loadWait
vector< ProgramInfo * > * m_nextCache
bool Remove(uint recordingID)
Marks a ProgramInfo in the cache for deletion on the next call to Refresh().
bool IsLoadInProgress(void) const
static guint32 * tmp
Definition: goom_core.c:35
void Add(const ProgramInfo &pginfo)
Adds a ProgramInfo to the cache.
vector< ProgramInfo * > * VPI_ptr
Holds information on recordings and videos.
Definition: programinfo.h:67
This class is used as a container for messages.
Definition: mythevent.h:16
bool UpdateFileSize(uint recordingID, uint64_t filesize)
Updates a ProgramInfo in the cache.
void Clear(void)
Clears the cache, m_lock must be held when this is called.
uint GetRecordingID(void) const
Definition: programinfo.h:440
unsigned int uint
Definition: compat.h:140
ProgramInfoLoader(ProgramInfoCache &c, const bool updateUI)
bool Update(const ProgramInfo &pginfo)
Updates a ProgramInfo in the cache.
static MThreadPool * globalInstance(void)
void start(QRunnable *runnable, const QString &debugName, int priority=0)
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:366
QString GetRecGroup(uint recordingID) const
Returns the ProgramInfo::recgroup or an empty string if not found.
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
Definition: programinfo.h:398
static void free_vec(VPI_ptr &v)
vector< ProgramInfo * > * RemoteGetRecordedList(int sort)
Definition: remoteutil.cpp:16
void GetOrdered(vector< ProgramInfo * > &list, bool newest_first=false)
friend class ProgramInfoLoader