-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Expand file tree
/
Copy pathds4_kvstore.h
More file actions
218 lines (198 loc) · 8.82 KB
/
Copy pathds4_kvstore.h
File metadata and controls
218 lines (198 loc) · 8.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#ifndef DS4_KVSTORE_H
#define DS4_KVSTORE_H
#include "ds4.h"
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#define DS4_KVSTORE_FIXED_HEADER 48u
#define DS4_KVSTORE_DEFAULT_MB 4096
#define DS4_KVSTORE_HIT_HALF_LIFE_SECONDS (6ull * 60ull * 60ull)
#define DS4_KVSTORE_EXT_TOOL_MAP (1u << 0)
#define DS4_KVSTORE_EXT_RESPONSES_VISIBLE (1u << 1)
#define DS4_KVSTORE_EXT_THINKING_VISIBLE (1u << 2)
#define DS4_KVSTORE_EXT_SESSION_TITLE (1u << 3)
typedef enum {
DS4_KVSTORE_REASON_UNKNOWN = 0,
DS4_KVSTORE_REASON_COLD = 1,
DS4_KVSTORE_REASON_CONTINUED = 2,
DS4_KVSTORE_REASON_EVICT = 3,
DS4_KVSTORE_REASON_SHUTDOWN = 4,
DS4_KVSTORE_REASON_AGENT_SYSTEM = 5,
DS4_KVSTORE_REASON_AGENT_SESSION = 6,
} ds4_kvstore_reason;
typedef enum {
DS4_KVSTORE_LOG_DEFAULT,
DS4_KVSTORE_LOG_KVCACHE,
DS4_KVSTORE_LOG_WARNING,
} ds4_kvstore_log_type;
typedef struct {
/* The file name is the rendered byte prefix, not the token sequence. The
* payload still carries the exact tokens and graph state; the hash only
* answers "does this checkpoint represent the bytes at the front of the
* incoming prompt?" */
char sha[41];
char *path;
uint8_t quant_bits;
/* Stored in header byte 7. Flash is 0 for backward compatibility with
* older cache files where this reserved byte was always written as zero. */
uint8_t model_id;
uint8_t reason;
uint32_t tokens;
uint32_t hits;
uint32_t ctx_size;
uint8_t ext_flags;
uint64_t created_at;
uint64_t last_used;
uint64_t payload_bytes;
uint64_t text_bytes;
uint64_t file_size;
} ds4_kvstore_entry;
typedef struct {
int min_tokens;
int cold_max_tokens;
int continued_interval_tokens;
int boundary_trim_tokens;
int boundary_align_tokens;
} ds4_kvstore_options;
typedef struct {
bool enabled;
char *dir;
uint64_t budget_bytes;
bool reject_different_quant;
ds4_kvstore_options opt;
int continued_last_store_tokens;
ds4_kvstore_entry *entry;
int len;
int cap;
const char *log_name;
void *log_ud;
void (*log)(void *ud, ds4_kvstore_log_type type, const char *msg);
} ds4_kvstore;
typedef struct {
const char *text;
size_t text_len;
uint8_t model_id;
uint8_t quant_bits;
uint32_t ctx_size;
bool reject_different_quant;
} ds4_kvstore_eviction_context;
typedef struct {
void *ud;
uint8_t ext_flag;
bool (*serialized_size)(void *ud, const char *text, uint64_t *bytes_out);
bool (*write)(void *ud, FILE *fp, const char *text, uint64_t *written_bytes);
int (*load)(void *ud, FILE *fp, const void *wanted);
const void *load_wanted;
} ds4_kvstore_trailer_hooks;
typedef struct {
int tokens;
uint32_t text_bytes;
uint8_t quant_bits;
uint8_t ext_flags;
double load_ms;
bool consumed;
char *path;
} ds4_kvstore_load_result;
ds4_kvstore_options ds4_kvstore_default_options(void);
uint8_t ds4_kvstore_reason_code(const char *reason);
const char *ds4_kvstore_key_kind(uint8_t ext_flags);
bool ds4_kvstore_open(ds4_kvstore *kc, const char *dir, uint64_t budget_mb,
bool reject_different_quant, ds4_kvstore_options opt,
const char *log_name,
void (*log)(void *ud, ds4_kvstore_log_type type, const char *msg),
void *log_ud);
void ds4_kvstore_close(ds4_kvstore *kc);
void ds4_kvstore_clear(ds4_kvstore *kc);
void ds4_kvstore_entry_free(ds4_kvstore_entry *e);
char *ds4_kvstore_render_tokens_text(ds4_engine *engine,
const ds4_tokens *tokens,
size_t *out_len);
bool ds4_kvstore_byte_prefix_match(const char *text, size_t text_len,
const char *prefix, size_t prefix_len);
void ds4_kvstore_tokens_copy_prefix(ds4_tokens *dst, const ds4_tokens *src, int n);
void ds4_kvstore_build_prompt_from_exact_prefix_and_text_suffix(
ds4_engine *engine,
const ds4_tokens *exact_prefix,
const char *suffix_text,
ds4_tokens *out);
int ds4_kvstore_store_len(const ds4_kvstore *kc, int tokens);
int ds4_kvstore_chat_anchor_pos(const ds4_kvstore *kc,
const ds4_tokens *prompt,
int user_token_id,
int assistant_token_id);
int ds4_kvstore_continued_store_target(const ds4_kvstore *kc, int live_tokens);
void ds4_kvstore_note_store(ds4_kvstore *kc, int tokens);
int ds4_kvstore_suppress_continued_store(ds4_kvstore *kc, int tokens);
void ds4_kvstore_restore_suppressed_continued(ds4_kvstore *kc,
int old_tokens,
int suppressed_tokens);
bool ds4_kvstore_file_size_fits(const ds4_kvstore *kc,
uint64_t text_bytes,
uint64_t payload_bytes,
uint64_t trailer_bytes,
uint64_t *file_bytes_out,
uint64_t *required_bytes_out);
double ds4_kvstore_entry_eviction_score(const ds4_kvstore_entry *e,
const ds4_tokens *live,
uint64_t now,
const ds4_kvstore_eviction_context *incoming);
void ds4_kvstore_evict(ds4_kvstore *kc, const ds4_tokens *live,
uint64_t extra_bytes,
const ds4_kvstore_eviction_context *incoming);
int ds4_kvstore_find_text_prefix(ds4_kvstore *kc, const char *prompt_text,
int model_id, int quant_bits, int ctx_size);
bool ds4_kvstore_store_live_prefix_text(ds4_kvstore *kc,
ds4_engine *engine,
ds4_session *session,
const ds4_tokens *tokens,
int store_len,
const char *reason,
const char *cache_text_override,
uint8_t cache_text_ext,
const char *cache_text_key,
const ds4_kvstore_trailer_hooks *hooks,
char *err,
size_t err_len);
bool ds4_kvstore_store_live_prefix(ds4_kvstore *kc,
ds4_engine *engine,
ds4_session *session,
const ds4_tokens *tokens,
int store_len,
const char *reason,
const ds4_kvstore_trailer_hooks *hooks,
char *err,
size_t err_len);
bool ds4_kvstore_maybe_store_continued(ds4_kvstore *kc,
ds4_engine *engine,
ds4_session *session,
const ds4_kvstore_trailer_hooks *hooks,
char *err,
size_t err_len);
int ds4_kvstore_try_load_text(ds4_kvstore *kc,
ds4_engine *engine,
ds4_session *session,
const char *prompt_text,
ds4_tokens *effective_prompt,
ds4_kvstore_load_result *result,
const ds4_kvstore_trailer_hooks *hooks,
bool responses_protocol);
void ds4_kvstore_load_result_free(ds4_kvstore_load_result *result);
bool ds4_kvstore_read_header(FILE *fp, ds4_kvstore_entry *e,
uint32_t *text_bytes);
bool ds4_kvstore_read_entry_file(const char *path, const char sha[41],
ds4_kvstore_entry *out);
void ds4_kvstore_fill_header(uint8_t h[DS4_KVSTORE_FIXED_HEADER],
uint8_t model_id, uint8_t quant_bits,
uint8_t reason, uint8_t ext_flags,
uint32_t tokens, uint32_t hits, uint32_t ctx_size,
uint64_t created_at, uint64_t last_used,
uint64_t payload_bytes);
bool ds4_kvstore_touch_file(const char *path, uint32_t hits);
bool ds4_kvstore_sha_hex_name(const char *name, char sha[41]);
void ds4_kvstore_sha1_bytes_hex(const void *ptr, size_t len, char out[41]);
char *ds4_kvstore_path_join(const char *dir, const char *name);
char *ds4_kvstore_path_for_sha(ds4_kvstore *kc, const char sha[41]);
void ds4_kvstore_le_put32(uint8_t *p, uint32_t v);
uint32_t ds4_kvstore_le_get32(const uint8_t *p);
#endif