Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added: housekeeping code for addons/packages #323

Merged
1 commit merged into from Oct 2, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
72 changes: 72 additions & 0 deletions xbmc/addons/AddonInstaller.cpp
Expand Up @@ -21,10 +21,12 @@
#include "AddonInstaller.h" #include "AddonInstaller.h"
#include "Service.h" #include "Service.h"
#include "utils/log.h" #include "utils/log.h"
#include "utils/FileUtils.h"
#include "utils/URIUtils.h" #include "utils/URIUtils.h"
#include "Util.h" #include "Util.h"
#include "guilib/LocalizeStrings.h" #include "guilib/LocalizeStrings.h"
#include "filesystem/Directory.h" #include "filesystem/Directory.h"
#include "settings/AdvancedSettings.h"
#include "settings/GUISettings.h" #include "settings/GUISettings.h"
#include "settings/Settings.h" #include "settings/Settings.h"
#include "ApplicationMessenger.h" #include "ApplicationMessenger.h"
Expand Down Expand Up @@ -84,6 +86,7 @@ void CAddonInstaller::OnJobComplete(unsigned int jobID, bool success, CJob* job)
JobMap::iterator i = find_if(m_downloadJobs.begin(), m_downloadJobs.end(), bind2nd(find_map(), jobID)); JobMap::iterator i = find_if(m_downloadJobs.begin(), m_downloadJobs.end(), bind2nd(find_map(), jobID));
if (i != m_downloadJobs.end()) if (i != m_downloadJobs.end())
m_downloadJobs.erase(i); m_downloadJobs.erase(i);
PrunePackageCache();
} }
lock.Leave(); lock.Leave();


Expand Down Expand Up @@ -381,6 +384,75 @@ bool CAddonInstaller::HasJob(const CStdString& ID) const
return m_downloadJobs.find(ID) != m_downloadJobs.end(); return m_downloadJobs.find(ID) != m_downloadJobs.end();
} }


void CAddonInstaller::PrunePackageCache()
{
std::map<CStdString,CFileItemList*> packs;
int64_t size = EnumeratePackageFolder(packs);
if (size < g_advancedSettings.m_addonPackageFolderSize)
return;

// Prune packages
// 1. Remove the largest packages, leaving at least 2 for each add-on
CFileItemList items;
for (std::map<CStdString,CFileItemList*>::const_iterator it = packs.begin();
it != packs.end();++it)
{
it->second->Sort(SORT_METHOD_LABEL,SortOrderDescending);
for (int j=2;j<it->second->Size();++j)
items.Add(CFileItemPtr(new CFileItem(*it->second->Get(j))));
}
items.Sort(SORT_METHOD_SIZE,SortOrderDescending);
int i=0;
while (size > g_advancedSettings.m_addonPackageFolderSize && i < items.Size())
{
size -= items[i]->m_dwSize;
CFileUtils::DeleteItem(items[i++],true);
}

if (size > g_advancedSettings.m_addonPackageFolderSize)
{
// 2. Remove the oldest packages (leaving least 1 for each add-on)
items.Clear();
for (std::map<CStdString,CFileItemList*>::iterator it = packs.begin();
it != packs.end();++it)
{
if (it->second->Size() > 1)
items.Add(CFileItemPtr(new CFileItem(*it->second->Get(1))));
}
items.Sort(SORT_METHOD_DATE,SortOrderAscending);
i=0;
while (size > g_advancedSettings.m_addonPackageFolderSize && i < items.Size())
{
size -= items[i]->m_dwSize;
CFileUtils::DeleteItem(items[i++],true);
}
}
// clean up our mess
for (std::map<CStdString,CFileItemList*>::iterator it = packs.begin();
it != packs.end();++it)
delete it->second;
}

int64_t CAddonInstaller::EnumeratePackageFolder(std::map<CStdString,CFileItemList*>& result)
{
CFileItemList items;
CDirectory::GetDirectory("special://home/addons/packages/",items,".zip",DIR_FLAG_NO_FILE_DIRS);
int64_t size=0;
for (int i=0;i<items.Size();++i)
{
if (items[i]->m_bIsFolder)
continue;
size += items[i]->m_dwSize;
CStdString pack,dummy;
AddonVersion::SplitFileName(pack,dummy,items[i]->GetLabel());
if (result.find(pack) == result.end())
result[pack] = new CFileItemList;
result[pack]->Add(CFileItemPtr(new CFileItem(*items[i])));
}

return size;
}

CAddonInstallJob::CAddonInstallJob(const AddonPtr &addon, const CStdString &hash, bool update, const CStdString &referer) CAddonInstallJob::CAddonInstallJob(const AddonPtr &addon, const CStdString &hash, bool update, const CStdString &referer)
: m_addon(addon), m_hash(hash), m_update(update), m_referer(referer) : m_addon(addon), m_hash(hash), m_update(update), m_referer(referer)
{ {
Expand Down
3 changes: 3 additions & 0 deletions xbmc/addons/AddonInstaller.h
Expand Up @@ -122,6 +122,9 @@ class CAddonInstaller : public IJobCallback
*/ */
bool DoInstall(const ADDON::AddonPtr &addon, const CStdString &hash = "", bool update = false, const CStdString &referer = "", bool background = true); bool DoInstall(const ADDON::AddonPtr &addon, const CStdString &hash = "", bool update = false, const CStdString &referer = "", bool background = true);


void PrunePackageCache();
int64_t EnumeratePackageFolder(std::map<CStdString,CFileItemList*>& result);

CCriticalSection m_critSection; CCriticalSection m_critSection;
JobMap m_downloadJobs; JobMap m_downloadJobs;
CStopWatch m_repoUpdateWatch; ///< repository updates are done based on this counter CStopWatch m_repoUpdateWatch; ///< repository updates are done based on this counter
Expand Down
2 changes: 2 additions & 0 deletions xbmc/settings/AdvancedSettings.cpp
Expand Up @@ -298,6 +298,7 @@ void CAdvancedSettings::Initialize()
m_measureRefreshrate = false; m_measureRefreshrate = false;


m_cacheMemBufferSize = 1024 * 1024 * 20; m_cacheMemBufferSize = 1024 * 1024 * 20;
m_addonPackageFolderSize = 200*1024*1024;


m_jsonOutputCompact = true; m_jsonOutputCompact = true;
m_jsonTcpPort = 9090; m_jsonTcpPort = 9090;
Expand Down Expand Up @@ -759,6 +760,7 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file)
XMLUtils::GetUInt(pRootElement,"restrictcapsmask", m_RestrictCapsMask); XMLUtils::GetUInt(pRootElement,"restrictcapsmask", m_RestrictCapsMask);
XMLUtils::GetFloat(pRootElement,"sleepbeforeflip", m_sleepBeforeFlip, 0.0f, 1.0f); XMLUtils::GetFloat(pRootElement,"sleepbeforeflip", m_sleepBeforeFlip, 0.0f, 1.0f);
XMLUtils::GetBoolean(pRootElement,"virtualshares", m_bVirtualShares); XMLUtils::GetBoolean(pRootElement,"virtualshares", m_bVirtualShares);
XMLUtils::GetUInt(pRootElement, "packagefoldersize", m_addonPackageFolderSize);


//Tuxbox //Tuxbox
pElement = pRootElement->FirstChildElement("tuxbox"); pElement = pRootElement->FirstChildElement("tuxbox");
Expand Down
1 change: 1 addition & 0 deletions xbmc/settings/AdvancedSettings.h
Expand Up @@ -346,6 +346,7 @@ class CAdvancedSettings
bool m_guiVisualizeDirtyRegions; bool m_guiVisualizeDirtyRegions;
int m_guiAlgorithmDirtyRegions; int m_guiAlgorithmDirtyRegions;
int m_guiDirtyRegionNoFlipTimeout; int m_guiDirtyRegionNoFlipTimeout;
unsigned int m_addonPackageFolderSize;


unsigned int m_cacheMemBufferSize; unsigned int m_cacheMemBufferSize;


Expand Down