diff --git a/app/render/CMakeLists.txt b/app/render/CMakeLists.txt index 9b4593c6f..99225da03 100644 --- a/app/render/CMakeLists.txt +++ b/app/render/CMakeLists.txt @@ -24,6 +24,8 @@ set(OLIVE_SOURCES render/colormanager.cpp render/colorprocessor.h render/colorprocessor.cpp + render/diskmanager.h + render/diskmanager.cpp render/pixelformat.h render/pixelformat.cpp render/pixelservice.h diff --git a/app/render/diskmanager.cpp b/app/render/diskmanager.cpp new file mode 100644 index 000000000..f210bac2b --- /dev/null +++ b/app/render/diskmanager.cpp @@ -0,0 +1,121 @@ +#include "diskmanager.h" + +#include +#include +#include +#include + +#include "common/filefunctions.h" +#include "config/config.h" + +DiskManager* DiskManager::instance_ = nullptr; + +DiskManager::DiskManager() : + consumption_(0) +{ + + // Try to load any current cache index from file + QFile cache_index_file(QDir(GetMediaCacheLocation()).filePath("index")); + + if (cache_index_file.open(QFile::ReadOnly)) { + QDataStream ds(&cache_index_file); + + while (!cache_index_file.atEnd()) { + HashTime h; + + ds >> h.file_name; + ds >> h.hash; + ds >> h.access_time; + ds >> h.file_size; + + disk_data_.append(h); + } + } else { + qWarning() << "Failed to read cache index"; + } + +} + +DiskManager::~DiskManager() +{ + // Save current cache index + QFile cache_index_file(QDir(GetMediaCacheLocation()).filePath("index")); + + if (cache_index_file.open(QFile::WriteOnly)) { + QDataStream ds(&cache_index_file); + + foreach (const HashTime& h, disk_data_) { + ds << h.file_name; + ds << h.hash; + ds << h.access_time; + ds << h.file_size; + } + } else { + qWarning() << "Failed to write cache index"; + } +} + +void DiskManager::CreateInstance() +{ + instance_ = new DiskManager(); +} + +void DiskManager::DestroyInstance() +{ + delete instance_; + instance_ = nullptr; +} + +DiskManager *DiskManager::instance() +{ + return instance_; +} + +void DiskManager::Accessed(const QByteArray &hash) +{ + for (int i=disk_data_.size()-1;i>=0;i--) { + const HashTime& h = disk_data_.at(i); + + if (h.hash == hash) { + HashTime moved_hash = h; + + moved_hash.access_time = QDateTime::currentMSecsSinceEpoch(); + + disk_data_.removeAt(i); + disk_data_.append(moved_hash); + break; + } + } +} + +void DiskManager::CreatedFile(const QString &file_name, const QByteArray &hash) +{ + qint64 file_size = QFile(file_name).size(); + + disk_data_.append({file_name, hash, QDateTime::currentMSecsSinceEpoch(), }); + + consumption_ += file_size; + + while (consumption_ > DiskLimit()) { + DeleteLeastRecent(); + } +} + +void DiskManager::DeleteLeastRecent() +{ + HashTime h = disk_data_.takeFirst(); + + QFile::remove(h.file_name); + + consumption_ -= h.file_size; + + emit DeletedFrame(h.hash); +} + +qint64 DiskManager::DiskLimit() +{ + double gigabytes = Config::Current()["DiskCacheSize"].toDouble(); + + // Convert gigabytes to bytes + return qRound64(gigabytes * 1073741824); +} diff --git a/app/render/diskmanager.h b/app/render/diskmanager.h new file mode 100644 index 000000000..bc7e7f7ed --- /dev/null +++ b/app/render/diskmanager.h @@ -0,0 +1,47 @@ +#ifndef DISKMANAGER_H +#define DISKMANAGER_H + +#include + +class DiskManager : public QObject +{ + Q_OBJECT +public: + static void CreateInstance(); + + static void DestroyInstance(); + + static DiskManager* instance(); + + void Accessed(const QByteArray& hash); + + void CreatedFile(const QString& file_name, const QByteArray& hash); + +signals: + void DeletedFrame(const QByteArray& hash); + +private: + DiskManager(); + + virtual ~DiskManager() override; + + static DiskManager* instance_; + + void DeleteLeastRecent(); + + qint64 DiskLimit(); + + struct HashTime { + QString file_name; + QByteArray hash; + qint64 access_time; + qint64 file_size; + }; + + QList disk_data_; + + qint64 consumption_; + +}; + +#endif // DISKMANAGER_H