diff options
author | Paul Querna | 2004-12-02 21:35:29 +0000 |
---|---|---|
committer | Paul Querna | 2004-12-02 21:35:29 +0000 |
commit | 0b3bc057ca6c68214614f257704cb5a332747b75 (patch) | |
tree | 856e31bec8b57da1cfbdbec5fc70e027ed37dfba /include/memcache.h | |
parent | ed47098c757860a9444fd6de621699a951900211 (diff) |
setting proper ignores.
adding an empty cache files
trying to fix >16kb writes.
Diffstat (limited to 'include/memcache.h')
-rw-r--r-- | include/memcache.h | 402 |
1 files changed, 402 insertions, 0 deletions
diff --git a/include/memcache.h b/include/memcache.h new file mode 100644 index 0000000..b11bf4c --- /dev/null +++ b/include/memcache.h | |||
@@ -0,0 +1,402 @@ | |||
1 | /* Copyright (c) 2004 Sean Chittenden <sean@chittenden.org> | ||
2 | * | ||
3 | * All rights reserved until such time as this code is released with | ||
4 | * an official license. Use of this code for commerical, | ||
5 | * non-commercial, and personal purposes is encouraged. Public forks | ||
6 | * of this code is permitted so long as the fork and its decendents | ||
7 | * use this copyright/license. Use of this software in programs | ||
8 | * released under the GPL programs is expressly prohibited by the | ||
9 | * author (ie, BSD, closed source, or artistic license is okay, but | ||
10 | * GPL is not). */ | ||
11 | |||
12 | #ifndef MEMCACHE_H | ||
13 | #define MEMCACHE_H | ||
14 | |||
15 | #include <netdb.h> | ||
16 | #include <sys/queue.h> | ||
17 | #include <sys/types.h> | ||
18 | #include <sys/time.h> | ||
19 | #include <unistd.h> | ||
20 | |||
21 | #ifdef __cplusplus | ||
22 | extern "C" { | ||
23 | #endif | ||
24 | |||
25 | /* Our initial read(2) buffer has to be long enough to read the | ||
26 | * first line of the response. ie: | ||
27 | * | ||
28 | * "VALUE #{'k' * 250} #{2 ** 15} #{2 ** 32}\r\n.length => 275 | ||
29 | * | ||
30 | * However, since we want to avoid the number of system calls | ||
31 | * necessary, include trailing part of the protocol in our estimate: | ||
32 | * | ||
33 | * "\r\nEND\r\n".length => 7 | ||
34 | * | ||
35 | * Which yields a manditory limit of 282 bytes for a successful | ||
36 | * response. If we wish to try and get lucky with our first read(2) | ||
37 | * call and be able to read(2) in small values without making a second | ||
38 | * read(2) call, pad this number with a sufficiently large byte value. | ||
39 | * If most of your keys are 512B, then a GET_INIT_BUF_SIZE of 794 | ||
40 | * would be prudent (512 + 282). | ||
41 | * | ||
42 | * The default value of 1024 means that values less than 724 bytes | ||
43 | * will always be read(2) via the first read(2) call. Increasing this | ||
44 | * value to large values is not beneficial. If a second read(2) call | ||
45 | * is necessary, the read(2) will be made with a sufficiently large | ||
46 | * buffer already allocated. */ | ||
47 | #define GET_INIT_BUF_SIZE ((size_t)1024) | ||
48 | |||
49 | /* Enables extra protocol checking. It's not strickly necesary if the | ||
50 | * server's sending the right data. This should be on by default, | ||
51 | * but, for those that don't want every check done to make sure things | ||
52 | * are right, undef this. 99% of the universe should leave this as | ||
53 | * is. If you think you're than 1% who doesn't need it, you're on | ||
54 | * crack and should definately leave PEDANTIC on. %*/ | ||
55 | #define PEDANTIC | ||
56 | |||
57 | #define MAX_KEY_LEN 250 | ||
58 | |||
59 | #define HAVE_SELECT 1 | ||
60 | |||
61 | #define USE_CRC32_HASH 1 | ||
62 | /* #define USE_ELF_HASH 1 */ | ||
63 | /* #define USE_PERL_HASH 1 */ | ||
64 | |||
65 | /* Various values for _flags */ | ||
66 | #define MC_RES_FREE_ON_DELETE 0x01 | ||
67 | #define MC_RES_NO_FREE_ON_DELETE 0x02 | ||
68 | #define MC_RES_FOUND 0x04 | ||
69 | struct memcache_res { | ||
70 | const char *key; /* key */ | ||
71 | size_t len; /* length of key */ | ||
72 | u_int32_t hash; /* hash of the key */ | ||
73 | void *val; /* the value */ | ||
74 | size_t bytes; /* length of val */ | ||
75 | |||
76 | /* If size is zero (default), the memory for val is automatically | ||
77 | * allocated using mcMalloc(3). If size is zero, _flags has its | ||
78 | * MC_RES_FREE_ON_DELETE bit set. | ||
79 | * | ||
80 | * If size is non-zero, libmemcache(3) assumes that the caller has | ||
81 | * set val to an available portion of memory that is size bytes | ||
82 | * long. libmemcache(3) will only populate val with as many bytes | ||
83 | * as are specified by size (ie, it will trim the value in order to | ||
84 | * fit into val). If size is non-zero, _flags has its | ||
85 | * MC_RES_NO_FREE_ON_DELETE bit set by default. */ | ||
86 | size_t size; | ||
87 | TAILQ_ENTRY(memcache_res) entries; | ||
88 | |||
89 | /* Note: this flags is very different than _flags. */ | ||
90 | u_int16_t flags; | ||
91 | |||
92 | /* If _flags has 0x01 set, val will be free(3)'ed on when this | ||
93 | * struct is cleaned up via mc_res_free() or the request is cleaned | ||
94 | * up via mc_req_free(). | ||
95 | * | ||
96 | * If _flags has is 0x02 set, val will not be free(3)'ed when this | ||
97 | * response or its parent request are cleaned up. | ||
98 | * | ||
99 | * Note: Use mc_res_free_on_delete() to set the "free on delete" | ||
100 | * bits. */ | ||
101 | char _flags; | ||
102 | }; | ||
103 | |||
104 | struct memcache_req { | ||
105 | TAILQ_HEAD(memcache_res_list, memcache_res) query; | ||
106 | u_int16_t num_keys; | ||
107 | }; | ||
108 | |||
109 | struct memcache_server { | ||
110 | /* The hostname of the server. */ | ||
111 | char *hostname; | ||
112 | |||
113 | /* Port number of the host we're connecting to. */ | ||
114 | char *port; | ||
115 | |||
116 | /* The file descriptor for this server */ | ||
117 | int fd; | ||
118 | |||
119 | /* The file descriptor flags */ | ||
120 | int flags; | ||
121 | |||
122 | /* The timeout for this server */ | ||
123 | struct timeval tv; | ||
124 | |||
125 | /* Is this particular server active or not? | ||
126 | * | ||
127 | * 'd' == Down Last request was unsuccessful | ||
128 | * 'n' == No host The hostname doesn't exist | ||
129 | * 't' == Try Haven't connected to it yet, will attempt | ||
130 | * 'u' == Up Has been connected to successfully | ||
131 | */ | ||
132 | char active; | ||
133 | |||
134 | /* A cached copy of the looked up host. */ | ||
135 | struct addrinfo *hostinfo; | ||
136 | |||
137 | /* The number of addresses in the cached copy. If there is more | ||
138 | * than one per DNS entry (discouraged), we establish a connection | ||
139 | * to them all. */ | ||
140 | u_int32_t num_addrs; | ||
141 | |||
142 | #ifdef HAVE_SELECT | ||
143 | /* Reduces the amount of user time required when reading data. */ | ||
144 | fd_set fds; | ||
145 | struct timeval select_tv; | ||
146 | #endif | ||
147 | |||
148 | /* Misc list bits */ | ||
149 | TAILQ_ENTRY(memcache_server) entries; | ||
150 | }; | ||
151 | |||
152 | |||
153 | struct memcache_server_stats { | ||
154 | pid_t pid; | ||
155 | time_t uptime; | ||
156 | time_t time; | ||
157 | char *version; | ||
158 | struct timeval rusage_user; | ||
159 | struct timeval rusage_system; | ||
160 | u_int32_t curr_items; | ||
161 | u_int64_t total_items; | ||
162 | u_int64_t bytes; | ||
163 | u_int32_t curr_connections; | ||
164 | u_int64_t total_connections; | ||
165 | u_int32_t connection_structures; | ||
166 | u_int64_t cmd_get; | ||
167 | u_int64_t cmd_refresh; | ||
168 | u_int64_t cmd_set; | ||
169 | u_int64_t get_hits; | ||
170 | u_int64_t get_misses; | ||
171 | u_int64_t refresh_hits; | ||
172 | u_int64_t refresh_misses; | ||
173 | u_int64_t bytes_read; | ||
174 | u_int64_t bytes_written; | ||
175 | u_int64_t limit_maxbytes; | ||
176 | }; | ||
177 | |||
178 | |||
179 | struct memcache { | ||
180 | /* The default timeout for all servers */ | ||
181 | struct timeval tv; | ||
182 | |||
183 | /* The default read(2) size when reading a response. */ | ||
184 | size_t read_size; | ||
185 | |||
186 | /* The complete list of servers */ | ||
187 | TAILQ_HEAD(memcache_server_list, memcache_server) server_list; | ||
188 | |||
189 | /* A buffer for data */ | ||
190 | char *buf; | ||
191 | |||
192 | /* A cursor for where we are in the buffer */ | ||
193 | char *cur; | ||
194 | |||
195 | /* A pointer to where data should be appended with future read(2) | ||
196 | * calls. */ | ||
197 | char *read_cur; | ||
198 | |||
199 | /* A pointer to the start of the current line in the buffer. */ | ||
200 | char *start; | ||
201 | |||
202 | /* The allocated size of the buffer */ | ||
203 | size_t size; | ||
204 | |||
205 | /* The number of servers in live_servers */ | ||
206 | u_int32_t num_live_servers; | ||
207 | |||
208 | /* An array of usable memcache_servers */ | ||
209 | struct memcache_server **live_servers; | ||
210 | }; | ||
211 | |||
212 | |||
213 | /* Adds a given key to the cache */ | ||
214 | int mc_add(struct memcache *mc, | ||
215 | const char *key, const size_t key_len, | ||
216 | const void *val, const size_t bytes, | ||
217 | const time_t expire, const u_int16_t flags); | ||
218 | |||
219 | /* Gets the value from memcache and allocates the data for the caller. | ||
220 | * It is the caller's responsibility to free the returned value. | ||
221 | * mc_get() is the preferred interface, however. */ | ||
222 | void *mc_aget(struct memcache *mc, const char *key, const size_t len); | ||
223 | |||
224 | /* Gets the value from memcache and allocates the data for the caller. | ||
225 | * It is the caller's responsibility to free the returned value. | ||
226 | * mc_refresh() is the preferred interface, however. */ | ||
227 | void *mc_arefresh(struct memcache *mc, const char *key, const size_t len); | ||
228 | |||
229 | /* Disconnects from a given server and marks it as down. */ | ||
230 | void mc_deactivate_server(struct memcache *mc, struct memcache_server *ms); | ||
231 | |||
232 | /* Decrements a given key */ | ||
233 | u_int32_t mc_decr(struct memcache *mc, const char *key, const size_t key_len, const u_int32_t val); | ||
234 | |||
235 | /* Deletes a given key */ | ||
236 | int mc_delete(struct memcache *mc, const char *key, const size_t key_len, const time_t hold); | ||
237 | |||
238 | /* When given a hash value, this function returns the appropriate | ||
239 | * server to connect to in order to find the key. */ | ||
240 | struct memcache_server *mc_find_server(struct memcache *mc, const u_int32_t hash); | ||
241 | |||
242 | /* Flushes all keys */ | ||
243 | int mc_flush_all(struct memcache *mc, const char *key, const size_t key_len); | ||
244 | |||
245 | /* cleans up a memcache object. */ | ||
246 | void mc_free(struct memcache *mc); | ||
247 | |||
248 | /* Tells the response object to free the allocated memory when it gets | ||
249 | * cleaned up or to let the caller manage the memory. */ | ||
250 | void mc_res_free_on_delete(struct memcache_res *res, int free_on_delete); | ||
251 | |||
252 | /* mc_get() is the preferred method of accessing memcache. It | ||
253 | * accepts multiple keys and lets a user (should they so choose) | ||
254 | * perform memory caching to reduce the number of mcMalloc(3) calls | ||
255 | * mades. */ | ||
256 | void mc_get(struct memcache *mc, struct memcache_req *req); | ||
257 | |||
258 | /* Generates a hash value from a given key */ | ||
259 | u_int32_t mc_hash_key(const char *key, const size_t len); | ||
260 | |||
261 | /* Increments a given key */ | ||
262 | u_int32_t mc_incr(struct memcache *mc, const char *key, const size_t key_len, const u_int32_t val); | ||
263 | |||
264 | /* Allocates a new memcache object */ | ||
265 | struct memcache *mc_new(void); | ||
266 | |||
267 | /* mc_refresh() is the preferred method of accessing memcache. It | ||
268 | * accepts multiple keys and lets a user (should they so choose) | ||
269 | * perform memory caching to reduce the number of mcMalloc(3) calls | ||
270 | * mades. mc_refresh() differs from mc_get() in that mc_refresh | ||
271 | * updates the expiration time to be now + whatever the expiration for | ||
272 | * the item was set to. Sessions should use this as a way of noting | ||
273 | * sessions expiring. */ | ||
274 | void mc_refresh(struct memcache *mc, struct memcache_req *req); | ||
275 | |||
276 | /* Replaces a given key to the cache */ | ||
277 | int mc_replace(struct memcache *mc, | ||
278 | const char *key, const size_t key_len, | ||
279 | const void *val, const size_t bytes, | ||
280 | const time_t expire, const u_int16_t flags); | ||
281 | |||
282 | /* Adds a key to a given request */ | ||
283 | struct memcache_res *mc_req_add(struct memcache_req *req, const char *key, size_t len); | ||
284 | |||
285 | /* Cleans up a given request and its subsequent responses. If _flags | ||
286 | * has the MC_RES_FREE_ON_DELETE bit set (default), it will clean up | ||
287 | * the value too. If _flags has MC_RES_NO_FREE_ON_DELETE set, | ||
288 | * however, it is the caller's responsibility to free the value. To | ||
289 | * prevent double free(3) errors, if a value is free(3)'ed before | ||
290 | * mc_req_free() is called, set val to NULL. */ | ||
291 | void mc_req_free(struct memcache_req *req); | ||
292 | |||
293 | /* Allocates a new memcache request object. */ | ||
294 | struct memcache_req *mc_req_new(void); | ||
295 | |||
296 | /* Cleans up an individual response object. Normally this is not | ||
297 | * necessary as a call to mc_req_free() will clean up its response | ||
298 | * objects. */ | ||
299 | void mc_res_free(struct memcache_req *req, struct memcache_res *res); | ||
300 | |||
301 | /* Adds a server to the list of available servers. By default, | ||
302 | * servers are assumed to be available. Return codes: | ||
303 | * | ||
304 | * 0: success | ||
305 | * -1: Unable to allocate a new server instance | ||
306 | * -2: Unable to strdup hostname | ||
307 | * -3: Unable to strdup port | ||
308 | * -4: Unable to Unable to resolve the host, server deactivated, but added to list | ||
309 | * -5: Unable to realloc(3) the server list, server list unchanged */ | ||
310 | int mc_server_add(struct memcache *mc, const char *hostname, const char *port); | ||
311 | int mc_server_add2(struct memcache *mc, | ||
312 | const char *hostname, const size_t hostname_len, | ||
313 | const char *port, const size_t port_len); | ||
314 | |||
315 | /* Cleans up a given stat's object */ | ||
316 | void mc_server_stats_free(struct memcache_server_stats *s); | ||
317 | |||
318 | /* Gets a stats object from the given server. It is the caller's | ||
319 | * responsibility to cleanup the resulting object via | ||
320 | * mc_server_stats_free(). */ | ||
321 | struct memcache_server_stats *mc_server_stats(struct memcache *mc, struct memcache_server *ms); | ||
322 | |||
323 | /* Sets a given key */ | ||
324 | int mc_set(struct memcache *mc, | ||
325 | const char *key, const size_t key_len, | ||
326 | const void *val, const size_t bytes, | ||
327 | const time_t expire, const u_int16_t flags); | ||
328 | |||
329 | /* Creates a stats object for all available servers and returns the | ||
330 | * cumulative stats. Per host-specific data is generally the same as | ||
331 | * the last server querried. */ | ||
332 | struct memcache_server_stats *mc_stats(struct memcache *mc); | ||
333 | |||
334 | /* Sets the default timeout for new servers. */ | ||
335 | void mc_timeout(struct memcache *mc, const int sec, const int usec); | ||
336 | |||
337 | |||
338 | |||
339 | /* BEGIN memory management API functions */ | ||
340 | |||
341 | /* The memcache API allows callers to provide their own memory | ||
342 | * allocation routines to aid in embedability with existing programs, | ||
343 | * libraries, programming languages, and environments that have their | ||
344 | * own memory handling routines. This interface was inspired by | ||
345 | * libxml. */ | ||
346 | typedef void (*mcFreeFunc)(void *mem); | ||
347 | typedef void *(*mcMallocFunc)(const size_t size); | ||
348 | typedef void *(*mcReallocFunc)(void *mem, const size_t size); | ||
349 | typedef char *(*mcStrdupFunc)(const char *str); | ||
350 | |||
351 | extern mcFreeFunc mcFree; | ||
352 | extern mcMallocFunc mcMalloc; | ||
353 | extern mcMallocFunc mcMallocAtomic; | ||
354 | extern mcReallocFunc mcRealloc; | ||
355 | extern mcStrdupFunc mcStrdup; | ||
356 | |||
357 | int mcMemSetup(mcFreeFunc freeFunc, mcMallocFunc mallocFunc, | ||
358 | mcReallocFunc reallocFunc, mcStrdupFunc strdupFunc); | ||
359 | int mcMemGet(mcFreeFunc *freeFunc, mcMallocFunc *mallocFunc, | ||
360 | mcReallocFunc *reallocFunc, mcStrdupFunc *strdupFunc); | ||
361 | /* END memory management API functions */ | ||
362 | |||
363 | |||
364 | /* APIs that should be implemented: */ | ||
365 | |||
366 | /* Resets all hosts that are down to try */ | ||
367 | void mc_server_reset_all_active(struct memcache *mc); | ||
368 | |||
369 | /* Resets a given host back to a try state */ | ||
370 | void mc_server_reset_active(struct memcache *mc, const char *hostname, const int port); | ||
371 | |||
372 | /* Resets all dns entries */ | ||
373 | void mc_server_reset_all_dns(struct memcache *mc); | ||
374 | |||
375 | /* Resets only one host's DNS cache */ | ||
376 | void mc_server_reset_dns(struct memcache *mc, const char *hostname, const int port); | ||
377 | |||
378 | /* Disconnects from all memcache servers */ | ||
379 | void mc_server_disconnect_all(struct memcache *mc); | ||
380 | |||
381 | /* Disconnects from one memcache server */ | ||
382 | void mc_server_disconnect(struct memcache *mc, const char *hostname, const int port); | ||
383 | |||
384 | #ifdef TCP_NODELAY | ||
385 | /* Enable/disable TCP_NODELAY */ | ||
386 | void mc_nodelay_enable(struct memcache *mc, const int enable); | ||
387 | |||
388 | /* Enable/disable TCP_NODELAY for a given server */ | ||
389 | void mc_server_nodelay_enable(struct memcache_server *ms, const int enable); | ||
390 | #endif | ||
391 | |||
392 | /* Set the timeout on a per server basis */ | ||
393 | void mc_server_timeout(struct memcache_server *ms, const int sec, const int usec); | ||
394 | |||
395 | /* Set the number of seconds you're willing to wait in total for a | ||
396 | * response. ??? */ | ||
397 | |||
398 | #ifdef __cplusplus | ||
399 | } | ||
400 | #endif | ||
401 | |||
402 | #endif | ||