12 #include <QDirIterator>
13 #include <QtConcurrentRun>
23 NetworkDiskCacheGC::NetworkDiskCacheGC ()
25 const auto timer =
new QTimer {
this };
29 &NetworkDiskCacheGC::HandleCollect);
30 timer->start (60 * 60 * 1000);
35 static NetworkDiskCacheGC gc;
41 struct SizeCollectInfo
43 QMultiMap<QDateTime, QString>
Items_;
47 SizeCollectInfo CollectSizes (
const QString& cacheDirectory)
49 SizeCollectInfo result;
51 const QDir::Filters filters = QDir::AllDirs | QDir:: Files | QDir::NoDotAndDotDot;
52 QDirIterator it { cacheDirectory, filters, QDirIterator::Subdirectories };
56 const auto& path = it.next ();
57 const auto& info = it.fileInfo ();
58 result.Items_.insert (info.birthTime (), path);
59 result.TotalSize_ += info.size ();
68 return QtConcurrent::run ([path] {
return CollectSizes (path).TotalSize_; });
72 const std::function<
int ()>& sizeGetter)
74 auto& list = Directories_ [path];
75 list.push_front (sizeGetter);
76 const auto thisItem = list.begin ();
78 return Util::MakeScopeGuard ([
this, path, thisItem] { UnregisterDirectory (path, thisItem); }).EraseType ();
81 void NetworkDiskCacheGC::UnregisterDirectory (
const QString& path, CacheSizeGetters_t::iterator pos)
83 if (!Directories_.contains (path))
85 qWarning () << Q_FUNC_INFO
86 <<
"unknown directory"
91 auto& list = Directories_ [path];
97 Directories_.remove (path);
98 LastSizes_.remove (path);
103 qint64 Collector (
const QString& cacheDirectory, qint64 goal)
105 if (cacheDirectory.isEmpty ())
108 qDebug () << Q_FUNC_INFO <<
"running..." << cacheDirectory << goal;
110 auto sizeInfoResult = CollectSizes (cacheDirectory);
112 for (
auto i = sizeInfoResult.Items_.constBegin ();
113 i != sizeInfoResult.Items_.constEnd () && sizeInfoResult.TotalSize_ > goal;
117 sizeInfoResult.TotalSize_ -= file.size ();
121 qDebug () <<
"collector finished" << sizeInfoResult.TotalSize_;
123 return sizeInfoResult.TotalSize_;
127 void NetworkDiskCacheGC::HandleCollect ()
131 qWarning () << Q_FUNC_INFO
132 <<
"already collecting";
139 const auto& getters = pair.second;
140 const auto minSize = (*std::min_element (getters.begin (), getters.end (),
142 dirs.append ({ pair.first, minSize });
148 IsCollecting_ =
true;
150 Util::Sequence (
this,
151 QtConcurrent::run ([dirs]
154 for (
const auto& pair : dirs)
155 sizes [pair.first] = Collector (pair.first, pair.second);
160 IsCollecting_ =
false;
162 LastSizes_ [pair.first] = pair.second;