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 
134  for (auto it = m_cache.begin(); it != m_cache.end(); )
135  {
136  if ((*it)->GetAvailableStatus() == asDeleted)
137  {
138  delete (*it);
139  it = m_cache.erase(it);
140  }
141  else
142  {
143  it++;
144  }
145  }
146 }
147 
153 {
154  QMutexLocker locker(&m_lock);
155 
156  Cache::iterator it = m_cache.find(pginfo.GetRecordingID());
157 
158  if (it != m_cache.end())
159  (*it)->clone(pginfo, true);
160 
161  return it != m_cache.end();
162 }
163 
168 bool ProgramInfoCache::UpdateFileSize(uint recordingID, uint64_t filesize)
169 {
170  QMutexLocker locker(&m_lock);
171 
172  Cache::iterator it = m_cache.find(recordingID);
173 
174  if (it != m_cache.end())
175  {
176  (*it)->SetFilesize(filesize);
177  if (filesize)
178  (*it)->SetAvailableStatus(asAvailable, "PIC::UpdateFileSize");
179  }
180 
181  return it != m_cache.end();
182 }
183 
187 QString ProgramInfoCache::GetRecGroup(uint recordingID) const
188 {
189  QMutexLocker locker(&m_lock);
190 
191  Cache::const_iterator it = m_cache.find(recordingID);
192 
193  QString recgroup;
194  if (it != m_cache.end())
195  recgroup = (*it)->GetRecordingGroup();
196 
197  return recgroup;
198 }
199 
204 {
205  if (!pginfo.GetRecordingID() || Update(pginfo))
206  return;
207 
208  m_cache[pginfo.GetRecordingID()] = new ProgramInfo(pginfo);
209 }
210 
217 {
218  Cache::iterator it = m_cache.find(recordingID);
219 
220  if (it != m_cache.end())
221  (*it)->SetAvailableStatus(asDeleted, "PIC::Remove");
222 
223  return it != m_cache.end();
224 }
225 
226 // two helper functions that are used only in this file
227 namespace {
228  // Sorting functions for ProgramInfoCache::GetOrdered()
229  bool PISort(const ProgramInfo *a, const ProgramInfo *b)
230  {
232  return a->GetChanID() < b->GetChanID();
233  return (a->GetRecordingStartTime() < b->GetRecordingStartTime());
234  }
235 
236  bool reversePISort(const ProgramInfo *a, const ProgramInfo *b)
237  {
239  return a->GetChanID() > b->GetChanID();
240  return (a->GetRecordingStartTime() > b->GetRecordingStartTime());
241  }
242 }
243 
244 void ProgramInfoCache::GetOrdered(vector<ProgramInfo*> &list, bool newest_first)
245 {
246  std::copy(m_cache.cbegin(), m_cache.cend(), std::back_inserter(list));
247 
248  if (newest_first)
249  std::sort(list.begin(), list.end(), reversePISort);
250  else
251  std::sort(list.begin(), list.end(), PISort);
252 
253 }
254 
256 {
257  Cache::const_iterator it = m_cache.find(recordingID);
258 
259  if (it != m_cache.end())
260  return *it;
261 
262  return nullptr;
263 }
264 
267 {
268  for (const auto & pi : qAsConst(m_cache))
269  delete pi;
270  m_cache.clear();
271 }
ProgramInfoCache::Add
void Add(const ProgramInfo &pginfo)
Adds a ProgramInfo to the cache.
Definition: programinfocache.cpp:203
ProgramInfoCache::m_cache
Cache m_cache
Definition: programinfocache.h:57
mythevent.h
ProgramInfoCache::m_loadIsQueued
bool m_loadIsQueued
Definition: programinfocache.h:60
ProgramInfoLoader::ProgramInfoLoader
ProgramInfoLoader(ProgramInfoCache &c, const bool updateUI)
Definition: programinfocache.cpp:34
copy
long long copy(QFile &dst, QFile &src, uint block_size)
Copies src file to dst file.
Definition: mythmiscutil.cpp:314
ProgramInfoCache::GetRecGroup
QString GetRecGroup(uint recordingID) const
Returns the ProgramInfo::recgroup or an empty string if not found.
Definition: programinfocache.cpp:187
ProgramInfoCache::Update
bool Update(const ProgramInfo &pginfo)
Updates a ProgramInfo in the cache.
Definition: programinfocache.cpp:152
asAvailable
@ asAvailable
Definition: programtypes.h:178
ProgramInfoCache
Definition: programinfocache.h:20
ProgramInfoCache::GetOrdered
void GetOrdered(std::vector< ProgramInfo * > &list, bool newest_first=false)
Definition: programinfocache.cpp:244
ProgramInfo::GetRecordingID
uint GetRecordingID(void) const
Definition: programinfo.h:445
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:16
asDeleted
@ asDeleted
Definition: programtypes.h:183
remoteutil.h
ProgramInfoCache::ProgramInfoLoader
friend class ProgramInfoLoader
Definition: programinfocache.h:22
ProgramInfoCache::m_listener
QObject * m_listener
Definition: programinfocache.h:59
ProgramInfo::GetRecordingStartTime
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
Definition: programinfo.h:403
tmp
static guint32 * tmp
Definition: goom_core.cpp:31
ProgramInfoCache::m_loadsInProgress
uint m_loadsInProgress
Definition: programinfocache.h:61
programinfo.h
mythlogging.h
RemoteGetRecordedList
vector< ProgramInfo * > * RemoteGetRecordedList(int sort)
Definition: remoteutil.cpp:16
ProgramInfoLoader::run
void run(void) override
Definition: programinfocache.cpp:37
ProgramInfoLoader::m_updateUI
bool m_updateUI
Definition: programinfocache.cpp:43
ProgramInfoCache::ScheduleLoad
void ScheduleLoad(bool updateUI=true)
Definition: programinfocache.cpp:57
ProgramInfoCache::GetRecordingInfo
ProgramInfo * GetRecordingInfo(uint recordingID) const
Definition: programinfocache.cpp:255
ProgramInfoCache::Refresh
void Refresh(void)
Refreshed the cache.
Definition: programinfocache.cpp:116
free_vec
static void free_vec(VPI_ptr &v)
Definition: programinfocache.cpp:20
uint
unsigned int uint
Definition: compat.h:144
ProgramInfoCache::WaitForLoadToComplete
void WaitForLoadToComplete(void) const
Definition: programinfocache.cpp:99
ProgramInfoCache::IsLoadInProgress
bool IsLoadInProgress(void) const
Definition: programinfocache.cpp:93
ProgramInfoCache::Load
void Load(bool updateUI=true)
Definition: programinfocache.cpp:69
mthreadpool.h
ProgramInfoLoader::m_cache
ProgramInfoCache & m_cache
Definition: programinfocache.cpp:42
ProgramInfo::GetChanID
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:371
ProgramInfoCache::m_lock
QMutex m_lock
Definition: programinfocache.h:56
ProgramInfoLoader
Definition: programinfocache.cpp:31
programinfocache.h
ProgramInfo
Holds information on recordings and videos.
Definition: programinfo.h:67
VPI_ptr
vector< ProgramInfo * > * VPI_ptr
Definition: programinfocache.cpp:19
ProgramInfoCache::m_loadWait
QWaitCondition m_loadWait
Definition: programinfocache.h:62
ProgramInfoCache::~ProgramInfoCache
~ProgramInfoCache()
Definition: programinfocache.cpp:46
ProgramInfoCache::Remove
bool Remove(uint recordingID)
Marks a ProgramInfo in the cache for deletion on the next call to Refresh().
Definition: programinfocache.cpp:216
ProgramInfoCache::UpdateFileSize
bool UpdateFileSize(uint recordingID, uint64_t filesize)
Updates a ProgramInfo in the cache.
Definition: programinfocache.cpp:168
MThreadPool::globalInstance
static MThreadPool * globalInstance(void)
Definition: mthreadpool.cpp:317
ProgramInfoCache::Clear
void Clear(void)
Clears the cache, m_lock must be held when this is called.
Definition: programinfocache.cpp:266
MThreadPool::start
void start(QRunnable *runnable, const QString &debugName, int priority=0)
Definition: mthreadpool.cpp:352
ProgramInfoCache::m_nextCache
std::vector< ProgramInfo * > * m_nextCache
Definition: programinfocache.h:58