/*** Olive - Non-Linear Video Editor Copyright (C) 2019 Olive Team This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ***/ #include "diskmanager.h" #include #include #include #include #include #include #include "common/filefunctions.h" #include "config/config.h" OLIVE_NAMESPACE_ENTER DiskManager* DiskManager::instance_ = nullptr; DiskManager::DiskManager() : consumption_(0) { // Try to load any current cache index from file QFile cache_index_file(GetCacheIndexFilename()); 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; if (QFileInfo::exists(h.file_name)) { consumption_ += h.file_size; disk_data_.append(h); } } } } DiskManager::~DiskManager() { if (Config::Current()["ClearDiskCacheOnClose"].toBool()) { // Clear all cache data ClearDiskCache(true); } else { // Save current cache index QFile cache_index_file(GetCacheIndexFilename()); 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:" << GetCacheIndexFilename(); } } } void DiskManager::CreateInstance() { instance_ = new DiskManager(); } void DiskManager::DestroyInstance() { delete instance_; instance_ = nullptr; } DiskManager *DiskManager::instance() { return instance_; } void DiskManager::Accessed(const QByteArray &hash) { lock_.lock(); 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; } } lock_.unlock(); } void DiskManager::Accessed(const QString &filename) { lock_.lock(); for (int i=disk_data_.size()-1;i>=0;i--) { const HashTime& h = disk_data_.at(i); if (h.file_name == filename) { HashTime moved_hash = h; moved_hash.access_time = QDateTime::currentMSecsSinceEpoch(); disk_data_.removeAt(i); disk_data_.append(moved_hash); break; } } lock_.unlock(); } void DiskManager::CreatedFile(const QString &file_name, const QByteArray &hash) { lock_.lock(); qint64 file_size = QFile(file_name).size(); disk_data_.append({file_name, hash, QDateTime::currentMSecsSinceEpoch(), file_size}); consumption_ += file_size; QList deleted_hashes; while (consumption_ > DiskLimit()) { deleted_hashes.append(DeleteLeastRecent()); } lock_.unlock(); foreach (const QByteArray& h, deleted_hashes) { emit DeletedFrame(h); } } bool DiskManager::ClearDiskCache(bool quick_delete) { bool deleted_files; lock_.lock(); if (quick_delete) { deleted_files = QDir(GetMediaCacheLocation()).removeRecursively(); disk_data_.clear(); } else { deleted_files = true; for (int i=0;i