rendered paste bodyIndex: libs/libmythtv/tvosdmenuentry.h
===================================================================
--- libs/libmythtv/tvosdmenuentry.h (revision 22742)
+++ libs/libmythtv/tvosdmenuentry.h (working copy)
@@ -63,7 +63,7 @@
TVOSDMenuEntry* FindEntry(QString category);
private:
- void GetEntriesFromDB(void);
+ int GetEntriesFromDB(void);
void InitDefaultEntries(void);
QList<TVOSDMenuEntry*> curMenuEntries;
Index: libs/libmythtv/tv_play.cpp
===================================================================
--- libs/libmythtv/tv_play.cpp (revision 22742)
+++ libs/libmythtv/tv_play.cpp (working copy)
@@ -839,45 +839,167 @@
pseudoChangeChanTimerId(0), speedChangeTimerId(0),
errorRecoveryTimerId(0), exitPlayerTimerId(0)
{
- VERBOSE(VB_PLAYBACK, LOC + "ctor");
+ VERBOSE(VB_PLAYBACK, LOC + "ctor -- begin");
setObjectName("TV");
keyRepeatTimer.start();
- db_idle_timeout = gContext->GetNumSetting("LiveTVIdleTimeout", 0);
- db_idle_timeout *= 60 * 1000; // convert from minutes to ms.
- db_udpnotify_port = gContext->GetNumSetting("UDPNotifyPort", 0);
- db_browse_max_forward = gContext->GetNumSetting("BrowseMaxForward",240)*60;
- db_playback_exit_prompt= gContext->GetNumSetting("PlaybackExitPrompt", 0);
- db_autoexpire_default = gContext->GetNumSetting("AutoExpireDefault", 0);
+ QStringList keys;
+ QStringList values;
+ keys.push_back("LiveTVIdleTimeout");
+ values.push_back("0");
+ keys.push_back("UDPNotifyPort");
+ values.push_back("0");
+ keys.push_back("BrowseMaxForward");
+ values.push_back("240");
+ keys.push_back("PlaybackExitPrompt");
+ values.push_back("0");
+ keys.push_back("AutoExpireDefault");
+ values.push_back("0");
+ keys.push_back("AutomaticSetWatched");
+ values.push_back("0");
+ keys.push_back("EndOfRecordingExitPrompt");
+ values.push_back("0");
+ keys.push_back("JumpToProgramOSD");
+ values.push_back("1");
+ keys.push_back("GuiSizeForTV");
+ values.push_back("0");
+ keys.push_back("WatchTVGuide");
+ values.push_back("0");
+ keys.push_back("AltClearSavedPosition");
+ values.push_back("1");
+ keys.push_back("JobsRunOnRecordHost");
+ values.push_back("0");
+ keys.push_back("EnableDVDBookmark");
+ values.push_back("0");
+ keys.push_back("ContinueEmbeddedTVPlay");
+ values.push_back("0");
+ keys.push_back("UseFixedWindowSize");
+ values.push_back("1");
+ keys.push_back("PersistentBrowseMode");
+ values.push_back("0");
+ keys.push_back("BrowseAllTuners");
+ values.push_back("0");
+ keys.push_back("ChannelOrdering");
+ values.push_back("channum");
- db_auto_set_watched = gContext->GetNumSetting("AutomaticSetWatched", 0);
- db_end_of_rec_exit_prompt =
- gContext->GetNumSetting("EndOfRecordingExitPrompt", 0);
- db_jump_prefer_osd = gContext->GetNumSetting("JumpToProgramOSD", 1);
- db_use_gui_size_for_tv = gContext->GetNumSetting("GuiSizeForTV", 0);
- db_start_in_guide = gContext->GetNumSetting("WatchTVGuide", 0);
- db_toggle_bookmark = gContext->GetNumSetting("AltClearSavedPosition",1);
- db_run_jobs_on_remote = gContext->GetNumSetting("JobsRunOnRecordHost", 0);
- db_use_dvd_bookmark = gContext->GetNumSetting("EnableDVDBookmark", 0);
- db_continue_embedded = gContext->GetNumSetting(
- "ContinueEmbeddedTVPlay", 0);
- db_use_fixed_size = gContext->GetNumSettingOnHost(
- "UseFixedWindowSize", gContext->GetHostName(), 1);
- db_browse_always = gContext->GetNumSetting("PersistentBrowseMode", 0);
- db_browse_all_tuners = gContext->GetNumSetting("BrowseAllTuners", 0);
+ keys.push_back("CustomFilters");
+ values.push_back("");
+ keys.push_back("ChannelFormat");
+ values.push_back("<num> <sign>");
+ keys.push_back("TimeFormat");
+ values.push_back("h:mm AP");
+ keys.push_back("ShortDateFormat");
+ values.push_back("M/d");
+ keys.push_back("SmartChannelChange");
+ values.push_back("0");
+ keys.push_back("IndividualMuteControl");
+ values.push_back("0");
+ keys.push_back("UseArrowAccels");
+ values.push_back("1");
+ keys.push_back("OSDGeneralTimeout");
+ values.push_back("2");
+ keys.push_back("OSDProgramInfoTimeout");
+ values.push_back("3");
+ keys.push_back("TryUnflaggedSkip");
+ values.push_back("0");
+
+ keys.push_back("ChannelGroupDefault");
+ values.push_back("-1");
+ keys.push_back("BrowseChannelGroup");
+ values.push_back("0");
+ keys.push_back("SmartForward");
+ values.push_back("0");
+ keys.push_back("StickyKeys");
+ values.push_back("0");
+ keys.push_back("FFRewReposTime");
+ values.push_back("100");
+ keys.push_back("FFRewReverse");
+ values.push_back("1");
+
+ keys.push_back("ChannelGroupDefault");
+ values.push_back("-1");
+ keys.push_back("BrowseChannelGroup");
+ values.push_back("0");
+ keys.push_back("VbiFormat");
+ values.push_back("");
+ keys.push_back("DecodeVBIFormat");
+ values.push_back("");
+
+ int ff_rew_def[8] = { 3, 5, 10, 20, 30, 60, 120, 180 };
+ for (uint i = 0; i < sizeof(ff_rew_def)/sizeof(ff_rew_def[0]); i++)
+ {
+ keys.push_back(QString("FFRewSpeed%1").arg(i));
+ values.push_back(QString::number(ff_rew_def[i]));
+ }
+
+ QMap<QString,QString> map;
+ bool ok = MythDB::getMythDB()->GetSettings(
+ keys, values, MythDB::kCacheDefaults);
+
+ if (ok)
+ {
+ for (uint i = 0; i < (uint) keys.size(); i++)
+ map[keys[i]] = values[i];
+ }
+
+ // convert from minutes to ms.
+ db_idle_timeout = map["LiveTVIdleTimeout"].toInt() * 60 * 1000;
+ db_udpnotify_port = map["UDPNotifyPort"].toInt();
+ db_browse_max_forward = map["BrowseMaxForward"].toInt() * 60;
+ db_playback_exit_prompt= map["PlaybackExitPrompt"].toInt();
+ db_autoexpire_default = map["AutoExpireDefault"].toInt();
+ db_auto_set_watched = map["AutomaticSetWatched"].toInt();
+ db_end_of_rec_exit_prompt = map["EndOfRecordingExitPrompt"].toInt();
+ db_jump_prefer_osd = map["JumpToProgramOSD"].toInt();
+ db_use_gui_size_for_tv = map["GuiSizeForTV"].toInt();
+ db_start_in_guide = map["WatchTVGuide"].toInt();
+ db_toggle_bookmark = map["AltClearSavedPosition"].toInt();
+ db_run_jobs_on_remote = map["JobsRunOnRecordHost"].toInt();
+ db_use_dvd_bookmark = map["EnableDVDBookmark"].toInt();
+ db_continue_embedded = map["ContinueEmbeddedTVPlay"].toInt();
+ db_use_fixed_size = map["UseFixedWindowSize"].toInt();
+ db_browse_always = map["PersistentBrowseMode"].toInt();
+ db_browse_all_tuners = map["BrowseAllTuners"].toInt();
+ QString channelOrdering= map["ChannelOrdering"];
+ baseFilters += map["CustomFilters"];
+ db_channel_format = map["ChannelFormat"];
+ db_time_format = map["TimeFormat"];
+ db_short_date_format = map["ShortDateFormat"];
+ smartChannelChange = map["SmartChannelChange"].toInt();
+ MuteIndividualChannels = map["IndividualMuteControl"].toInt();
+ arrowAccel = map["UseArrowAccels"].toInt();
+ osd_general_timeout = map["OSDGeneralTimeout"].toInt();
+ osd_prog_info_timeout = map["OSDProgramInfoTimeout"].toInt();
+ tryUnflaggedSkip = map["TryUnflaggedSkip"].toInt();
+ channel_group_id = map["ChannelGroupDefault"].toInt();
+ browse_changrp = map["BrowseChannelGroup"].toInt();
+ smartForward = map["SmartForward"].toInt();
+ stickykeys = map["StickyKeys"].toInt();
+ ff_rew_repos = map["FFRewReposTime"].toFloat() * 0.01f;
+ ff_rew_reverse = map["FFRewReverse"].toInt();
+ channel_group_id = map["ChannelGroupDefault"].toInt();
+ browse_changrp = map["BrowseChannelGroup"].toInt();
+ QString beVBI = map["VbiFormat"];
+ QString feVBI = map["DecodeVBIFormat"];
+
+ for (uint i = 0; i < sizeof(ff_rew_def)/sizeof(ff_rew_def[0]); i++)
+ ff_rew_speeds.push_back(map[QString("FFRewSpeed%1").arg(i)].toInt());
+
+ // process it..
+
if (db_browse_all_tuners)
{
QMutexLocker locker(&browseLock);
- QString channelOrdering = gContext->GetSetting(
- "ChannelOrdering", "channum");
db_browse_all_channels = ChannelUtil::GetChannels(
0, true, "channum, callsign");
ChannelUtil::SortChannels(
db_browse_all_channels, channelOrdering, true);
}
+ vbimode = VBIMode::Parse(!feVBI.isEmpty() ? feVBI : beVBI);
+
sleep_times.push_back(SleepTimerInfo(QObject::tr("Off"), 0));
sleep_times.push_back(SleepTimerInfo(QObject::tr("30m"), 30*60));
sleep_times.push_back(SleepTimerInfo(QObject::tr("1h"), 60*60));
@@ -892,6 +1014,7 @@
player.push_back(new PlayerContext("player"));
playerActive = 0;
playerLock.unlock();
+ VERBOSE(VB_PLAYBACK, LOC + "ctor -- end");
}
/** \fn TV::Init(bool)
@@ -902,6 +1025,8 @@
*/
bool TV::Init(bool createWindow)
{
+ VERBOSE(VB_PLAYBACK, LOC + "Init -- begin");
+
MSqlQuery query(MSqlQuery::InitCon());
if (!query.isConnected())
{
@@ -910,35 +1035,6 @@
return false;
}
- baseFilters += gContext->GetSetting("CustomFilters");
- db_channel_format =gContext->GetSetting("ChannelFormat","<num> <sign>");
- db_time_format = gContext->GetSetting("TimeFormat", "h:mm AP");
- db_short_date_format = gContext->GetSetting("ShortDateFormat", "M/d");
- smartChannelChange = gContext->GetNumSetting("SmartChannelChange", 0);
- MuteIndividualChannels=gContext->GetNumSetting("IndividualMuteControl", 0);
- arrowAccel = gContext->GetNumSetting("UseArrowAccels", 1);
- osd_general_timeout = gContext->GetNumSetting("OSDGeneralTimeout", 2);
- osd_prog_info_timeout= gContext->GetNumSetting("OSDProgramInfoTimeout", 3);
- tryUnflaggedSkip = gContext->GetNumSetting("TryUnflaggedSkip", 0);
- channel_group_id = gContext->GetNumSetting("ChannelGroupDefault", -1);
- browse_changrp = gContext->GetNumSetting("BrowseChannelGroup", 0);
- smartForward = gContext->GetNumSetting("SmartForward", 0);
- stickykeys = gContext->GetNumSetting("StickyKeys");
- ff_rew_repos = gContext->GetNumSetting("FFRewReposTime", 100)/100.0;
- ff_rew_reverse = gContext->GetNumSetting("FFRewReverse", 1);
- int def[8] = { 3, 5, 10, 20, 30, 60, 120, 180 };
- for (uint i = 0; i < sizeof(def)/sizeof(def[0]); i++)
- ff_rew_speeds.push_back(
- gContext->GetNumSetting(QString("FFRewSpeed%1").arg(i), def[i]));
-
- vbimode = VBIMode::Parse(gContext->GetSetting("VbiFormat"));
- QString feVBI = gContext->GetSetting("DecodeVBIFormat", "");
- if (!feVBI.isEmpty())
- vbimode = VBIMode::Parse(gContext->GetSetting(feVBI));
-
- channel_group_id = gContext->GetNumSetting("ChannelGroupDefault", -1);
- browse_changrp = gContext->GetNumSetting("BrowseChannelGroup", 0);
-
if (browse_changrp && (channel_group_id > -1))
{
m_channellist = ChannelUtil::GetChannels(0, true, "channum, callsign", channel_group_id);
@@ -947,6 +1043,8 @@
m_changrplist = ChannelGroup::GetChannelGroups();
+ VERBOSE(VB_PLAYBACK, LOC + "Init -- end channel groups");
+
if (createWindow)
{
bool fullscreen = !gContext->GetNumSetting("GuiSizeForTV", 0);
@@ -1040,6 +1138,7 @@
mainLoopCondLock.unlock();
+ VERBOSE(VB_PLAYBACK, LOC + "Init -- end");
return true;
}
Index: libs/libmythtv/tvosdmenuentry.cpp
===================================================================
--- libs/libmythtv/tvosdmenuentry.cpp (revision 22742)
+++ libs/libmythtv/tvosdmenuentry.cpp (working copy)
@@ -238,54 +238,67 @@
curMenuEntries.append(new TVOSDMenuEntry(
"SLEEP", 1, 1, 1, 1, "Sleep"));
- GetEntriesFromDB();
- if (GetCount() != curMenuEntries.count())
+ int preload_cnt = curMenuEntries.size();
+ int loaded_cnt = GetEntriesFromDB();
+ if (preload_cnt != loaded_cnt)
UpdateDB();
}
int TVOSDMenuEntryList::GetCount(void)
{
- MSqlQuery query(MSqlQuery::InitCon());
- if (!query.isConnected())
- return curMenuEntries.count();
+ return (int) curMenuEntries.size();
+}
- query.prepare ("SELECT COUNT(osdcategory) FROM tvosdmenu;");
- if (query.exec() && query.isActive() && query.size() > 0)
+// Returns the number of entries intialized from database.
+int TVOSDMenuEntryList::GetEntriesFromDB(void)
+{
+ typedef QList<TVOSDMenuEntry*>::iterator Lit;
+ QMap<QString,Lit> catmap;
+ Lit it = curMenuEntries.begin();
+ QString catlist("");
+ for (; it != curMenuEntries.end(); ++it)
{
- query.next();
- return query.value(0).toUInt();
+ QString cat = (*it)->GetCategory();
+ catlist += QString("'%1',").arg(cat);
+ catmap[cat] = it;
}
- MythDB::DBError(LOC + "GetCount()", query);
- return 0;
-}
+ if (catlist.isEmpty())
+ return 0;
-void TVOSDMenuEntryList::GetEntriesFromDB(void)
-{
+ catlist = catlist.left(catlist.length() - 1);
MSqlQuery query(MSqlQuery::InitCon());
- if (!query.isConnected())
- return;
+ query.prepare(
+ QString(
+ "SELECT osdcategory, livetv, recorded, video, dvd "
+ "FROM tvosdmenu "
+ "WHERE osdcategory IN (%1)").arg(catlist));
- TVOSDMenuEntry *entry = NULL;
- QString osdcategory;
- QListIterator<TVOSDMenuEntry *> cm = GetIterator();
- while (cm.hasNext())
+ if (!query.exec())
{
- entry = cm.next();
- osdcategory = entry->GetCategory();
- query.prepare("SELECT livetv, recorded, video, dvd "
- "FROM tvosdmenu WHERE osdcategory = :OSDCATEGORY;");
- query.bindValue(":OSDCATEGORY", osdcategory);
+ MythDB::DBError("TVOSDMenuEntryList::GetEntriesFromDB()", query);
+ return 0;
+ }
- if (query.exec() && query.isActive() && query.size() == 1)
+ int cnt = 0;
+ while (query.next())
+ {
+ QString cat = query.value(0).toString();
+ QMap<QString,Lit>::iterator mit = catmap.find(cat);
+ if (mit == catmap.end())
{
- query.next();
- entry->UpdateEntry(query.value(0).toInt(),
- query.value(1).toInt(),
- query.value(2).toInt(),
- query.value(3).toInt());
+ VERBOSE(VB_IMPORTANT, QString("TVOSDMenuEntryList, Error: ") +
+ QString("Unable to find category '%1'").arg(cat));
+ continue;
}
+
+ (**mit)->UpdateEntry(query.value(1).toInt(),
+ query.value(2).toInt(),
+ query.value(3).toInt(),
+ query.value(4).toInt());
+ cnt++;
}
+ return cnt;
}
void TVOSDMenuEntryList::UpdateDB(void)
Index: libs/libmythtv/videoout_xv.h
===================================================================
--- libs/libmythtv/videoout_xv.h (revision 22742)
+++ libs/libmythtv/videoout_xv.h (working copy)
@@ -209,6 +209,7 @@
int non_xv_fps;
PixelFormat non_xv_av_format;
time_t non_xv_stop_time;
+ bool first_show;
// Basic XvMC drawing info
XvMCBufferSettings *xvmc_buf_attr;
Index: libs/libmythtv/videoout_xv.cpp
===================================================================
--- libs/libmythtv/videoout_xv.cpp (revision 22742)
+++ libs/libmythtv/videoout_xv.cpp (working copy)
@@ -114,6 +114,7 @@
XJ_non_xv_image(0), non_xv_frames_shown(0), non_xv_show_frame(1),
non_xv_fps(0), non_xv_av_format(PIX_FMT_NB), non_xv_stop_time(0),
+ first_show(true),
xvmc_buf_attr(new XvMCBufferSettings()),
xvmc_chroma(XVMC_CHROMA_FORMAT_420), xvmc_ctx(NULL),
@@ -2464,6 +2465,12 @@
// this is documented in videooutbase.cpp
void VideoOutputXv::Show(FrameScanType scan)
{
+ if (first_show)
+ {
+ VERBOSE(VB_IMPORTANT, LOC + "First Show");
+ first_show = false;
+ }
+
if (IsErrored())
{
VERBOSE(VB_IMPORTANT, LOC_ERR + "IsErrored() is true in Show()");
Index: libs/libmyth/mythcontext.h
===================================================================
--- libs/libmyth/mythcontext.h (revision 22742)
+++ libs/libmyth/mythcontext.h (working copy)
@@ -114,7 +114,7 @@
QString GetHostName(void);
- void ClearSettingsCache(QString myKey = "", QString newVal = "");
+ void ClearSettingsCache(const QString &myKey = QString(""));
void ActivateSettingsCache(bool activate = true);
void OverrideSettingForSession(const QString &key, const QString &newValue);
Index: libs/libmyth/mythcontext.cpp
===================================================================
--- libs/libmyth/mythcontext.cpp (revision 22742)
+++ libs/libmyth/mythcontext.cpp (working copy)
@@ -1895,9 +1895,9 @@
return ret;
}
-void MythContext::ClearSettingsCache(QString myKey, QString newVal)
+void MythContext::ClearSettingsCache(const QString &myKey)
{
- d->m_database->ClearSettingsCache(myKey, newVal);
+ d->m_database->ClearSettingsCache(myKey);
}
void MythContext::ActivateSettingsCache(bool activate)
Index: libs/libmythdb/mythdb.cpp
===================================================================
--- libs/libmythdb/mythdb.cpp (revision 22742)
+++ libs/libmythdb/mythdb.cpp (working copy)
@@ -1,4 +1,8 @@
+#include <vector>
+using namespace std;
+
#include <QMutex>
+#include <QReadWriteLock>
#include <QHash>
#include <QSqlError>
@@ -44,6 +48,7 @@
MythDB::destroyMythDB();
}
+typedef QHash<QString,QString> SettingsMap;
class MythDBPrivate
{
@@ -58,18 +63,21 @@
Settings *m_settings;
bool ignoreDatabase;
- bool useSettingsCache;
bool suppressDBMessages;
- QMutex settingsCacheLock;
- QHash <QString, QString> settingsCache; // permanent settings in the DB
- QHash <QString, QString> overriddenSettings; // overridden this session only
+
+ QReadWriteLock settingsCacheLock;
+ volatile bool useSettingsCache;
+ /// Permanent settings in the DB and overridden settings
+ SettingsMap settingsCache;
+ /// Overridden this session only
+ SettingsMap overriddenSettings;
};
static const int settings_reserve = 61;
MythDBPrivate::MythDBPrivate()
: m_settings(new Settings()),
- ignoreDatabase(false), useSettingsCache(false), suppressDBMessages(true)
+ ignoreDatabase(false), suppressDBMessages(true), useSettingsCache(false)
{
m_localhostname.clear();
settingsCache.reserve(settings_reserve);
@@ -174,15 +182,18 @@
d->m_DBparams = params;
}
-void MythDB::SetLocalHostname(QString name)
+void MythDB::SetLocalHostname(const QString &name)
{
- d->m_localhostname = name;
+ if (d->m_localhostname != name.toLower())
+ {
+ d->m_localhostname = name.toLower();
+ ClearSettingsCache();
+ }
}
QString MythDB::GetHostName(void)
{
- QString tmp = d->m_localhostname;
- return tmp;
+ return d->m_localhostname;
}
void MythDB::IgnoreDatabase(bool bIgnore)
@@ -218,16 +229,16 @@
}
bool MythDB::SaveSettingOnHost(const QString &key,
- const QString &newValue,
- const QString &host)
+ const QString &newValue,
+ const QString &host)
{
QString LOC = QString("SaveSettingOnHost('%1') ").arg(key);
bool success = false;
if (d->ignoreDatabase)
{
- ClearSettingsCache(key, newValue);
- ClearSettingsCache(host + ' ' + key, newValue);
+ if (host.toLower() == d->m_localhostname)
+ OverrideSettingForSession(key, newValue);
return true;
}
@@ -284,86 +295,223 @@
VERBOSE(VB_IMPORTANT, LOC + "- database not open");
}
- ClearSettingsCache(key, newValue);
- ClearSettingsCache(host + ' ' + key, newValue);
+ ClearSettingsCache(host + ' ' + key);
return success;
}
-QString MythDB::GetSetting(const QString &key, const QString &defaultval)
+QString MythDB::GetSetting(const QString &_key, const QString &defaultval)
{
+ QString key = _key.toLower();
QString value;
- if (d->overriddenSettings.contains(key))
+ d->settingsCacheLock.lockForRead();
+ if (d->useSettingsCache)
{
- value = d->overriddenSettings[key];
+ SettingsMap::const_iterator it = d->settingsCache.find(key);
+ if (it != d->settingsCache.end())
+ {
+ value = *it;
+ d->settingsCacheLock.unlock();
+ return value;
+ }
+ }
+ else
+ {
+ SettingsMap::const_iterator it = d->overriddenSettings.find(key);
+ if (it != d->overriddenSettings.end())
+ {
+ value = *it;
+ d->settingsCacheLock.unlock();
+ return value;
+ }
+ }
+ d->settingsCacheLock.unlock();
+
+ if (d->ignoreDatabase)
return value;
+
+ MSqlQuery query(MSqlQuery::InitCon());
+ if (!query.isConnected())
+ {
+ VERBOSE(VB_IMPORTANT,
+ QString("Database not open while trying to load setting: %1")
+ .arg(key));
+ return d->m_settings->GetSetting(key, defaultval);
}
- d->settingsCacheLock.lock();
+ query.prepare(
+ "SELECT data "
+ "FROM settings "
+ "WHERE value = :KEY AND hostname = :HOSTNAME");
+ query.bindValue(":KEY", key);
+ query.bindValue(":HOSTNAME", d->m_localhostname);
+
+ if (query.exec() && query.next())
+ {
+ value = query.value(0).toString();
+ }
+ else
+ {
+ query.prepare(
+ "SELECT data "
+ "FROM settings "
+ "WHERE value = :KEY AND hostname IS NULL");
+ query.bindValue(":KEY", key);
- value = d->settingsCache.value(key, "_cold_");
+ if (query.exec() && query.next())
+ {
+ value = query.value(0).toString();
+ }
+ else
+ {
+ return d->m_settings->GetSetting(key, defaultval);
+ }
+ }
- d->settingsCacheLock.unlock();
+ if (d->useSettingsCache)
+ {
+ key.squeeze();
+ value.squeeze();
+ d->settingsCacheLock.lockForWrite();
+ // another thread may have inserted a value into the cache
+ // while we did not have the lock, check first then save
+ if (d->settingsCache.find(key) == d->settingsCache.end())
+ d->settingsCache[key] = value;
+ d->settingsCacheLock.unlock();
+ }
- if (value != "_cold_" && d->useSettingsCache)
- return value;
+ return value;
+}
- bool found = false;
- if (!d->ignoreDatabase)
+bool MythDB::GetSettings(
+ const QStringList &_keys, QStringList &values, CacheBehavior cb)
+{
+ if (_keys.size() != values.size())
+ return false;
+
+ uint done_cnt = 0;
+ vector<bool> done;
+ done.resize(_keys.size(), false);
+
+ QStringList keys;
+ for (uint i = 0; i < (uint) _keys.size(); ++i)
+ keys.push_back(_keys[i].toLower());
+
+ d->settingsCacheLock.lockForRead();
+ if (d->useSettingsCache)
{
- MSqlQuery query(MSqlQuery::InitCon());
- if (query.isConnected())
+ for (uint i = 0; i < (uint) keys.size(); ++i)
{
- query.prepare("SELECT data FROM settings WHERE value "
- "= :KEY AND hostname = :HOSTNAME ;");
- query.bindValue(":KEY", key);
- query.bindValue(":HOSTNAME", d->m_localhostname);
-
- if (query.exec() && query.next())
+ SettingsMap::const_iterator it = d->settingsCache.find(keys[i]);
+ if (it != d->settingsCache.end())
{
- found = true;
- value = query.value(0).toString();
+ values[i] = *it;
+ done[i] = true;
+ done_cnt++;
}
- else
+ }
+ }
+ else
+ {
+ for (uint i = 0; i < (uint) keys.size(); ++i)
+ {
+ SettingsMap::const_iterator it = d->overriddenSettings.find(keys[i]);
+ if (it != d->overriddenSettings.end())
{
- query.prepare("SELECT data FROM settings "
- "WHERE value = :KEY AND "
- "hostname IS NULL;");
- query.bindValue(":KEY", key);
-
- if (query.exec() && query.next())
- {
- found = true;
- value = query.value(0).toString();
- }
- else
- {
- value = defaultval;
- }
+ values[i] = *it;
+ done[i] = true;
+ done_cnt++;
}
}
+ }
+ d->settingsCacheLock.unlock();
+
+ if (done.size() == done_cnt || d->ignoreDatabase)
+ return true;
+
+ QString keylist("");
+ QMap<QString,int> keymap;
+ for (uint i = 0; i < (uint) keys.size(); ++i)
+ {
+ if (done[i])
+ continue;
+
+ QString key = keys[i];
+ if (!key.contains("'"))
+ {
+ keylist += QString("'%1',").arg(key);
+ keymap[key] = i;
+ }
else
+ { // don't bother optimizing this case..
+ values[i] = GetSetting(key, values[i]);
+ done[i] = true;
+ done_cnt++;
+ }
+ }
+
+ if (keylist.isEmpty())
+ return true;
+
+ keylist = keylist.left(keylist.length() - 1);
+
+ MSqlQuery query(MSqlQuery::InitCon());
+ if (!query.exec(
+ QString(
+ "SELECT value, data, hostname "
+ "FROM settings "
+ "WHERE (hostname = '%1' OR hostname IS NULL) AND "
+ " value IN (%2) "
+ "ORDER BY hostname DESC")
+ .arg(d->m_localhostname).arg(keylist)))
+ {
+ DBError("GetSettings", query);
+ return false;
+ }
+
+ while (query.next())
+ {
+ QString key = query.value(0).toString().toLower();
+ QMap<QString,int>::const_iterator it = keymap.find(key);
+ if (it != keymap.end() && !done[*it])
{
- VERBOSE(VB_IMPORTANT,
- QString("Database not open while trying to "
- "load setting: %1")
- .arg(key));
+ values[*it] = query.value(1).toString();
+ done[*it] = true;
+ done_cnt++;
}
}
- if (!found)
- return d->m_settings->GetSetting(key, defaultval);
+ if (d->useSettingsCache)
+ {
+ VERBOSE(VB_IMPORTANT, "d->useSettingsCache");
+ d->settingsCacheLock.lockForWrite();
+ QMap<QString,int>::const_iterator it = keymap.begin();
+ for (; it != keymap.end(); ++it)
+ {
+ if ((kCacheDBOnly == cb) && !done[*it])
+ {
+ VERBOSE(VB_IMPORTANT, QString("Not caching '%1'").arg(it.key()));
+ continue;
+ }
- // Do not store default values since they may not have been specified.
- if (!value.isNull() && d->useSettingsCache)
- {
- d->settingsCacheLock.lock();
- d->settingsCache[key] = value;
+ QString key = it.key(), value = values[*it];
+
+ // another thread may have inserted a value into the cache
+ // while we did not have the lock, check first then save
+ if (d->settingsCache.find(key) == d->settingsCache.end())
+ {
+ key.squeeze();
+ value.squeeze();
+ d->settingsCache[key] = value;
+ }
+ }
d->settingsCacheLock.unlock();
}
+ else
+ VERBOSE(VB_IMPORTANT, "!d->useSettingsCache");
- return value;
+ return true;
}
int MythDB::GetNumSetting(const QString &key, int defaultval)
@@ -382,74 +530,71 @@
return retval.toDouble();
}
-QString MythDB::GetSettingOnHost(const QString &key, const QString &host,
- const QString &defaultval)
+QString MythDB::GetSettingOnHost(const QString &_key, const QString &_host,
+ const QString &defaultval)
{
- bool found = false;
+ QString key = _key.toLower();
+ QString host = _host.toLower();
QString value = defaultval;
QString myKey = host + ' ' + key;
- if (d->overriddenSettings.contains(myKey))
+ d->settingsCacheLock.lockForRead();
+ if (d->useSettingsCache)
{
- value = d->overriddenSettings[myKey];
- return value;
+ SettingsMap::const_iterator it = d->settingsCache.find(myKey);
+ if (it != d->settingsCache.end())
+ {
+ value = *it;
+ d->settingsCacheLock.unlock();
+ return value;
+ }
}
-
- if ((host == d->m_localhostname) &&
- (d->overriddenSettings.contains(key)))
+ else
{
-
- value = d->overriddenSettings[key];
- return value;
- }
-
- if (d->useSettingsCache)
- {
- d->settingsCacheLock.lock();
- if (d->settingsCache.contains(myKey))
+ SettingsMap::const_iterator it = d->overriddenSettings.find(myKey);
+ if (it != d->overriddenSettings.end())
{
- value = d->settingsCache[myKey];
+ value = *it;
d->settingsCacheLock.unlock();
return value;
}
- d->settingsCacheLock.unlock();
}
+ d->settingsCacheLock.unlock();
- if (!d->ignoreDatabase)
+ if (d->ignoreDatabase)
+ return value;
+
+ MSqlQuery query(MSqlQuery::InitCon());
+ if (!query.isConnected())
{
- MSqlQuery query(MSqlQuery::InitCon());
- if (query.isConnected())
- {
- query.prepare("SELECT data FROM settings WHERE value = :VALUE "
- "AND hostname = :HOSTNAME ;");
- query.bindValue(":VALUE", key);
- query.bindValue(":HOSTNAME", host);
+ VERBOSE(VB_IMPORTANT,
+ QString("Database not open while trying to "
+ "load setting: %1").arg(key));
+ return value;
+ }
- if (query.exec() && query.isActive() && query.size() > 0)
- {
- if (query.next())
- {
- value = query.value(0).toString();
- found = true;
- }
- }
- }
- else
+ query.prepare(
+ "SELECT data "
+ "FROM settings "
+ "WHERE value = :VALUE AND hostname = :HOSTNAME");
+ query.bindValue(":VALUE", key);
+ query.bindValue(":HOSTNAME", host);
+
+ if (query.exec() && query.next())
+ {
+ value = query.value(0).toString();
+
+ if (d->useSettingsCache)
{
- VERBOSE(VB_IMPORTANT,
- QString("Database not open while trying to "
- "load setting: %1")
- .arg(key));
+ myKey.squeeze();
+ value.squeeze();
+ d->settingsCacheLock.lockForWrite();
+ if (d->settingsCache.find(myKey) == d->settingsCache.end())
+ d->settingsCache[myKey] = value;
+ d->settingsCacheLock.unlock();
}
}
- if (found && d->useSettingsCache)
- {
- d->settingsCacheLock.lock();
- d->settingsCache[host + ' ' + key] = value;
- d->settingsCacheLock.unlock();
- }
-
return value;
}
@@ -474,7 +619,7 @@
void MythDB::SetSetting(const QString &key, const QString &newValue)
{
d->m_settings->SetSetting(key, newValue);
- ClearSettingsCache(key, newValue);
+ ClearSettingsCache(key);
}
void MythDB::GetResolutionSetting(const QString &type,
@@ -550,28 +695,75 @@
* This allows defining settings for the session only, without touching the
* settings in the data base.
*/
-void MythDB::OverrideSettingForSession(const QString &key,
- const QString &value)
+void MythDB::OverrideSettingForSession(
+ const QString &key, const QString &value)
{
- d->overriddenSettings[key] = value;
+ QString mk = key.toLower(), mk2 = d->m_localhostname + ' ' + mk, mv = value;
+ mk.squeeze();
+ mk2.squeeze();
+ mv.squeeze();
+
+ d->settingsCacheLock.lockForWrite();
+ d->overriddenSettings[mk] = mv;
+ d->settingsCache[mk] = mv;
+ d->settingsCache[mk2] = mv;
+ d->settingsCacheLock.unlock();
}
-void MythDB::ClearSettingsCache(QString myKey, QString newVal)
+static void clear(
+ SettingsMap &cache, SettingsMap &overrides, const QString &myKey)
{
- d->settingsCacheLock.lock();
- if (!myKey.isEmpty() && d->settingsCache.contains(myKey))
+ // Do the actual clearing..
+ SettingsMap::iterator it = cache.find(myKey);
+ if (it != cache.end())
{
- VERBOSE(VB_DATABASE, QString("Clearing Settings Cache for '%1'.")
- .arg(myKey));
- d->settingsCache.remove(myKey);
- d->settingsCache[myKey] = newVal;
+ SettingsMap::const_iterator oit = overrides.find(myKey);
+ if (oit == overrides.end())
+ {
+ VERBOSE(VB_DATABASE,
+ QString("Clearing Settings Cache for '%1'.").arg(myKey));
+ cache.erase(it);
+ }
+ else
+ {
+ VERBOSE(VB_DATABASE,
+ QString("Clearing Cache of overridden '%1' ignored.")
+ .arg(myKey));
+ }
}
- else
+}
+
+void MythDB::ClearSettingsCache(const QString &_key)
+{
+ d->settingsCacheLock.lockForWrite();
+
+ if (_key.isEmpty())
{
VERBOSE(VB_DATABASE, "Clearing Settings Cache.");
d->settingsCache.clear();
d->settingsCache.reserve(settings_reserve);
+
+ SettingsMap::const_iterator it = d->overriddenSettings.begin();
+ for (; it != d->overriddenSettings.end(); ++it)
+ {
+ QString mk2 = d->m_localhostname + ' ' + it.key();
+ mk2.squeeze();
+
+ d->settingsCache[it.key()] = *it;
+ d->settingsCache[mk2] = *it;
+ }
}
+ else
+ {
+ QString myKey = _key.toLower();
+ clear(d->settingsCache, d->overriddenSettings, myKey);
+
+ // To be safe always clear any local[ized] version too
+ QStringList mkl = myKey.split(QChar(' '));
+ if (mkl.size() == 2)
+ clear(d->settingsCache, d->overriddenSettings, mkl[1]);
+ }
+
d->settingsCacheLock.unlock();
}
@@ -585,4 +777,3 @@
d->useSettingsCache = activate;
ClearSettingsCache();
}
-
Index: libs/libmythdb/mythdb.h
===================================================================
--- libs/libmythdb/mythdb.h (revision 22742)
+++ libs/libmythdb/mythdb.h (working copy)
@@ -13,6 +13,11 @@
class MPUBLIC MythDB
{
public:
+ typedef enum
+ {
+ kCacheDBOnly,
+ kCacheDefaults,
+ } CacheBehavior;
MDBManager *GetDBManager(void);
Settings *GetOldSettings(void);
@@ -23,7 +28,7 @@
DatabaseParams GetDatabaseParams(void);
void SetDatabaseParams(const DatabaseParams ¶ms);
- void SetLocalHostname(QString name);
+ void SetLocalHostname(const QString &name);
QString GetHostName(void);
void IgnoreDatabase(bool bIgnore);
@@ -32,7 +37,7 @@
void SetSuppressDBMessages(bool bUpgraded);
bool SuppressDBMessages(void) const;
- void ClearSettingsCache(QString myKey = "", QString newVal = "");
+ void ClearSettingsCache(const QString &key = QString());
void ActivateSettingsCache(bool activate = true);
void OverrideSettingForSession(const QString &key, const QString &newValue);
@@ -42,6 +47,9 @@
const QString &host);
QString GetSetting(const QString &key, const QString &defaultval = "");
+ bool GetSettings(const QStringList &_keys, QStringList &values,
+ CacheBehavior cb = kCacheDBOnly);
+
int GetNumSetting(const QString &key, int defaultval = 0);
double GetFloatSetting(const QString &key, double defaultval = 0.0);
void GetResolutionSetting(const QString &type, int &width, int &height,