Branch data Line data Source code
1 : : // Copyright 2026 HPActor Contributors
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 : : #pragma once
16 : :
17 : : #include <hpactor/ref/actor_ref.hpp>
18 : : #include <hpactor/types/types.hpp>
19 : :
20 : : #include <optional>
21 : : #include <unordered_map>
22 : :
23 : : namespace hpactor {
24 : :
25 : : class ActorRefCache {
26 : : public:
27 : 157 : explicit ActorRefCache(size_t max_entries = DefaultMaxEntries)
28 : 157 : : max_entries_(max_entries) {}
29 : :
30 : 347 : std::optional<ActorRef> get(ActorId id) {
31 : 347 : auto it = cache_.find(id);
32 : 347 : if (it == cache_.end()) {
33 : 34 : return std::nullopt;
34 : : }
35 : 313 : it->second.last_access_tick = ++tick_;
36 : 313 : return it->second.ref;
37 : : }
38 : :
39 : 40 : void put(ActorId id, ActorRef ref) {
40 : 40 : auto it = cache_.find(id);
41 : 40 : if (it != cache_.end()) {
42 : 1 : it->second.ref = std::move(ref);
43 : 1 : it->second.last_access_tick = ++tick_;
44 : 1 : return;
45 : : }
46 : 39 : if (cache_.size() >= max_entries_) {
47 : 2 : evict_lru();
48 : : }
49 : 39 : cache_.emplace(id, Entry{std::move(ref), ++tick_});
50 : : }
51 : :
52 : : private:
53 : : static constexpr size_t DefaultMaxEntries = 256;
54 : :
55 : : struct Entry {
56 : : ActorRef ref;
57 : : uint64_t last_access_tick = 0;
58 : : };
59 : :
60 : 2 : void evict_lru() {
61 : 2 : ActorId lru_id;
62 : 2 : uint64_t min_tick = UINT64_MAX;
63 : 8 : for (const auto& [id, entry] : cache_) {
64 : 6 : if (entry.last_access_tick < min_tick) {
65 : 5 : min_tick = entry.last_access_tick;
66 : 5 : lru_id = id;
67 : : }
68 : : }
69 : 2 : cache_.erase(lru_id);
70 : 2 : }
71 : :
72 : : std::unordered_map<ActorId, Entry> cache_;
73 : : uint64_t tick_ = 0;
74 : : size_t max_entries_;
75 : : };
76 : :
77 : : } // namespace hpactor
|