Entropic 2.14.3
Local-first agentic inference engine
Loading...
Searching...
No Matches
session_residency.h
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
34#pragma once
35
36#include <cstddef>
37#include <cstdint>
38#include <string>
39#include <unordered_map>
40#include <vector>
41
42namespace entropic {
43
45constexpr int kNoSessionSlot = -1;
46
53template <typename Tok>
55public:
61 explicit SessionResidency(int slots = 1)
62 : slots_(slots < 1 ? 1 : slots), resident_(
63 static_cast<std::size_t>(slots < 1 ? 1 : slots)) {}
64
72 int slot_for(const std::string& key) const {
73 auto it = assigned_.find(key);
74 return it == assigned_.end() ? kNoSessionSlot : it->second;
75 }
76
88 int acquire(const std::string& key, std::string* evicted) {
89 if (evicted != nullptr) { evicted->clear(); }
90 auto it = assigned_.find(key);
91 if (it != assigned_.end()) {
92 touch(key);
93 return it->second;
94 }
95 int slot = free_slot();
96 if (slot == kNoSessionSlot) {
97 const std::string victim = lru_key();
98 slot = assigned_[victim];
99 forget(victim);
100 if (evicted != nullptr) { *evicted = victim; }
101 }
102 assigned_[key] = slot;
103 touch(key);
104 return slot;
105 }
106
114 const std::vector<Tok>& resident(int slot) const {
115 static const std::vector<Tok> kEmpty;
116 return valid(slot) ? resident_[static_cast<std::size_t>(slot)]
117 : kEmpty;
118 }
119
127 void set_resident(int slot, std::vector<Tok> tokens) {
128 if (valid(slot)) {
129 resident_[static_cast<std::size_t>(slot)] = std::move(tokens);
130 }
131 }
132
139 void invalidate(int slot) {
140 if (valid(slot)) {
141 resident_[static_cast<std::size_t>(slot)].clear();
142 }
143 }
144
154 for (auto& v : resident_) { v.clear(); }
155 }
156
180 int forget_session(const std::string& key) {
181 auto it = assigned_.find(key);
182 if (it == assigned_.end()) { return kNoSessionSlot; }
183 const int slot = it->second;
185 forget(key);
186 return slot;
187 }
188
195 int slots() const { return slots_; }
196
203 std::size_t assigned_count() const { return assigned_.size(); }
204
205private:
213 bool valid(int slot) const {
214 return slot >= 0 && slot < slots_;
215 }
216
223 void touch(const std::string& key) { use_order_[key] = ++tick_; }
224
231 void forget(const std::string& key) {
232 assigned_.erase(key);
233 use_order_.erase(key);
234 }
235
242 int free_slot() const {
243 std::vector<bool> taken(static_cast<std::size_t>(slots_), false);
244 for (const auto& [k, s] : assigned_) {
245 if (s >= 0 && s < slots_) {
246 taken[static_cast<std::size_t>(s)] = true;
247 }
248 }
249 int found = kNoSessionSlot;
250 for (int i = 0; i < slots_ && found == kNoSessionSlot; ++i) {
251 if (!taken[static_cast<std::size_t>(i)]) { found = i; }
252 }
253 return found;
254 }
255
262 std::string lru_key() const {
263 std::string oldest;
265 for (const auto& [k, t] : use_order_) {
266 if (t < best) { best = t; oldest = k; }
267 }
268 return oldest;
269 }
270
271 int slots_;
272 std::vector<std::vector<Tok>> resident_;
273 std::unordered_map<std::string, int> assigned_;
274 std::unordered_map<std::string, uint64_t> use_order_;
275 uint64_t tick_ = 0;
276};
277
278} // namespace entropic
Per-session llama sequence slots and their resident tokens.
int slot_for(const std::string &key) const
Slot currently holding this session, if any.
const std::vector< Tok > & resident(int slot) const
Tokens recorded as resident in a slot.
int slots() const
Number of sequence slots in the pool.
std::size_t assigned_count() const
How many sessions currently hold a slot.
void invalidate_all()
Forget every slot's residency.
SessionResidency(int slots=1)
Size the pool.
void invalidate(int slot)
Forget a slot's residency (its KV was cleared or invalidated).
int forget_session(const std::string &key)
Drop one SESSION's residency and release its slot (gh#165).
int acquire(const std::string &key, std::string *evicted)
Assign a slot to this session, evicting the least-recently used one when the pool is full.
void set_resident(int slot, std::vector< Tok > tokens)
Record what a slot now holds after a decode.
Activate model on GPU (WARM → ACTIVE).
@ tokens
Gate on generated tokens since the last tool call.
constexpr int kNoSessionSlot
Sentinel for "no slot assigned".
@ optional
optional: every escape asks the host's path approver