LeechCraft 0.6.70-14794-g33744ae6ce
Modular cross-platform feature rich live environment.
Loading...
Searching...
No Matches
networkdiskcachegc.cpp
Go to the documentation of this file.
1/**********************************************************************
2 * LeechCraft - modular cross-platform feature rich internet client.
3 * Copyright (C) 2006-2014 Georg Rudoy
4 *
5 * Distributed under the Boost Software License, Version 1.0.
6 * (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7 **********************************************************************/
8
10#include <QTimer>
11#include <QDir>
12#include <QDirIterator>
13#include <QtConcurrentRun>
14#include <QDateTime>
15#include <QtDebug>
16#include <util/sll/qtutil.h>
17#include <util/sll/prelude.h>
18#include <util/sll/util.h>
20
21namespace LC::Util
22{
23 NetworkDiskCacheGC::NetworkDiskCacheGC ()
24 {
25 const auto timer = new QTimer { this };
26 connect (timer,
27 &QTimer::timeout,
28 this,
29 &NetworkDiskCacheGC::HandleCollect);
30 timer->start (60 * 60 * 1000);
31 }
32
34 {
35 static NetworkDiskCacheGC gc;
36 return gc;
37 }
38
39 namespace
40 {
41 struct SizeCollectInfo
42 {
43 QMultiMap<QDateTime, QString> Items_;
44 qint64 TotalSize_ = 0;
45 };
46
47 SizeCollectInfo CollectSizes (const QString& cacheDirectory)
48 {
49 SizeCollectInfo result;
50
51 const QDir::Filters filters = QDir::AllDirs | QDir:: Files | QDir::NoDotAndDotDot;
52 QDirIterator it { cacheDirectory, filters, QDirIterator::Subdirectories };
53
54 while (it.hasNext ())
55 {
56 const auto& path = it.next ();
57 const auto& info = it.fileInfo ();
58 result.Items_.insert (info.birthTime (), path);
59 result.TotalSize_ += info.size ();
60 }
61
62 return result;
63 }
64 }
65
67 {
68 return QtConcurrent::run ([path] { return CollectSizes (path).TotalSize_; });
69 }
70
72 const std::function<int ()>& sizeGetter)
73 {
74 auto& list = Directories_ [path];
75 list.push_front (sizeGetter);
76 const auto thisItem = list.begin ();
77
78 return Util::MakeScopeGuard ([this, path, thisItem] { UnregisterDirectory (path, thisItem); }).EraseType ();
79 }
80
81 void NetworkDiskCacheGC::UnregisterDirectory (const QString& path, CacheSizeGetters_t::iterator pos)
82 {
83 if (!Directories_.contains (path))
84 {
85 qWarning () << Q_FUNC_INFO
86 << "unknown directory"
87 << path;
88 return;
89 }
90
91 auto& list = Directories_ [path];
92 list.erase (pos);
93
94 if (!list.isEmpty ())
95 return;
96
97 Directories_.remove (path);
98 LastSizes_.remove (path);
99 }
100
101 namespace
102 {
103 qint64 Collector (const QString& cacheDirectory, qint64 goal)
104 {
105 if (cacheDirectory.isEmpty ())
106 return 0;
107
108 qDebug () << Q_FUNC_INFO << "running..." << cacheDirectory << goal;
109
110 auto sizeInfoResult = CollectSizes (cacheDirectory);
111
112 for (auto i = sizeInfoResult.Items_.constBegin ();
113 i != sizeInfoResult.Items_.constEnd () && sizeInfoResult.TotalSize_ > goal;
114 ++i)
115 {
116 QFile file { *i };
117 sizeInfoResult.TotalSize_ -= file.size ();
118 file.remove ();
119 }
120
121 qDebug () << "collector finished" << sizeInfoResult.TotalSize_;
122
123 return sizeInfoResult.TotalSize_;
124 }
125 };
126
127 void NetworkDiskCacheGC::HandleCollect ()
128 {
129 if (IsCollecting_)
130 {
131 qWarning () << Q_FUNC_INFO
132 << "already collecting";
133 return;
134 }
135
137 for (const auto& pair : Util::Stlize (Directories_))
138 {
139 const auto& getters = pair.second;
140 const auto minSize = (*std::min_element (getters.begin (), getters.end (),
142 dirs.append ({ pair.first, minSize });
143 }
144
145 if (dirs.isEmpty ())
146 return;
147
148 IsCollecting_ = true;
149
150 Util::Sequence (this,
151 QtConcurrent::run ([dirs]
152 {
154 for (const auto& pair : dirs)
155 sizes [pair.first] = Collector (pair.first, pair.second);
156 return sizes;
157 })) >>
158 [this] (const QMap<QString, qint64>& sizes)
159 {
160 IsCollecting_ = false;
161 for (const auto& pair : Util::Stlize (sizes))
162 LastSizes_ [pair.first] = pair.second;
163 };
164 }
165}
Garbage collection for a set of network disk caches.
Util::DefaultScopeGuard RegisterDirectory(const QString &path, const std::function< int()> &sizeGetter)
Registers the given cache path.
static NetworkDiskCacheGC & Instance()
Returns a single global instance of the GC manager.
QFuture< qint64 > GetCurrentSize(const QString &path) const
Schedules calculation of the path total size.
Definition: anutil.h:17
detail::ScopeGuard< F > MakeScopeGuard(const F &f)
Returns an object performing passed function on scope exit.
Definition: util.h:136
auto Stlize(Assoc &&assoc)
Converts an Qt's associative sequence assoc to an STL-like iteratable range.
Definition: qtutil.h:43
auto ComparingBy(R r)
Definition: prelude.h:221
constexpr auto Apply
Definition: prelude.h:232
qint64 TotalSize_
QMultiMap< QDateTime, QString > Items_