Action Engine
Loading...
Searching...
No Matches
groupcache.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_GROUPCACHE_H_
16#define ACTIONENGINE_DISTRIBUTED_GROUPCACHE_H_
17
18#include <atomic>
19
20#include <absl/base/nullability.h>
21#include <absl/functional/any_invocable.h>
22#include <absl/random/random.h>
23
25#include "actionengine/distributed/lru.h"
26#include "actionengine/distributed/peers.h"
27#include "actionengine/distributed/singleflight.h"
28#include "actionengine/distributed/sinks.h"
29
30namespace act::distributed {
31
32using Getter = absl::AnyInvocable<absl::Status(std::string_view key,
33 Sink* absl_nonnull sink)>;
34
35struct Stats {
36 std::atomic<uint64_t> gets{0};
37 std::atomic<uint64_t> cache_hits{0};
38 std::atomic<uint64_t> peer_loads{0};
39 std::atomic<uint64_t> peer_errors{0};
40 std::atomic<uint64_t> loads{0};
41 std::atomic<uint64_t> loads_deduped{0};
42 std::atomic<uint64_t> local_loads{0};
43 std::atomic<uint64_t> local_load_errors{0};
44 std::atomic<uint64_t> server_requests{0};
45};
46
47struct CacheStats {
48 uint64_t bytes;
49 uint64_t items;
50 uint64_t gets;
51 uint64_t hits;
52 uint64_t evictions;
53};
54
55class Cache {
56 public:
57 explicit Cache(size_t max_entries = 0);
58
59 void Add(std::string_view key, std::string_view value);
60
61 const std::string* absl_nullable Get(std::string_view key);
62
63 void Remove(std::string_view key);
64
65 void RemoveOldest();
66
67 CacheStats Stats() const {
68 act::MutexLock l(&mu_);
69 return CacheStats{bytes_, lru_.Size(), gets_, hits_, evictions_};
70 }
71
72 uint64_t Size() const {
73 act::MutexLock l(&mu_);
74 return bytes_;
75 }
76
77 uint64_t Items() const {
78 act::MutexLock l(&mu_);
79 return lru_.Size();
80 }
81
82 private:
83 mutable act::Mutex mu_;
84 LruCache lru_ ABSL_GUARDED_BY(mu_);
85
86 uint64_t bytes_ ABSL_GUARDED_BY(mu_) = 0;
87 uint64_t gets_ ABSL_GUARDED_BY(mu_) = 0;
88 uint64_t hits_ ABSL_GUARDED_BY(mu_) = 0;
89 uint64_t evictions_ ABSL_GUARDED_BY(mu_) = 0;
90};
91
92class Group {
93 public:
94 Group(std::string_view name, size_t cache_bytes, Getter getter);
95
96 std::string_view Name() const { return name_; }
97
98 absl::StatusOr<std::string_view> LookupCache(std::string_view key);
99
100 absl::StatusOr<std::string> Load(std::string_view key,
101 Sink* absl_nonnull dest,
102 bool* absl_nonnull dest_populated);
103
104 private:
105 absl::Status PopulateCache(std::string_view key, std::string_view value,
106 Cache* absl_nonnull cache);
107
108 absl::StatusOr<std::string_view> GetLocally(std::string_view key,
109 Sink* absl_nonnull dest);
110
111 absl::StatusOr<std::string> GetFromPeer(ServiceGetter* absl_nonnull peer,
112 std::string_view key);
113
114 std::string name_;
115
116 Getter getter_;
117 PeerPicker* absl_nullable peers_ = nullptr;
118
119 Cache main_cache_;
120 Cache hot_cache_;
121 uint64_t cache_bytes_ = std::numeric_limits<
122 uint64_t>::max(); // Total bytes allocated for both caches.
123
124 FlightGroup load_group_;
125
126 Stats stats_;
127
128 absl::BitGen rng_;
129
130 absl::once_flag peers_init_once_;
131};
132
133class Instance {
134 public:
135 Group* absl_nonnull NewGroup(std::string_view name, uint64_t cache_bytes,
136 Getter getter,
137 PeerPicker* absl_nullable peers = nullptr);
138
139 Group* absl_nullable GetGroup(std::string_view name);
140
141 private:
142 mutable act::Mutex mu_;
143 absl::flat_hash_map<std::string, std::unique_ptr<Group>> groups_
144 ABSL_GUARDED_BY(mu_);
145};
146
147} // namespace act::distributed
148
149#endif // ACTIONENGINE_DISTRIBUTED_GROUPCACHE_H_
Concurrency utilities for ActionEngine.