1251876Speter/* Licensed to the Apache Software Foundation (ASF) under one or more
2251876Speter * contributor license agreements.  See the NOTICE file distributed with
3251876Speter * this work for additional information regarding copyright ownership.
4251876Speter * The ASF licenses this file to You under the Apache License, Version 2.0
5251876Speter * (the "License"); you may not use this file except in compliance with
6251876Speter * the License.  You may obtain a copy of the License at
7251876Speter *
8251876Speter *     http://www.apache.org/licenses/LICENSE-2.0
9251876Speter *
10251876Speter * Unless required by applicable law or agreed to in writing, software
11251876Speter * distributed under the License is distributed on an "AS IS" BASIS,
12251876Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13251876Speter * See the License for the specific language governing permissions and
14251876Speter * limitations under the License.
15251876Speter */
16251876Speter
17251876Speter#ifndef APR_MEMCACHE_H
18251876Speter#define APR_MEMCACHE_H
19251876Speter
20251876Speter/**
21251876Speter * @file apr_memcache.h
22251876Speter * @brief Client interface for memcached
23251876Speter * @remark To use this interface you must have a separate memcached
24251876Speter * server running. See the memcached website at http://www.danga.com/memcached/
25251876Speter * for more information.
26251876Speter */
27251876Speter
28251876Speter#include "apr.h"
29251876Speter#include "apr_pools.h"
30251876Speter#include "apr_time.h"
31251876Speter#include "apr_strings.h"
32251876Speter#include "apr_network_io.h"
33251876Speter#include "apr_ring.h"
34251876Speter#include "apr_buckets.h"
35251876Speter#include "apr_reslist.h"
36251876Speter#include "apr_hash.h"
37251876Speter
38251876Speter#ifdef __cplusplus
39251876Speterextern "C" {
40251876Speter#endif /* __cplusplus */
41251876Speter
42251876Speter/**
43251876Speter * @defgroup APR_Util_MC Memcached Client Routines
44251876Speter * @ingroup APR_Util
45251876Speter * @{
46251876Speter */
47251876Speter
48251876Speter/** Specifies the status of a memcached server */
49251876Spetertypedef enum
50251876Speter{
51251876Speter    APR_MC_SERVER_LIVE, /**< Server is alive and responding to requests */
52251876Speter    APR_MC_SERVER_DEAD  /**< Server is not responding to requests */
53251876Speter} apr_memcache_server_status_t;
54251876Speter
55251876Speter/** Opaque memcache client connection object */
56251876Spetertypedef struct apr_memcache_conn_t apr_memcache_conn_t;
57251876Speter
58251876Speter/** Memcache Server Info Object */
59251876Spetertypedef struct apr_memcache_server_t apr_memcache_server_t;
60251876Speterstruct apr_memcache_server_t
61251876Speter{
62251876Speter    const char *host; /**< Hostname of this Server */
63251876Speter    apr_port_t port; /**< Port of this Server */
64251876Speter    apr_memcache_server_status_t status; /**< @see apr_memcache_server_status_t */
65251876Speter#if APR_HAS_THREADS || defined(DOXYGEN)
66251876Speter    apr_reslist_t *conns; /**< Resource list of actual client connections */
67251876Speter#else
68251876Speter    apr_memcache_conn_t *conn;
69251876Speter#endif
70251876Speter    apr_pool_t *p; /** Pool to use for private allocations */
71251876Speter#if APR_HAS_THREADS
72251876Speter    apr_thread_mutex_t *lock;
73251876Speter#endif
74251876Speter    apr_time_t btime;
75251876Speter};
76251876Speter
77251876Speter/* Custom hash callback function prototype, user for server selection.
78251876Speter* @param baton user selected baton
79251876Speter* @param data data to hash
80251876Speter* @param data_len length of data
81251876Speter*/
82251876Spetertypedef apr_uint32_t (*apr_memcache_hash_func)(void *baton,
83251876Speter                                               const char *data,
84251876Speter                                               const apr_size_t data_len);
85251876Speter
86251876Spetertypedef struct apr_memcache_t apr_memcache_t;
87251876Speter
88251876Speter/* Custom Server Select callback function prototype.
89251876Speter* @param baton user selected baton
90251876Speter* @param mc memcache instance, use mc->live_servers to select a node
91251876Speter* @param hash hash of the selected key.
92251876Speter*/
93251876Spetertypedef apr_memcache_server_t* (*apr_memcache_server_func)(void *baton,
94251876Speter                                                 apr_memcache_t *mc,
95251876Speter                                                 const apr_uint32_t hash);
96251876Speter
97251876Speter/** Container for a set of memcached servers */
98251876Speterstruct apr_memcache_t
99251876Speter{
100251876Speter    apr_uint32_t flags; /**< Flags, Not currently used */
101251876Speter    apr_uint16_t nalloc; /**< Number of Servers Allocated */
102251876Speter    apr_uint16_t ntotal; /**< Number of Servers Added */
103251876Speter    apr_memcache_server_t **live_servers; /**< Array of Servers */
104251876Speter    apr_pool_t *p; /** Pool to use for allocations */
105251876Speter    void *hash_baton;
106251876Speter    apr_memcache_hash_func hash_func;
107251876Speter    void *server_baton;
108251876Speter    apr_memcache_server_func server_func;
109251876Speter};
110251876Speter
111251876Speter/** Returned Data from a multiple get */
112251876Spetertypedef struct
113251876Speter{
114251876Speter    apr_status_t status;
115251876Speter    const char* key;
116251876Speter    apr_size_t len;
117251876Speter    char *data;
118251876Speter    apr_uint16_t flags;
119251876Speter} apr_memcache_value_t;
120251876Speter
121251876Speter/**
122251876Speter * Creates a crc32 hash used to split keys between servers
123251876Speter * @param mc The memcache client object to use
124251876Speter * @param data Data to be hashed
125251876Speter * @param data_len Length of the data to use
126251876Speter * @return crc32 hash of data
127251876Speter * @remark The crc32 hash is not compatible with old memcached clients.
128251876Speter */
129251876SpeterAPU_DECLARE(apr_uint32_t) apr_memcache_hash(apr_memcache_t *mc,
130251876Speter                                            const char *data,
131251876Speter                                            const apr_size_t data_len);
132251876Speter
133251876Speter/**
134251876Speter * Pure CRC32 Hash. Used by some clients.
135251876Speter */
136251876SpeterAPU_DECLARE(apr_uint32_t) apr_memcache_hash_crc32(void *baton,
137251876Speter                                                  const char *data,
138251876Speter                                                  const apr_size_t data_len);
139251876Speter
140251876Speter/**
141251876Speter * hash compatible with the standard Perl Client.
142251876Speter */
143251876SpeterAPU_DECLARE(apr_uint32_t) apr_memcache_hash_default(void *baton,
144251876Speter                                                    const char *data,
145251876Speter                                                    const apr_size_t data_len);
146251876Speter
147251876Speter/**
148251876Speter * Picks a server based on a hash
149251876Speter * @param mc The memcache client object to use
150251876Speter * @param hash Hashed value of a Key
151251876Speter * @return server that controls specified hash
152251876Speter * @see apr_memcache_hash
153251876Speter */
154251876SpeterAPU_DECLARE(apr_memcache_server_t *) apr_memcache_find_server_hash(apr_memcache_t *mc,
155251876Speter                                                                   const apr_uint32_t hash);
156251876Speter
157251876Speter/**
158251876Speter * server selection compatible with the standard Perl Client.
159251876Speter */
160251876SpeterAPU_DECLARE(apr_memcache_server_t *) apr_memcache_find_server_hash_default(void *baton,
161251876Speter                                                                           apr_memcache_t *mc,
162251876Speter                                                                           const apr_uint32_t hash);
163251876Speter
164251876Speter/**
165251876Speter * Adds a server to a client object
166251876Speter * @param mc The memcache client object to use
167251876Speter * @param server Server to add
168251876Speter * @remark Adding servers is not thread safe, and should be done once at startup.
169251876Speter * @warning Changing servers after startup may cause keys to go to
170251876Speter * different servers.
171251876Speter */
172251876SpeterAPU_DECLARE(apr_status_t) apr_memcache_add_server(apr_memcache_t *mc,
173251876Speter                                                  apr_memcache_server_t *server);
174251876Speter
175251876Speter
176251876Speter/**
177251876Speter * Finds a Server object based on a hostname/port pair
178251876Speter * @param mc The memcache client object to use
179251876Speter * @param host Hostname of the server
180251876Speter * @param port Port of the server
181251876Speter * @return Server with matching Hostname and Port, or NULL if none was found.
182251876Speter */
183251876SpeterAPU_DECLARE(apr_memcache_server_t *) apr_memcache_find_server(apr_memcache_t *mc,
184251876Speter                                                              const char *host,
185251876Speter                                                              apr_port_t port);
186251876Speter
187251876Speter/**
188251876Speter * Enables a Server for use again
189251876Speter * @param mc The memcache client object to use
190251876Speter * @param ms Server to Activate
191251876Speter */
192251876SpeterAPU_DECLARE(apr_status_t) apr_memcache_enable_server(apr_memcache_t *mc,
193251876Speter                                                     apr_memcache_server_t *ms);
194251876Speter
195251876Speter
196251876Speter/**
197251876Speter * Disable a Server
198251876Speter * @param mc The memcache client object to use
199251876Speter * @param ms Server to Disable
200251876Speter */
201251876SpeterAPU_DECLARE(apr_status_t) apr_memcache_disable_server(apr_memcache_t *mc,
202251876Speter                                                      apr_memcache_server_t *ms);
203251876Speter
204251876Speter/**
205251876Speter * Creates a new Server Object
206251876Speter * @param p Pool to use
207251876Speter * @param host hostname of the server
208251876Speter * @param port port of the server
209251876Speter * @param min  minimum number of client sockets to open
210251876Speter * @param smax soft maximum number of client connections to open
211251876Speter * @param max  hard maximum number of client connections
212251876Speter * @param ttl  time to live in microseconds of a client connection
213251876Speter * @param ns   location of the new server object
214251876Speter * @see apr_reslist_create
215251876Speter * @remark min, smax, and max are only used when APR_HAS_THREADS
216251876Speter */
217251876SpeterAPU_DECLARE(apr_status_t) apr_memcache_server_create(apr_pool_t *p,
218251876Speter                                                     const char *host,
219251876Speter                                                     apr_port_t port,
220251876Speter                                                     apr_uint32_t min,
221251876Speter                                                     apr_uint32_t smax,
222251876Speter                                                     apr_uint32_t max,
223251876Speter                                                     apr_uint32_t ttl,
224251876Speter                                                     apr_memcache_server_t **ns);
225251876Speter/**
226251876Speter * Creates a new memcached client object
227251876Speter * @param p Pool to use
228251876Speter * @param max_servers maximum number of servers
229251876Speter * @param flags Not currently used
230251876Speter * @param mc   location of the new memcache client object
231251876Speter */
232251876SpeterAPU_DECLARE(apr_status_t) apr_memcache_create(apr_pool_t *p,
233251876Speter                                              apr_uint16_t max_servers,
234251876Speter                                              apr_uint32_t flags,
235251876Speter                                              apr_memcache_t **mc);
236251876Speter
237251876Speter/**
238251876Speter * Gets a value from the server, allocating the value out of p
239251876Speter * @param mc client to use
240251876Speter * @param p Pool to use
241251876Speter * @param key null terminated string containing the key
242251876Speter * @param baton location of the allocated value
243251876Speter * @param len   length of data at baton
244251876Speter * @param flags any flags set by the client for this key
245251876Speter * @return
246251876Speter */
247251876SpeterAPU_DECLARE(apr_status_t) apr_memcache_getp(apr_memcache_t *mc,
248251876Speter                                            apr_pool_t *p,
249251876Speter                                            const char* key,
250251876Speter                                            char **baton,
251251876Speter                                            apr_size_t *len,
252251876Speter                                            apr_uint16_t *flags);
253251876Speter
254251876Speter
255251876Speter/**
256251876Speter * Add a key to a hash for a multiget query
257251876Speter *  if the hash (*value) is NULL it will be created
258251876Speter * @param data_pool pool from where the hash and their items are created from
259251876Speter * @param key null terminated string containing the key
260251876Speter * @param values hash of keys and values that this key will be added to
261251876Speter * @return
262251876Speter */
263251876SpeterAPU_DECLARE(void) apr_memcache_add_multget_key(apr_pool_t *data_pool,
264251876Speter                                               const char* key,
265251876Speter                                               apr_hash_t **values);
266251876Speter
267251876Speter/**
268251876Speter * Gets multiple values from the server, allocating the values out of p
269251876Speter * @param mc client to use
270251876Speter * @param temp_pool Pool used for temporary allocations. May be cleared inside this
271251876Speter *        call.
272251876Speter * @param data_pool Pool used to allocate data for the returned values.
273251876Speter * @param values hash of apr_memcache_value_t keyed by strings, contains the
274251876Speter *        result of the multiget call.
275251876Speter * @return
276251876Speter */
277251876SpeterAPU_DECLARE(apr_status_t) apr_memcache_multgetp(apr_memcache_t *mc,
278251876Speter                                                apr_pool_t *temp_pool,
279251876Speter                                                apr_pool_t *data_pool,
280251876Speter                                                apr_hash_t *values);
281251876Speter
282251876Speter/**
283251876Speter * Sets a value by key on the server
284251876Speter * @param mc client to use
285251876Speter * @param key   null terminated string containing the key
286251876Speter * @param baton data to store on the server
287251876Speter * @param data_size   length of data at baton
288251876Speter * @param timeout time in seconds for the data to live on the server
289251876Speter * @param flags any flags set by the client for this key
290251876Speter */
291251876SpeterAPU_DECLARE(apr_status_t) apr_memcache_set(apr_memcache_t *mc,
292251876Speter                                           const char *key,
293251876Speter                                           char *baton,
294251876Speter                                           const apr_size_t data_size,
295251876Speter                                           apr_uint32_t timeout,
296251876Speter                                           apr_uint16_t flags);
297251876Speter
298251876Speter/**
299251876Speter * Adds value by key on the server
300251876Speter * @param mc client to use
301251876Speter * @param key   null terminated string containing the key
302251876Speter * @param baton data to store on the server
303251876Speter * @param data_size   length of data at baton
304251876Speter * @param timeout time for the data to live on the server
305251876Speter * @param flags any flags set by the client for this key
306251876Speter * @return APR_SUCCESS if the key was added, APR_EEXIST if the key
307251876Speter * already exists on the server.
308251876Speter */
309251876SpeterAPU_DECLARE(apr_status_t) apr_memcache_add(apr_memcache_t *mc,
310251876Speter                                           const char *key,
311251876Speter                                           char *baton,
312251876Speter                                           const apr_size_t data_size,
313251876Speter                                           apr_uint32_t timeout,
314251876Speter                                           apr_uint16_t flags);
315251876Speter
316251876Speter/**
317251876Speter * Replaces value by key on the server
318251876Speter * @param mc client to use
319251876Speter * @param key   null terminated string containing the key
320251876Speter * @param baton data to store on the server
321251876Speter * @param data_size   length of data at baton
322251876Speter * @param timeout time for the data to live on the server
323251876Speter * @param flags any flags set by the client for this key
324251876Speter * @return APR_SUCCESS if the key was added, APR_EEXIST if the key
325251876Speter * did not exist on the server.
326251876Speter */
327251876SpeterAPU_DECLARE(apr_status_t) apr_memcache_replace(apr_memcache_t *mc,
328251876Speter                                               const char *key,
329251876Speter                                               char *baton,
330251876Speter                                               const apr_size_t data_size,
331251876Speter                                               apr_uint32_t timeout,
332251876Speter                                               apr_uint16_t flags);
333251876Speter/**
334251876Speter * Deletes a key from a server
335251876Speter * @param mc client to use
336251876Speter * @param key   null terminated string containing the key
337251876Speter * @param timeout time for the delete to stop other clients from adding
338251876Speter */
339251876SpeterAPU_DECLARE(apr_status_t) apr_memcache_delete(apr_memcache_t *mc,
340251876Speter                                              const char *key,
341251876Speter                                              apr_uint32_t timeout);
342251876Speter
343251876Speter/**
344251876Speter * Increments a value
345251876Speter * @param mc client to use
346251876Speter * @param key   null terminated string containing the key
347251876Speter * @param n     number to increment by
348251876Speter * @param nv    new value after incrementing
349251876Speter */
350251876SpeterAPU_DECLARE(apr_status_t) apr_memcache_incr(apr_memcache_t *mc,
351251876Speter                                            const char *key,
352251876Speter                                            apr_int32_t n,
353251876Speter                                            apr_uint32_t *nv);
354251876Speter
355251876Speter/**
356251876Speter * Decrements a value
357251876Speter * @param mc client to use
358251876Speter * @param key   null terminated string containing the key
359251876Speter * @param n     number to decrement by
360251876Speter * @param new_value    new value after decrementing
361251876Speter */
362251876SpeterAPU_DECLARE(apr_status_t) apr_memcache_decr(apr_memcache_t *mc,
363251876Speter                                            const char *key,
364251876Speter                                            apr_int32_t n,
365251876Speter                                            apr_uint32_t *new_value);
366251876Speter
367251876Speter/**
368251876Speter * Query a server's version
369251876Speter * @param ms    server to query
370251876Speter * @param p     Pool to allocate answer from
371251876Speter * @param baton location to store server version string
372251876Speter * @param len   length of the server version string
373251876Speter */
374251876SpeterAPU_DECLARE(apr_status_t) apr_memcache_version(apr_memcache_server_t *ms,
375251876Speter                                               apr_pool_t *p,
376251876Speter                                               char **baton);
377251876Speter
378251876Spetertypedef struct
379251876Speter{
380251876Speter    /** Version string of this server */
381251876Speter    const char *version;
382251876Speter    /** Process id of this server process */
383251876Speter    apr_uint32_t pid;
384251876Speter    /** Number of seconds this server has been running */
385251876Speter    apr_uint32_t uptime;
386251876Speter    /** current UNIX time according to the server */
387251876Speter    apr_time_t time;
388251876Speter    /** The size of a pointer on the current machine */
389251876Speter    apr_uint32_t pointer_size;
390251876Speter    /** Accumulated user time for this process */
391251876Speter    apr_time_t rusage_user;
392251876Speter    /** Accumulated system time for this process */
393251876Speter    apr_time_t rusage_system;
394251876Speter    /** Current number of items stored by the server */
395251876Speter    apr_uint32_t curr_items;
396251876Speter    /** Total number of items stored by this server */
397251876Speter    apr_uint32_t total_items;
398251876Speter    /** Current number of bytes used by this server to store items */
399251876Speter    apr_uint64_t bytes;
400251876Speter    /** Number of open connections */
401251876Speter    apr_uint32_t curr_connections;
402251876Speter    /** Total number of connections opened since the server started running */
403251876Speter    apr_uint32_t total_connections;
404251876Speter    /** Number of connection structures allocated by the server */
405251876Speter    apr_uint32_t connection_structures;
406251876Speter    /** Cumulative number of retrieval requests */
407251876Speter    apr_uint32_t cmd_get;
408251876Speter    /** Cumulative number of storage requests */
409251876Speter    apr_uint32_t cmd_set;
410251876Speter    /** Number of keys that have been requested and found present */
411251876Speter    apr_uint32_t get_hits;
412251876Speter    /** Number of items that have been requested and not found */
413251876Speter    apr_uint32_t get_misses;
414251876Speter    /** Number of items removed from cache because they passed their
415251876Speter        expiration time */
416251876Speter    apr_uint64_t evictions;
417251876Speter    /** Total number of bytes read by this server */
418251876Speter    apr_uint64_t bytes_read;
419251876Speter    /** Total number of bytes sent by this server */
420251876Speter    apr_uint64_t bytes_written;
421251876Speter    /** Number of bytes this server is allowed to use for storage. */
422251876Speter    apr_uint32_t limit_maxbytes;
423251876Speter    /** Number of threads the server is running (if built with threading) */
424251876Speter    apr_uint32_t threads;
425251876Speter} apr_memcache_stats_t;
426251876Speter
427251876Speter/**
428251876Speter * Query a server for statistics
429251876Speter * @param ms    server to query
430251876Speter * @param p     Pool to allocate answer from
431251876Speter * @param stats location of the new statistics structure
432251876Speter */
433251876SpeterAPU_DECLARE(apr_status_t) apr_memcache_stats(apr_memcache_server_t *ms,
434251876Speter                                             apr_pool_t *p,
435251876Speter                                             apr_memcache_stats_t **stats);
436251876Speter
437251876Speter
438251876Speter/** @} */
439251876Speter
440251876Speter#ifdef __cplusplus
441251876Speter}
442251876Speter#endif
443251876Speter
444251876Speter#endif /* APR_MEMCACHE_H */
445