2 Copyright (C) 2005 Georgia Public Library Service
3 Bill Erickson <highfalutin@gmail.com>
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
16 #include <opensrf/osrf_cache.h>
19 #define MAX_KEY_LEN 250
21 static struct memcached_st* _osrfCache = NULL;
22 static time_t _osrfCacheMaxSeconds = -1;
23 static char* _clean_key( const char* );
25 int osrfCacheInit( const char* serverStrings[], int size, time_t maxCacheSeconds ) {
26 memcached_server_st *server_pool;
29 if( !(serverStrings && size > 0) ) return -1;
30 osrfCacheCleanup(); /* in case we've already been init-ed */
33 _osrfCache = memcached_create(NULL);
34 _osrfCacheMaxSeconds = maxCacheSeconds;
36 for( i = 0; i < size && serverStrings[i]; i++ ) {
37 /* TODO: modify caller to pass a list of servers all at once */
38 server_pool = memcached_servers_parse(serverStrings[i]);
39 rc = memcached_server_push(_osrfCache, server_pool);
40 if (rc != MEMCACHED_SUCCESS) {
41 osrfLogError(OSRF_LOG_MARK,
42 "Failed to add memcached server: %s - %s",
43 serverStrings[i], memcached_strerror(_osrfCache, rc));
50 int osrfCachePutObject( const char* key, const jsonObject* obj, time_t seconds ) {
51 if( !(key && obj) ) return -1;
52 char* s = jsonObjectToJSON( obj );
53 osrfLogInternal( OSRF_LOG_MARK, "osrfCachePut(): Putting object (key=%s): %s", key, s);
54 osrfCachePutString(key, s, seconds);
59 char* _clean_key( const char* key ) {
60 char* clean_key = (char*)strdup(key);
64 while(isspace(*s) || ((*s != '\0') && iscntrl(*s))) s++;
65 } while((*d++ = *s++));
66 if (strlen(clean_key) > MAX_KEY_LEN) {
67 char *hashed = md5sum(clean_key);
69 strncat(clean_key, "shortened_", 11);
70 strncat(clean_key, hashed, MAX_KEY_LEN);
76 int osrfCachePutString( const char* key, const char* value, time_t seconds ) {
78 if( !(key && value) ) return -1;
79 seconds = (seconds <= 0 || seconds > _osrfCacheMaxSeconds) ? _osrfCacheMaxSeconds : seconds;
80 osrfLogInternal( OSRF_LOG_MARK, "osrfCachePutString(): Putting string (key=%s): %s", key, value);
82 char* clean_key = _clean_key( key );
84 /* add or overwrite existing key:value pair */
85 rc = memcached_set(_osrfCache, clean_key, strlen(clean_key), value, strlen(value), seconds, 0);
86 if (rc != MEMCACHED_SUCCESS) {
87 osrfLogError(OSRF_LOG_MARK, "Failed to cache key:value [%s]:[%s] - %s",
88 key, value, memcached_strerror(_osrfCache, rc));
95 jsonObject* osrfCacheGetObject( const char* key, ... ) {
99 jsonObject* obj = NULL;
101 char* clean_key = _clean_key( key );
102 const char* data = (const char*) memcached_get(_osrfCache, clean_key, strlen(clean_key), &val_len, &flags, &rc);
104 if (rc != MEMCACHED_SUCCESS) {
105 osrfLogDebug(OSRF_LOG_MARK, "Failed to get key [%s] - %s",
106 key, memcached_strerror(_osrfCache, rc));
109 osrfLogInternal( OSRF_LOG_MARK, "osrfCacheGetObject(): Returning object (key=%s): %s", key, data);
110 obj = jsonParse( data );
113 osrfLogDebug(OSRF_LOG_MARK, "No cache data exists with key %s", key);
118 char* osrfCacheGetString( const char* key, ... ) {
123 char* clean_key = _clean_key( key );
124 char* data = (char*) memcached_get(_osrfCache, clean_key, strlen(clean_key), &val_len, &flags, &rc);
126 if (rc != MEMCACHED_SUCCESS) {
127 osrfLogDebug(OSRF_LOG_MARK, "Failed to get key [%s] - %s",
128 key, memcached_strerror(_osrfCache, rc));
130 osrfLogInternal( OSRF_LOG_MARK, "osrfCacheGetString(): Returning object (key=%s): %s", key, data);
131 if(!data) osrfLogDebug(OSRF_LOG_MARK, "No cache data exists with key %s", key);
138 int osrfCacheRemove( const char* key, ... ) {
141 char* clean_key = _clean_key( key );
142 rc = memcached_delete(_osrfCache, clean_key, strlen(clean_key), 0 );
144 if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED) {
145 osrfLogDebug(OSRF_LOG_MARK, "Failed to delete key [%s] - %s",
146 key, memcached_strerror(_osrfCache, rc));
154 int osrfCacheSetExpire( time_t seconds, const char* key, ... ) {
156 char* clean_key = _clean_key( key );
157 jsonObject* o = osrfCacheGetObject( clean_key );
158 int rc = osrfCachePutObject( clean_key, o, seconds );
165 void osrfCacheCleanup() {
167 memcached_free(_osrfCache);