osquery-1/osquery/utils/caches/lru-impl.h
Alexander Kindyakov 5974649f2b Simple LRU cache implementation (#5521)
Summary:
Pull Request resolved: https://github.com/facebook/osquery/pull/5521

Implementation based on `std::unordered_map` and `std::list`, without any
age-bits or any sort of optimisations. If later we realize we need something
more powerfull we will use some fancy OSS lib for it.

I need it as a cache of "hot" processes in syscall traicing. To read cmdline
from file in `/proc/<pid>/cmdline` less often and preserve cmdline or any other
info about process for the events that came when process is already gone.

Reviewed By: SAlexandru

Differential Revision: D14424352

fbshipit-source-id: 472cf8b542bab2921393b9d2a126c254c791404a
2019-03-14 09:40:10 -07:00

51 lines
1.4 KiB
C++

/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed in accordance with the terms specified in
* the LICENSE file found in the root directory of this source tree.
*/
namespace osquery {
namespace caches {
template <typename KeyType, typename ValueType>
ValueType const* LRU<KeyType, ValueType>::insert(const KeyType& key,
ValueType value) {
auto map_iter = map_.find(key);
if (map_iter == map_.end()) {
if (size() >= capacity_) {
evict();
}
queue_.push_front(key);
auto const inserted_element_iter =
map_.emplace(key, ValueAndIterType{std::move(value), queue_.begin()})
.first;
return &inserted_element_iter->second.value;
} else {
map_iter->second.value = std::move(value);
queue_.erase(map_iter->second.iter);
queue_.push_front(key);
map_iter->second.iter = queue_.begin();
}
return &map_iter->second.value;
}
template <typename KeyType, typename ValueType>
ValueType const* LRU<KeyType, ValueType>::get(const KeyType& key) {
auto map_iter = map_.find(key);
if (map_iter == map_.end()) {
return nullptr;
}
auto queue_iter = map_iter->second.iter;
if (queue_iter != queue_.begin()) {
queue_.erase(queue_iter);
queue_.push_front(key);
map_iter->second.iter = queue_.begin();
}
return &map_iter->second.value;
}
} // namespace caches
} // namespace osquery