Commit f24ba596 authored by Lukas Appelhans's avatar Lukas Appelhans

Refactor cache class to use d pointer and rename it

parent 8dc93f55
......@@ -20,7 +20,6 @@
*/
namespace Akabei
{
/**
* @class CachePair
* @brief Class for data pairs with a date and a file path.
......@@ -56,53 +55,77 @@ private:
QString m_value;
};
class Cache::Private
{
public:
Private(const QDir &cd) : cachedir(cd), cacheFiles(cd.entryList()) {}
Private(const QDir &cd, const QStringList &kp) : cachedir(cd), cacheFiles(cd.entryList()), keepPackages(kp) {}
~Private() {}
void init();
bool cleanOld();
bool cleanUnused();
bool cleanAll();
QString getPackageName(const QString &);
QString getPackageVersion(const QString &);
qint64 totalCacheSize();
bool cleanConditional(bool);
QDir cachedir;
QStringList cacheFiles;
QStringList plainEntryList;
QStringList keepPackages;
QDateTime weeks2older;
QString error;
};
/*
* This costructor is meant to be used by all the classes that needs to write/get a file from the cache.
* All the options are read from the configuration file later.
*/
AkabeiCache::AkabeiCache()
: m_cachedir(Config::instance()->cacheDir())
, m_plainEntryList(m_cachedir.entryList())
Cache::Cache()
: d(new Private(Config::instance()->cacheDir()))
{
init();
m_keepPackages.append(Config::instance()->keepPackages());
d->init();
d->keepPackages.append(Config::instance()->keepPackages());
}
/*
* This constructor is meant to be used by the akabei-clean-cache tool, where the options
* can be specified from the command line.
*/
AkabeiCache::AkabeiCache(QString cachedir, QStringList& keepPackages, QHash< QString, bool >& operations)
: m_cachedir(cachedir)
, m_plainEntryList(m_cachedir.entryList())
, m_keepPackages(keepPackages)
Cache::Cache(const QString &cachedir, const QStringList &keepPackages, const QHash< QString, bool > &operations)
: d(new Private(cachedir, keepPackages))
{
init();
d->init();
/*
* Decides the operation to execute
* (more than one can be executed in this same invocation, except for CleanAll of course)
*/
if (operations["clean-all"]) {
cleanAll();
d->cleanAll();
} else {
if (operations["clean-old"]) {
cleanOld();
d->cleanOld();
}
if (operations["clean-unused"]) {
cleanUnused();
d->cleanUnused();
}
}
}
void AkabeiCache::init()
void Cache::Private::init()
{
/*
* Create a new list of cache entries with their full path.
*/
foreach (QString const& cacheFile, m_plainEntryList) {
foreach (QString const& cacheFile, plainEntryList) {
if (!cacheFile.startsWith(".")) {
m_cacheFiles.append(m_cachedir.absoluteFilePath(cacheFile));
cacheFiles.append(cachedir.absoluteFilePath(cacheFile));
}
}
......@@ -113,19 +136,19 @@ void AkabeiCache::init()
* quite recent files to be removed.
*/
QDateTime current = QDateTime::currentDateTime();
m_weeks2older = current.addDays(-14);
weeks2older = current.addDays(-14);
}
bool AkabeiCache::isPackageInCache(QString filename)
bool Cache::isPackageInCache(const QString &filename) const
{
return m_plainEntryList.contains(filename);
return d->plainEntryList.contains(filename);
}
/*
* Get the path associated with the filename requested,
* or an empty string if the filename isn't in the cache.
*/
QString AkabeiCache::getPathInCache(QString filename)
QString Cache::getPathInCache(const QString &filename) const
{
//FIXME: Fix maybe? This should return the path also if file does not exist... why the manual read hack?
//if (m_plainEntryList.contains(filename)) {
......@@ -144,15 +167,15 @@ QString AkabeiCache::getPathInCache(QString filename)
}
return QString();*/
return m_cachedir.absoluteFilePath(filename);
return d->cachedir.absoluteFilePath(filename);
}
QStringList AkabeiCache::getPackagesByName(QString pkg)
QStringList Cache::getPackagesByName(const QString &pkg) const
{
QStringList matches;
foreach (QString const& file, m_plainEntryList) {
if (getPackageName(file) == pkg) {
foreach (QString const& file, d->plainEntryList) {
if (d->getPackageName(file) == pkg) {
matches.append(file);
}
}
......@@ -164,38 +187,38 @@ QStringList AkabeiCache::getPackagesByName(QString pkg)
* Writes a new file on cache
* checking if the maximum size has been reached and acting appropriately if so.
*/
bool AkabeiCache::writePackage(QString path, QString newName)
bool Cache::writePackage(const QString &path, const QString &newName)
{
if (!QFile::copy(path, m_cachedir.absoluteFilePath(newName))) {
m_error = "Could not copy \"" + path + "\" to cache.\n";
if (!QFile::copy(path, d->cachedir.absoluteFilePath(newName))) {
d->error = "Could not copy \"" + path + "\" to cache.\n";
return false;
}
/* Convert max size in bytes */
qint64 maxsize = (Config::instance()->maxCacheSize()) * 1024 * 1024;
if (maxsize > 0 && totalCacheSize() >= maxsize) {
if (maxsize > 0 && d->totalCacheSize() >= maxsize) {
/* No policy specified in config */
if (Config::instance()->cachePolicies().isEmpty()) {
return cleanAll();
return d->cleanAll();
}
foreach (CacheMaxSizePolicy policy, Config::instance()->cachePolicies()) {
switch (policy) {
case CleanAll:
return cleanAll(); /* no need to go on after this... */
case CleanOld:
if (!cleanOld()) {
return false;
}
break;
case CleanUnused:
if (!cleanUnused()) {
return false;
}
break;
case CleanAll:
return d->cleanAll(); /* no need to go on after this... */
case CleanOld:
if (!d->cleanOld()) {
return false;
}
break;
case CleanUnused:
if (!d->cleanUnused()) {
return false;
}
break;
}
}
}
......@@ -203,12 +226,12 @@ bool AkabeiCache::writePackage(QString path, QString newName)
return true;
}
bool AkabeiCache::cleanOld()
bool Cache::Private::cleanOld()
{
return cleanConditional(true);
}
bool AkabeiCache::cleanUnused()
bool Cache::Private::cleanUnused()
{
return cleanConditional(false);
}
......@@ -218,12 +241,12 @@ bool AkabeiCache::cleanUnused()
* Right now, it just says if the creation date (for CleanOld) or the last read date (for CleanUnused)
* is to be considered as a key to the comparison.
*/
bool AkabeiCache::cleanConditional(bool creationDate)
bool Cache::Private::cleanConditional(bool creationDate)
{
int newCacheSize( m_cacheFiles.size() / 2 ); /* each steps halves the cache size */
int newCacheSize( cacheFiles.size() / 2 ); /* each steps halves the cache size */
QList<CachePair> timedFiles;
foreach (QString const& file, m_cacheFiles) {
foreach (QString const& file, cacheFiles) {
QFileInfo fileInfo(file);
CachePair pair((creationDate) ? fileInfo.created() : fileInfo.lastRead(), file);
timedFiles.append(pair);
......@@ -235,13 +258,13 @@ bool AkabeiCache::cleanConditional(bool creationDate)
* Takes only the oldest/least accessed half from the list
*/
foreach (CachePair const& pair, timedFiles.mid(0, newCacheSize)) {
if (pair.key() >= m_weeks2older || m_keepPackages.contains(m_cachedir.relativeFilePath(pair.value()))) {
if (pair.key() >= weeks2older || keepPackages.contains(cachedir.relativeFilePath(pair.value()))) {
continue;
}
QFile file(pair.value());
if (!file.remove()) {
m_error = file.errorString();
error = file.errorString();
return false;
}
}
......@@ -249,18 +272,18 @@ bool AkabeiCache::cleanConditional(bool creationDate)
return true;
}
bool AkabeiCache::cleanAll()
bool Cache::Private::cleanAll()
{
foreach (QString const& file, m_plainEntryList) {
foreach (QString const& file, plainEntryList) {
QString packageName = getPackageName(file);
if (file.startsWith(".") || m_keepPackages.contains(packageName)) {
if (file.startsWith(".") || keepPackages.contains(packageName)) {
continue;
}
QFile f(m_cachedir.absoluteFilePath(file));
QFile f(cachedir.absoluteFilePath(file));
if (!f.remove()) {
m_error = f.errorString();
error = f.errorString();
return false;
}
}
......@@ -272,7 +295,7 @@ bool AkabeiCache::cleanAll()
* The following two functions separate the filename of a package, in the form
* package-version, into name and version.
*/
QString AkabeiCache::getPackageName(const QString& filename)
QString Cache::Private::getPackageName(const QString& filename)
{
QString pkgname;
......@@ -289,7 +312,7 @@ QString AkabeiCache::getPackageName(const QString& filename)
return pkgname;
}
QString AkabeiCache::getPackageVersion(const QString& filename)
QString Cache::Private::getPackageVersion(const QString& filename)
{
QString pkgver;
......@@ -306,20 +329,20 @@ QString AkabeiCache::getPackageVersion(const QString& filename)
return pkgver;
}
qint64 AkabeiCache::totalCacheSize()
qint64 Cache::Private::totalCacheSize()
{
qint64 total( 0 );
foreach (QString const& filename, m_cacheFiles) {
foreach (QString const& filename, cacheFiles) {
total += QFile( filename ).size();
}
return total;
}
QString AkabeiCache::errorString()
QString Cache::errorString() const
{
return m_error;
return d->error;
}
}
......@@ -9,7 +9,6 @@
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
*/
//FIXME: Pass by reference please! and use a d-pointer!!!
#ifndef AKABEICACHE_H
#define AKABEICACHE_H
......@@ -31,7 +30,7 @@ enum CacheMaxSizePolicy
CleanAll, CleanOld, CleanUnused
};
class AkabeiCache
class Cache
{
public:
......@@ -42,12 +41,12 @@ public:
* @param keepPackages A list of packages the cache must always maintain.
* @param operations A list of operations to perform.
*/
AkabeiCache(QString cachedir, QStringList & keepPackages, QHash<QString, bool> & operations);
Cache(const QString &cachedir, const QStringList &keepPackages, const QHash<QString, bool> &operations);
/**
* Constructs a cache manager.
*/
AkabeiCache();
Cache();
/**
* Checks whether a file is in the cache.
......@@ -55,7 +54,7 @@ public:
* @param filename filename.
* @returns true if file is present, false otherwise.
*/
bool isPackageInCache(QString filename);
bool isPackageInCache(const QString &filename) const;
/**
* Find a file in the cache.
......@@ -63,7 +62,7 @@ public:
* @param filename filename.
* @returns the file path, or an empty string if the file isn't found.
*/
QString getPathInCache(QString filename);
QString getPathInCache(const QString &filename) const;
/**
* Find a list of files in cache. Useful when you don't care about the version.
......@@ -71,7 +70,7 @@ public:
* @param pkg the name of the package to find.
* @returns a list of files with that package name.
*/
QStringList getPackagesByName(QString pkg);
QStringList getPackagesByName(const QString &pkg) const;
/**
* Copy a new file in cache.
......@@ -80,34 +79,18 @@ public:
* @param newName the new filename in cache.
* @returns true if successful, false otherwise.
*/
bool writePackage(QString path, QString newName);
bool writePackage(const QString &path, const QString &newName);
/**
* Error message.
*
* @returns a description if some error occurred, an empty string otherwise.
*/
QString errorString();
QString errorString() const;
private:
QDir m_cachedir;
QStringList m_cacheFiles;
QStringList m_plainEntryList;
QStringList m_keepPackages;
QDateTime m_weeks2older;
QString m_error;
void init();
bool cleanOld();
bool cleanUnused();
bool cleanAll();
QString getPackageName(const QString &);
QString getPackageVersion(const QString &);
qint64 totalCacheSize();
bool cleanConditional(bool);
class Private;
Private *d;
};
}
......
......@@ -28,7 +28,7 @@ namespace Akabei {
void PackagePrivate::attemptLoadFromCache()
{
AkabeiCache cache;
Cache cache;
akabeiDebug() << "I look for" << filename << "in cache";
if (cache.isPackageInCache(filename)) {
......
......@@ -162,7 +162,7 @@ void PlainInstallOperation::run()
if (!(processingOptions().testFlag(Akabei::DatabaseOnly))) {
// Add the archive to the cache.
// Simply copy it over to our cachedir.
AkabeiCache cache;
Cache cache;
cache.writePackage(p->pathToArchive(), p->filename());
QFile::copy(p->pathToArchive(), Config::instance()->cacheDir().absoluteFilePath(p->filename()));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment