]> git.evergreen-ils.org Git - OpenSRF.git/blob - src/libopensrf/osrf_cache.c
08ac596e5c023ae67dfe769ab2317cade2fecde4
[OpenSRF.git] / src / libopensrf / osrf_cache.c
1 /*
2 Copyright (C) 2005  Georgia Public Library Service 
3 Bill Erickson <highfalutin@gmail.com>
4
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.
9
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.
14 */
15
16 #include <opensrf/osrf_cache.h>
17 #include <ctype.h>
18
19 #define MAX_KEY_LEN 250
20
21 static struct memcached_st* _osrfCache = NULL;
22 static time_t _osrfCacheMaxSeconds = -1;
23 static char* _clean_key( const char* );
24
25 int osrfCacheInit( const char* serverStrings[], int size, time_t maxCacheSeconds ) {
26         memcached_server_st *server_pool;
27         memcached_return rc;
28
29         if( !(serverStrings && size > 0) ) return -1;
30         osrfCacheCleanup(); /* in case we've already been init-ed */
31
32         int i;
33         _osrfCache = memcached_create(NULL);
34         _osrfCacheMaxSeconds = maxCacheSeconds;
35
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));
44                 }
45         }
46
47         return 0;
48 }
49
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);
55         free(s);
56         return 0;
57 }
58
59 char* _clean_key( const char* key ) {
60     char* clean_key = (char*)strdup(key);
61     char* d = clean_key;
62     char* s = clean_key;
63     do {
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);
68         clean_key[0] = '\0';
69         strncat(clean_key, "shortened_", 11);
70         strncat(clean_key, hashed, MAX_KEY_LEN);
71         free(hashed);
72     }
73     return clean_key;
74 }
75
76 int osrfCachePutString( const char* key, const char* value, time_t seconds ) {
77         memcached_return rc;
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);
81
82         char* clean_key = _clean_key( key );
83
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));
89         }
90
91         free(clean_key);
92         return 0;
93 }
94
95 jsonObject* osrfCacheGetObject( const char* key, ... ) {
96         size_t val_len;
97         uint32_t flags;
98         memcached_return rc;
99         jsonObject* obj = NULL;
100         if( key ) {
101                 VA_LIST_TO_STRING(key);
102                 char* clean_key = _clean_key( VA_BUF );
103                 const char* data = (const char*) memcached_get(_osrfCache, clean_key, strlen(clean_key), &val_len, &flags, &rc);
104                 free(clean_key);
105                 if (rc != MEMCACHED_SUCCESS) {
106                         osrfLogDebug(OSRF_LOG_MARK, "Failed to get key [%s] - %s",
107                                 VA_BUF, memcached_strerror(_osrfCache, rc));
108                 }
109                 if( data ) {
110                         osrfLogInternal( OSRF_LOG_MARK, "osrfCacheGetObject(): Returning object (key=%s): %s", VA_BUF, data);
111                         obj = jsonParse( data );
112                         return obj;
113                 }
114                 osrfLogDebug(OSRF_LOG_MARK, "No cache data exists with key %s", VA_BUF);
115         }
116         return NULL;
117 }
118
119 char* osrfCacheGetString( const char* key, ... ) {
120         size_t val_len;
121         uint32_t flags;
122         memcached_return rc;
123         if( key ) {
124                 VA_LIST_TO_STRING(key);
125                 char* clean_key = _clean_key( VA_BUF );
126                 char* data = (char*) memcached_get(_osrfCache, clean_key, strlen(clean_key), &val_len, &flags, &rc);
127                 free(clean_key);
128                 if (rc != MEMCACHED_SUCCESS) {
129                         osrfLogDebug(OSRF_LOG_MARK, "Failed to get key [%s] - %s",
130                                 VA_BUF, memcached_strerror(_osrfCache, rc));
131                 }
132                 osrfLogInternal( OSRF_LOG_MARK, "osrfCacheGetString(): Returning object (key=%s): %s", VA_BUF, data);
133                 if(!data) osrfLogDebug(OSRF_LOG_MARK, "No cache data exists with key %s", VA_BUF);
134                 return data;
135         }
136         return NULL;
137 }
138
139
140 int osrfCacheRemove( const char* key, ... ) {
141         memcached_return rc;
142         if( key ) {
143                 VA_LIST_TO_STRING(key);
144                 char* clean_key = _clean_key( VA_BUF );
145                 rc = memcached_delete(_osrfCache, clean_key, strlen(clean_key), 0 );
146                 free(clean_key);
147                 if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED) {
148                         osrfLogDebug(OSRF_LOG_MARK, "Failed to delete key [%s] - %s",
149                                 VA_BUF, memcached_strerror(_osrfCache, rc));
150                 }
151                 return 0;
152         }
153         return -1;
154 }
155
156
157 int osrfCacheSetExpire( time_t seconds, const char* key, ... ) {
158         if( key ) {
159                 VA_LIST_TO_STRING(key);
160                 jsonObject* o = osrfCacheGetObject( VA_BUF );
161                 //osrfCacheRemove(VA_BUF);
162                 int rc = osrfCachePutObject( VA_BUF, o, seconds );
163                 jsonObjectFree(o);
164                 return rc;
165         }
166         return -1;
167 }
168
169 void osrfCacheCleanup() {
170         if(_osrfCache) {
171                 memcached_free(_osrfCache);
172         }
173 }
174
175