33 #include <QDirIterator> 34 #include <QtConcurrentRun> 46 NetworkDiskCacheGC::NetworkDiskCacheGC ()
48 const auto timer =
new QTimer {
this };
52 SLOT (handleCollect ()));
53 timer->start (60 * 60 * 1000);
64 struct SizeCollectInfo
66 QMultiMap<QDateTime, QString>
Items_;
70 SizeCollectInfo CollectSizes (
const QString& cacheDirectory)
72 SizeCollectInfo result;
74 const QDir::Filters filters = QDir::AllDirs | QDir:: Files | QDir::NoDotAndDotDot;
75 QDirIterator it { cacheDirectory, filters, QDirIterator::Subdirectories };
79 const auto& path = it.next ();
80 const auto& info = it.fileInfo ();
81 result.Items_.insert (info.created (), path);
82 result.TotalSize_ += info.size ();
91 return QtConcurrent::run ([path] {
return CollectSizes (path).TotalSize_; });
95 const std::function<
int ()>& sizeGetter)
97 auto& list = Directories_ [path];
98 list.push_front (sizeGetter);
99 const auto thisItem = list.begin ();
101 return Util::MakeScopeGuard ([
this, path, thisItem] { UnregisterDirectory (path, thisItem); }).EraseType ();
104 void NetworkDiskCacheGC::UnregisterDirectory (
const QString& path, CacheSizeGetters_t::iterator
pos)
106 if (!Directories_.contains (path))
108 qWarning () << Q_FUNC_INFO
109 <<
"unknown directory" 114 auto& list = Directories_ [path];
117 if (!list.isEmpty ())
120 Directories_.remove (path);
121 LastSizes_.remove (path);
126 qint64 Collector (
const QString& cacheDirectory, qint64 goal)
128 if (cacheDirectory.isEmpty ())
131 qDebug () << Q_FUNC_INFO <<
"running..." << cacheDirectory << goal;
133 auto sizeInfoResult = CollectSizes (cacheDirectory);
135 for (
auto i = sizeInfoResult.Items_.constBegin ();
136 i != sizeInfoResult.Items_.constEnd () && sizeInfoResult.TotalSize_ > goal;
140 sizeInfoResult.TotalSize_ -= file.size ();
144 qDebug () <<
"collector finished" << sizeInfoResult.TotalSize_;
146 return sizeInfoResult.TotalSize_;
150 void NetworkDiskCacheGC::handleCollect ()
154 qWarning () << Q_FUNC_INFO
155 <<
"already collecting";
162 const auto& getters = pair.second;
163 const auto minSize = (*std::min_element (getters.begin (), getters.end (),
165 dirs.append ({ pair.first, minSize });
171 IsCollecting_ =
true;
173 Util::Sequence (
this,
174 QtConcurrent::run ([dirs]
177 for (
const auto& pair : dirs)
178 sizes [pair.first] = Collector (pair.first, pair.second);
183 IsCollecting_ =
false;
185 LastSizes_ [pair.first] = pair.second;
auto Stlize(Assoc &&assoc) -> detail::StlAssocRange< detail::Identity, detail::Identity, decltype(assoc.begin()), Assoc, PairType >
Converts an Qt's associative sequence assoc to an STL-like iteratable range.
QMultiMap< QDateTime, QString > Items_
detail::ExprTree< detail::ExprType::LeafStaticPlaceholder, boost::mpl::int_< Idx > > pos
detail::ScopeGuard< F > MakeScopeGuard(const F &f)
Returns an object performing passed function on scope exit.
Garbage collection for a set of network disk caches.
static NetworkDiskCacheGC & Instance()
Returns a single global instance of the GC manager.
Util::DefaultScopeGuard RegisterDirectory(const QString &path, const std::function< int()> &sizeGetter)
Registers the given cache path.
QFuture< qint64 > GetCurrentSize(const QString &path) const
Schedules calculation of the path total size.