33 #include <QDirIterator>
34 #include <QtConcurrentRun>
47 NetworkDiskCacheGC::NetworkDiskCacheGC ()
49 const auto timer =
new QTimer {
this };
53 SLOT (handleCollect ()));
54 timer->start (60 * 60 * 1000);
59 static NetworkDiskCacheGC gc;
65 struct SizeCollectInfo
67 QMultiMap<QDateTime, QString>
Items_;
71 SizeCollectInfo CollectSizes (
const QString& cacheDirectory)
73 SizeCollectInfo result;
75 const QDir::Filters filters = QDir::AllDirs | QDir:: Files | QDir::NoDotAndDotDot;
76 QDirIterator it { cacheDirectory, filters, QDirIterator::Subdirectories };
80 const auto& path = it.next ();
81 const auto& info = it.fileInfo ();
83 result.TotalSize_ += info.size ();
92 return QtConcurrent::run ([path] {
return CollectSizes (path).TotalSize_; });
96 const std::function<
int ()>& sizeGetter)
98 auto& list = Directories_ [path];
99 list.push_front (sizeGetter);
100 const auto thisItem = list.begin ();
102 return Util::MakeScopeGuard ([
this, path, thisItem] { UnregisterDirectory (path, thisItem); }).EraseType ();
105 void NetworkDiskCacheGC::UnregisterDirectory (
const QString& path, CacheSizeGetters_t::iterator pos)
107 if (!Directories_.contains (path))
109 qWarning () << Q_FUNC_INFO
110 <<
"unknown directory"
115 auto& list = Directories_ [path];
118 if (!list.isEmpty ())
121 Directories_.remove (path);
122 LastSizes_.remove (path);
127 qint64 Collector (
const QString& cacheDirectory, qint64 goal)
129 if (cacheDirectory.isEmpty ())
132 qDebug () << Q_FUNC_INFO <<
"running..." << cacheDirectory << goal;
134 auto sizeInfoResult = CollectSizes (cacheDirectory);
136 for (
auto i = sizeInfoResult.Items_.constBegin ();
137 i != sizeInfoResult.Items_.constEnd () && sizeInfoResult.TotalSize_ > goal;
141 sizeInfoResult.TotalSize_ -= file.size ();
145 qDebug () <<
"collector finished" << sizeInfoResult.TotalSize_;
147 return sizeInfoResult.TotalSize_;
151 void NetworkDiskCacheGC::handleCollect ()
155 qWarning () << Q_FUNC_INFO
156 <<
"already collecting";
163 const auto& getters = pair.second;
164 const auto minSize = (*std::min_element (getters.begin (), getters.end (),
166 dirs.append ({ pair.first, minSize });
172 IsCollecting_ =
true;
174 Util::Sequence (
this,
175 QtConcurrent::run ([dirs]
178 for (
const auto& pair : dirs)
179 sizes [pair.first] = Collector (pair.first, pair.second);
184 IsCollecting_ =
false;
186 LastSizes_ [pair.first] = pair.second;