15 std::unique_lock<std::shared_mutex> locker(_lock);
21 if (timeout.
total() > 0)
24 _timestamp = (current <= _timestamp) ? _timestamp + 1 : current;
25 _entries_by_key.insert(std::make_pair(key, MemCacheEntry(std::move(value), _timestamp, timeout)));
26 _entries_by_timestamp.insert(std::make_pair(_timestamp, key));
29 _entries_by_key.emplace(std::make_pair(std::move(key), MemCacheEntry(std::move(value))));
36 std::unique_lock<std::shared_mutex> locker(_lock);
42 if (timeout.
total() > 0)
45 _timestamp = (current <= _timestamp) ? _timestamp + 1 : current;
46 _entries_by_key.insert(std::make_pair(key, MemCacheEntry(value, _timestamp, timeout)));
47 _entries_by_timestamp.insert(std::make_pair(_timestamp, key));
50 _entries_by_key.insert(std::make_pair(key, MemCacheEntry(value)));
57 std::shared_lock<std::shared_mutex> locker(_lock);
60 auto it = _entries_by_key.find(key);
61 if (it == _entries_by_key.end())
62 return std::make_pair(
false, std::string_view());
64 return std::make_pair(
true, std::string_view(it->second.value));
69 std::shared_lock<std::shared_mutex> locker(_lock);
72 auto it = _entries_by_key.find(key);
73 if (it == _entries_by_key.end())
74 return std::make_pair(
false, std::string_view());
76 timeout = it->second.timestamp + it->second.timespan;
77 return std::make_pair(
true, std::string_view(it->second.value));
82 std::unique_lock<std::shared_mutex> locker(_lock);
84 return remove_internal(key);
87 bool FileCache::remove_internal(
const std::string& key)
90 auto it = _entries_by_key.find(key);
91 if (it == _entries_by_key.end())
95 if (it->second.timestamp.total() > 0)
96 _entries_by_timestamp.erase(it->second.timestamp);
99 _entries_by_key.erase(it);
107 remove_path_internal(path);
110 if (!insert_path_internal(path, prefix, timeout, handler))
113 std::unique_lock<std::shared_mutex> locker(_lock);
116 if (timeout.
total() > 0)
119 _timestamp = (current <= _timestamp) ? _timestamp + 1 : current;
120 _paths_by_key.insert(std::make_pair(path, FileCacheEntry(prefix, handler, _timestamp, timeout)));
121 _paths_by_timestamp.insert(std::make_pair(_timestamp, path));
124 _paths_by_key.insert(std::make_pair(path, FileCacheEntry(prefix, handler)));
129 bool FileCache::insert_path_internal(
const CppCommon::Path& path,
const std::string& prefix,
const Timespan& timeout,
const InsertHandler& handler)
133 const std::string key_prefix = (prefix.empty() || (prefix ==
"/")) ?
"/" : (prefix +
"/");
144 if (!insert_path_internal(entry, key, timeout, handler))
153 std::string value(content.begin(), content.end());
154 if (!handler(*
this, key, value, timeout))
168 std::shared_lock<std::shared_mutex> locker(_lock);
171 auto it = _paths_by_key.find(path);
172 if (it == _paths_by_key.end())
180 std::shared_lock<std::shared_mutex> locker(_lock);
183 auto it = _paths_by_key.find(path);
184 if (it == _paths_by_key.end())
187 timeout = it->second.timestamp + it->second.timespan;
193 return remove_path_internal(path);
198 std::unique_lock<std::shared_mutex> locker(_lock);
201 auto it = _paths_by_key.find(path);
202 if (it == _paths_by_key.end())
206 if (it->second.timestamp.total() > 0)
207 _paths_by_timestamp.erase(it->second.timestamp);
210 _paths_by_key.erase(it);
217 std::unique_lock<std::shared_mutex> locker(_lock);
220 _entries_by_key.clear();
221 _entries_by_timestamp.clear();
222 _paths_by_key.clear();
223 _paths_by_timestamp.clear();
228 std::unique_lock<std::shared_mutex> locker(_lock);
231 auto it_entry_by_timestamp = _entries_by_timestamp.begin();
232 while (it_entry_by_timestamp != _entries_by_timestamp.end())
235 auto it_entry_by_key = _entries_by_key.find(it_entry_by_timestamp->second);
236 if ((it_entry_by_key->second.timestamp + it_entry_by_key->second.timespan) <= utc)
239 _entries_by_key.erase(it_entry_by_key);
240 _entries_by_timestamp.erase(it_entry_by_timestamp);
241 it_entry_by_timestamp = _entries_by_timestamp.begin();
249 auto it_path_by_timestamp = _paths_by_timestamp.begin();
250 while (it_path_by_timestamp != _paths_by_timestamp.end())
253 auto& it_path_by_key = _paths_by_key[it_path_by_timestamp->second];
254 if ((it_path_by_key.timestamp + it_path_by_key.timespan) <= utc)
257 auto path = it_path_by_timestamp->second;
258 auto prefix = it_path_by_key.prefix;
259 auto timespan = it_path_by_key.timespan;
260 auto handler = it_path_by_key.handler;
261 _paths_by_timestamp.erase(it_path_by_timestamp);
265 it_path_by_timestamp = _paths_by_timestamp.begin();
275 std::unique_lock<std::shared_mutex> locker1(_lock);
276 std::unique_lock<std::shared_mutex> locker2(cache._lock);
279 swap(_timestamp, cache._timestamp);
280 swap(_entries_by_key, cache._entries_by_key);
281 swap(_entries_by_timestamp, cache._entries_by_timestamp);
282 swap(_paths_by_key, cache._paths_by_key);
283 swap(_paths_by_timestamp, cache._paths_by_timestamp);
static std::string URLDecode(std::string_view str)
URL decode string.
bool insert(const std::string &key, const std::string &value, const Timespan &timeout=Timespan(0))
Insert a new cache value with the given timeout into the file cache.
void watchdog(const UtcTimestamp &utc=UtcTimestamp())
Watchdog the file cache.
std::pair< bool, std::string_view > find(const std::string &key)
Try to find the cache value by the given key.
bool remove(const std::string &key)
Remove the cache value with the given key from the file cache.
bool remove_path(const CppCommon::Path &path)
Remove the cache path from the file cache.
bool emplace(std::string &&key, std::string &&value, const Timespan &timeout=Timespan(0))
Emplace a new cache value with the given timeout into the file cache.
bool insert_path(const CppCommon::Path &path, const std::string &prefix="/", const Timespan &timeout=Timespan(0), const InsertHandler &handler=[](FileCache &cache, const std::string &key, const std::string &value, const Timespan &timeout){ return cache.insert(key, value, timeout);})
Insert a new cache path with the given timeout into the file cache.
bool find_path(const CppCommon::Path &path)
Try to find the cache path.
void swap(FileCache &cache) noexcept
Swap two instances.
void clear()
Clear the memory cache.
std::function< bool(FileCache &cache, const std::string &key, const std::string &value, const Timespan &timeout)> InsertHandler
File cache insert handler type.
std::vector< uint8_t > ReadAllBytes()
Read all bytes.
bool IsSymlink() const
Is the path points to symbolic link?
bool IsDirectory() const
Is the path points to directory?
Path target() const
Read symlink target path.
int64_t total() const noexcept
Get total value of the current timespan (total nanoseconds)
C++ Common project definitions.
void swap(FileCache &cache1, FileCache &cache2) noexcept