Action Engine
Loading...
Searching...
No Matches
lru.h
1// Copyright 2025 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef ACTIONENGINE_DISTRIBUTED_LRU_H_
16#define ACTIONENGINE_DISTRIBUTED_LRU_H_
17
18#include <any>
19#include <list>
20#include <string>
21#include <string_view>
22#include <utility>
23
24#include <absl/container/flat_hash_map.h>
25#include <absl/functional/any_invocable.h>
26#include <absl/log/log.h>
27#include <absl/status/status.h>
28#include <absl/status/statusor.h>
29
30#include "actionengine/util/status_macros.h"
31
32namespace act::distributed {
33
34using EvictCallback =
35 absl::AnyInvocable<void(std::string_view key, std::any value) const>;
36
37class LruCache {
38 public:
39 explicit LruCache(size_t max_entries = 0, EvictCallback on_evicted = nullptr);
40
41 void Add(std::string_view key, std::any value);
42
43 template <typename T>
44 void Add(std::string_view key, T&& value) {
45 Add(key, std::any(std::forward<T>(value)));
46 }
47
48 std::any* absl_nullable Get(std::string_view key);
49
50 template <typename T>
51 const T* absl_nullable Get(std::string_view key) {
52 const std::any* value = Get(key);
53 auto typed_ptr = std::any_cast<const T>(value);
54 if (typed_ptr == nullptr && value != nullptr) {
55 // TODO: revise if this is the best way to handle type mismatches
56 LOG(FATAL) << "Type mismatch for key '" << key << "' in LRU cache.";
57 ABSL_ASSUME(false);
58 }
59 return typed_ptr;
60 }
61
62 void Remove(std::string_view key);
63
64 void RemoveOldest();
65
66 [[nodiscard]] size_t Size() const { return map_.size(); }
67
68 private:
69 // Maximum number of entries in the cache, 0 means no limit.
70 size_t max_entries_ = 0;
71
72 // Optional callback function that is called when an entry is evicted.
73 EvictCallback on_evicted_ = nullptr;
74
75 // Doubly linked list of key-value pairs, most recently used at the front.
76 // The list stores pairs of key and value.
77 std::list<std::pair<std::string, std::any>> list_;
78 absl::flat_hash_map<std::string,
79 std::list<std::pair<std::string, std::any>>::iterator>
80 map_;
81};
82
83} // namespace act::distributed
84
85#endif // ACTIONENGINE_DISTRIBUTED_LRU_H_