| 155 | } |
| 156 | |
| 157 | void CleanCache(agi::fs::path const& directory, std::string const& file_type, uint64_t max_size, uint64_t max_files) { |
| 158 | static std::unique_ptr<agi::dispatch::Queue> queue; |
| 159 | if (!queue) |
| 160 | queue = agi::dispatch::Create(); |
| 161 | |
| 162 | max_size <<= 20; |
| 163 | if (max_files == 0) |
| 164 | max_files = std::numeric_limits<uint64_t>::max(); |
| 165 | queue->Async([=]{ |
| 166 | LOG_D("utils/clean_cache") << "cleaning " << directory/file_type; |
| 167 | uint64_t total_size = 0; |
| 168 | using cache_item = std::pair<std::filesystem::file_time_type, agi::fs::path>; |
| 169 | std::vector<cache_item> cachefiles; |
| 170 | for (auto const& file : agi::fs::DirectoryIterator(directory, file_type)) { |
| 171 | agi::fs::path path = directory/file; |
| 172 | cachefiles.push_back({agi::fs::ModifiedTime(path), path}); |
| 173 | total_size += agi::fs::Size(path); |
| 174 | } |
| 175 | |
| 176 | if (cachefiles.size() <= max_files && total_size <= max_size) { |
| 177 | LOG_D("utils/clean_cache") << agi::format("cache does not need cleaning (maxsize=%d, cursize=%d, maxfiles=%d, numfiles=%d), exiting" |
| 178 | , max_size, total_size, max_files, cachefiles.size()); |
| 179 | return; |
| 180 | } |
| 181 | |
| 182 | sort(begin(cachefiles), end(cachefiles), [](cache_item const& a, cache_item const& b) { |
| 183 | return a.first < b.first; |
| 184 | }); |
| 185 | |
| 186 | int deleted = 0; |
| 187 | for (auto const& i : cachefiles) { |
| 188 | // stop cleaning? |
| 189 | if ((total_size <= max_size && cachefiles.size() - deleted <= max_files) || cachefiles.size() - deleted < 2) |
| 190 | break; |
| 191 | |
| 192 | uint64_t size = agi::fs::Size(i.second); |
| 193 | try { |
| 194 | agi::fs::Remove(i.second); |
| 195 | LOG_D("utils/clean_cache") << "deleted " << i.second; |
| 196 | } |
| 197 | catch (agi::Exception const& e) { |
| 198 | LOG_D("utils/clean_cache") << "failed to delete file " << i.second << ": " << e.GetMessage(); |
| 199 | continue; |
| 200 | } |
| 201 | |
| 202 | total_size -= size; |
| 203 | ++deleted; |
| 204 | } |
| 205 | |
| 206 | LOG_D("utils/clean_cache") << "deleted " << deleted << " files, exiting"; |
| 207 | }); |
| 208 | } |
| 209 | |
| 210 | #ifndef __WXOSX_COCOA__ |
| 211 | // OS X implementation in osx_utils.mm |