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 typedef vector<ProgramInfo*> *VPI_ptr;
20 static void free_vec(VPI_ptr &v)
21 {
22  if (v)
23  {
24  vector<ProgramInfo*>::iterator it = v->begin();
25  for (; it != v->end(); ++it)
26  delete *it;
27  delete v;
28  v = nullptr;
29  }
30 }
31 
32 class ProgramInfoLoader : public QRunnable
33 {
34  public:
35  ProgramInfoLoader(ProgramInfoCache &c, const bool updateUI)
36  : m_cache(c), m_updateUI(updateUI) {}
37 
38  void run(void) override // QRunnable
39  {
41  }
42 
44  bool m_updateUI;
45 };
46 
48 {
49  QMutexLocker locker(&m_lock);
50 
51  while (m_loads_in_progress)
52  m_load_wait.wait(&m_lock);
53 
54  Clear();
56 }
57 
58 void ProgramInfoCache::ScheduleLoad(const bool updateUI)
59 {
60  QMutexLocker locker(&m_lock);
61  if (!m_load_is_queued)
62  {
63  m_load_is_queued = true;
66  new ProgramInfoLoader(*this, updateUI), "ProgramInfoLoader");
67  }
68 }
69 
70 void ProgramInfoCache::Load(const bool updateUI)
71 {
72  QMutexLocker locker(&m_lock);
73  m_load_is_queued = false;
74 
75  locker.unlock();
76 
77  // Get an unsorted list (sort = 0) from RemoteGetRecordedList
78  // we sort the list later anyway.
79  vector<ProgramInfo*> *tmp = RemoteGetRecordedList(0);
80 
81  locker.relock();
82 
84  m_next_cache = tmp;
85 
86  if (updateUI)
87  QCoreApplication::postEvent(
88  m_listener, new MythEvent("UPDATE_UI_LIST"));
89 
91  m_load_wait.wakeAll();
92 }
93 
95 {
96  QMutexLocker locker(&m_lock);
97  return m_loads_in_progress != 0U;
98 }
99 
101 {
102  QMutexLocker locker(&m_lock);
103  while (m_loads_in_progress)
104  m_load_wait.wait(&m_lock);
105 }
106 
118 {
119  QMutexLocker locker(&m_lock);
120  if (m_next_cache)
121  {
122  Clear();
123  vector<ProgramInfo*>::iterator it = m_next_cache->begin();
124  for (; it != m_next_cache->end(); ++it)
125  {
126  if (!(*it)->GetChanID())
127  continue;
128 
129  m_cache[(*it)->GetRecordingID()] = *it;
130  }
131  delete m_next_cache;
132  m_next_cache = nullptr;
133  return;
134  }
135  locker.unlock();
136 
137  Cache::iterator it = m_cache.begin();
138  Cache::iterator nit = it;
139  for (; it != m_cache.end(); it = nit)
140  {
141  nit = it;
142  ++nit;
143 
144  if ((*it)->GetAvailableStatus() == asDeleted)
145  {
146  delete (*it);
147  m_cache.erase(it);
148  }
149  }
150 }
151 
157 {
158  QMutexLocker locker(&m_lock);
159 
160  Cache::iterator it = m_cache.find(pginfo.GetRecordingID());
161 
162  if (it != m_cache.end())
163  (*it)->clone(pginfo, true);
164 
165  return it != m_cache.end();
166 }
167 
172 bool ProgramInfoCache::UpdateFileSize(uint recordingID, uint64_t filesize)
173 {
174  QMutexLocker locker(&m_lock);
175 
176  Cache::iterator it = m_cache.find(recordingID);
177 
178  if (it != m_cache.end())
179  {
180  (*it)->SetFilesize(filesize);
181  if (filesize)
182  (*it)->SetAvailableStatus(asAvailable, "PIC::UpdateFileSize");
183  }
184 
185  return it != m_cache.end();
186 }
187 
191 QString ProgramInfoCache::GetRecGroup(uint recordingID) const
192 {
193  QMutexLocker locker(&m_lock);
194 
195  Cache::const_iterator it = m_cache.find(recordingID);
196 
197  QString recgroup;
198  if (it != m_cache.end())
199  recgroup = (*it)->GetRecordingGroup();
200 
201  return recgroup;
202 }
203 
208 {
209  if (!pginfo.GetRecordingID() || Update(pginfo))
210  return;
211 
212  m_cache[pginfo.GetRecordingID()] = new ProgramInfo(pginfo);
213 }
214 
221 {
222  Cache::iterator it = m_cache.find(recordingID);
223 
224  if (it != m_cache.end())
225  (*it)->SetAvailableStatus(asDeleted, "PIC::Remove");
226 
227  return it != m_cache.end();
228 }
229 
230 // two helper functions that are used only in this file
231 namespace {
232  // Sorting functions for ProgramInfoCache::GetOrdered()
233  bool PISort(const ProgramInfo *a, const ProgramInfo *b)
234  {
235  if (a->GetRecordingStartTime() == b->GetRecordingStartTime())
236  return a->GetChanID() < b->GetChanID();
237  return (a->GetRecordingStartTime() < b->GetRecordingStartTime());
238  }
239 
240  bool reversePISort(const ProgramInfo *a, const ProgramInfo *b)
241  {
242  if (a->GetRecordingStartTime() == b->GetRecordingStartTime())
243  return a->GetChanID() > b->GetChanID();
244  return (a->GetRecordingStartTime() > b->GetRecordingStartTime());
245  }
246 }
247 
248 void ProgramInfoCache::GetOrdered(vector<ProgramInfo*> &list, bool newest_first)
249 {
250  for (Cache::iterator it = m_cache.begin(); it != m_cache.end(); ++it)
251  list.push_back(*it);
252 
253  if (newest_first)
254  std::sort(list.begin(), list.end(), reversePISort);
255  else
256  std::sort(list.begin(), list.end(), PISort);
257 
258 }
259 
261 {
262  Cache::const_iterator it = m_cache.find(recordingID);
263 
264  if (it != m_cache.end())
265  return *it;
266 
267  return nullptr;
268 }
269 
272 {
273  for (Cache::iterator it = m_cache.begin(); it != m_cache.end(); ++it)
274  delete (*it);
275  m_cache.clear();
276 }
void run(void) override
void ScheduleLoad(const bool updateUI=true)
ProgramInfoCache & m_cache
void WaitForLoadToComplete(void) const
ProgramInfo * GetRecordingInfo(uint recordingID) const
void Refresh(void)
Refreshed the cache.
vector< ProgramInfo * > * m_next_cache
QWaitCondition m_load_wait
unsigned int uint
Definition: compat.h:140
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
bool Update(const ProgramInfo &)
Updates a ProgramInfo in the cache.
unsigned char b
Definition: ParseText.cpp:329
Holds information on recordings and videos.
Definition: programinfo.h:66
This class is used as a container for messages.
Definition: mythevent.h:16
void Load(const bool updateUI=true)
bool UpdateFileSize(uint recordingID, uint64_t filesize)
Updates a ProgramInfo in the cache.
vector< ProgramInfo * > * VPI_ptr
void Clear(void)
Clears the cache, m_lock must be held when this is called.
uint GetRecordingID(void) const
Definition: programinfo.h:438
ProgramInfoLoader(ProgramInfoCache &c, const bool updateUI)
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:364
QString GetRecGroup(uint recordingID) const
Returns the ProgramInfo::recgroup or an empty string if not found.
void Add(const ProgramInfo &)
Adds a ProgramInfo to the cache.
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
Definition: programinfo.h:396
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