Merge lp:~posulliv/libmemcached/c++-interface into lp:~tangent-org/libmemcached/trunk
- c++-interface
- Merge into trunk
Proposed by
Padraig O'Sullivan
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~posulliv/libmemcached/c++-interface |
Merge into: | lp:~tangent-org/libmemcached/trunk |
Diff against target: | None lines |
To merge this branch: | bzr merge lp:~posulliv/libmemcached/c++-interface |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Libmemcached-developers | Pending | ||
Review via email: mp+8617@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Padraig O'Sullivan (posulliv) wrote : | # |
Revision history for this message
Brian Aker (brianaker) wrote : | # |
Thanks!
This is a huge improvement over the current interface (which I am sure no one is using).
Revision history for this message
Brian Aker (brianaker) wrote : | # |
Looking through the code.. mget() going to be quite slow I suspect because of the memory allocation that will be done because of it.
I modified mget() to not do a malloc, and instead use a vector for the key sizes.
I suspect we could look at the lower level interfaces and find a way of getting the advantages of mget() without doing the vector overhead. Probably just a matter of flipping the bit for pipelining requests and sending down directly the bits from the std:string.
Code is now in trunk.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'libmemcached/memcached.hh' | |||
2 | --- libmemcached/memcached.hh 2009-07-07 21:57:24 +0000 | |||
3 | +++ libmemcached/memcached.hh 2009-07-11 19:10:39 +0000 | |||
4 | @@ -1,175 +1,354 @@ | |||
8 | 1 | #include "libmemcached/memcached.h" | 1 | #include <libmemcached/memcached.h> |
9 | 2 | #include <string.h> | 2 | |
10 | 3 | #include <stdio.h> | 3 | #include <string> |
11 | 4 | #include <vector> | ||
12 | 4 | 5 | ||
13 | 5 | class Memcached | 6 | class Memcached |
14 | 6 | { | 7 | { |
15 | 7 | memcached_st memc; | ||
16 | 8 | memcached_result_st result; | ||
17 | 9 | |||
18 | 10 | public: | 8 | public: |
19 | 11 | 9 | ||
21 | 12 | Memcached() : memc(), result() | 10 | Memcached() |
22 | 11 | : | ||
23 | 12 | memc(), | ||
24 | 13 | result() | ||
25 | 13 | { | 14 | { |
26 | 14 | memcached_create(&memc); | 15 | memcached_create(&memc); |
27 | 15 | } | 16 | } |
28 | 16 | 17 | ||
30 | 17 | Memcached(memcached_st *clone) : memc(), result() | 18 | Memcached(memcached_st *clone) |
31 | 19 | : | ||
32 | 20 | memc(), | ||
33 | 21 | result() | ||
34 | 18 | { | 22 | { |
35 | 19 | memcached_clone(&memc, clone); | 23 | memcached_clone(&memc, clone); |
36 | 20 | } | 24 | } |
187 | 21 | char *fetch (char *key, size_t *key_length, size_t *value_length) | 25 | |
38 | 22 | { | ||
39 | 23 | uint32_t flags; | ||
40 | 24 | memcached_return rc; | ||
41 | 25 | |||
42 | 26 | return memcached_fetch(&memc, key, key_length, | ||
43 | 27 | value_length, &flags, &rc); | ||
44 | 28 | } | ||
45 | 29 | char *get(const char *key, size_t *value_length) | ||
46 | 30 | { | ||
47 | 31 | uint32_t flags; | ||
48 | 32 | memcached_return rc; | ||
49 | 33 | |||
50 | 34 | return memcached_get(&memc, key, strlen(key), | ||
51 | 35 | value_length, &flags, &rc); | ||
52 | 36 | } | ||
53 | 37 | |||
54 | 38 | char *get_by_key(const char *master_key, const char *key, | ||
55 | 39 | size_t *value_length) | ||
56 | 40 | { | ||
57 | 41 | uint32_t flags; | ||
58 | 42 | memcached_return rc; | ||
59 | 43 | |||
60 | 44 | return memcached_get_by_key(&memc, master_key, strlen(master_key), | ||
61 | 45 | key, strlen(key), | ||
62 | 46 | value_length, &flags, &rc); | ||
63 | 47 | } | ||
64 | 48 | |||
65 | 49 | memcached_return mget(char **keys, size_t *key_length, | ||
66 | 50 | unsigned int number_of_keys) | ||
67 | 51 | { | ||
68 | 52 | |||
69 | 53 | return memcached_mget(&memc, keys, key_length, number_of_keys); | ||
70 | 54 | } | ||
71 | 55 | |||
72 | 56 | memcached_return set(const char *key, const char *value, size_t value_length) | ||
73 | 57 | { | ||
74 | 58 | return memcached_set(&memc, key, strlen(key), | ||
75 | 59 | value, value_length, | ||
76 | 60 | time_t(0), uint32_t(0)); | ||
77 | 61 | } | ||
78 | 62 | |||
79 | 63 | memcached_return set_by_key(const char *master_key, const char *key, | ||
80 | 64 | const char *value, size_t value_length) | ||
81 | 65 | { | ||
82 | 66 | return memcached_set_by_key(&memc, master_key, strlen(master_key), | ||
83 | 67 | key, strlen(key), | ||
84 | 68 | value, value_length, | ||
85 | 69 | time_t(0), | ||
86 | 70 | uint32_t(0) ); | ||
87 | 71 | } | ||
88 | 72 | memcached_return | ||
89 | 73 | increment(const char *key, unsigned int offset, uint64_t *value) | ||
90 | 74 | { | ||
91 | 75 | return memcached_increment(&memc, key, strlen(key), | ||
92 | 76 | offset, value); | ||
93 | 77 | } | ||
94 | 78 | memcached_return | ||
95 | 79 | decrement(const char *key, unsigned int offset, uint64_t *value) | ||
96 | 80 | { | ||
97 | 81 | return memcached_decrement(&memc, key, strlen(key), | ||
98 | 82 | offset, value); | ||
99 | 83 | } | ||
100 | 84 | |||
101 | 85 | |||
102 | 86 | memcached_return add(const char *key, const char *value, size_t value_length) | ||
103 | 87 | { | ||
104 | 88 | return memcached_add(&memc, key, strlen(key), value, value_length, 0, 0); | ||
105 | 89 | } | ||
106 | 90 | memcached_return add_by_key(const char *master_key, const char *key, | ||
107 | 91 | const char *value, size_t value_length) | ||
108 | 92 | { | ||
109 | 93 | return memcached_add_by_key(&memc, master_key, strlen(master_key), | ||
110 | 94 | key, strlen(key), | ||
111 | 95 | value, value_length, | ||
112 | 96 | 0, 0); | ||
113 | 97 | } | ||
114 | 98 | |||
115 | 99 | memcached_return replace(const char *key, const char *value, | ||
116 | 100 | size_t value_length) | ||
117 | 101 | { | ||
118 | 102 | return memcached_replace(&memc, key, strlen(key), | ||
119 | 103 | value, value_length, | ||
120 | 104 | 0, 0); | ||
121 | 105 | } | ||
122 | 106 | memcached_return replace_by_key(const char *master_key, const char *key, | ||
123 | 107 | const char *value, size_t value_length) | ||
124 | 108 | { | ||
125 | 109 | return memcached_replace_by_key(&memc, master_key, strlen(master_key), | ||
126 | 110 | key, strlen(key), | ||
127 | 111 | value, value_length, 0, 0); | ||
128 | 112 | } | ||
129 | 113 | |||
130 | 114 | memcached_return prepend(const char *key, const char *value, | ||
131 | 115 | size_t value_length) | ||
132 | 116 | { | ||
133 | 117 | return memcached_prepend(&memc, key, strlen(key), | ||
134 | 118 | value, value_length, 0, 0); | ||
135 | 119 | } | ||
136 | 120 | memcached_return prepend_by_key(const char *master_key, const char *key, | ||
137 | 121 | const char *value, size_t value_length) | ||
138 | 122 | { | ||
139 | 123 | return memcached_prepend_by_key(&memc, master_key, strlen(master_key), | ||
140 | 124 | key, strlen(key), | ||
141 | 125 | value, value_length, | ||
142 | 126 | 0, | ||
143 | 127 | 0); | ||
144 | 128 | } | ||
145 | 129 | |||
146 | 130 | memcached_return append(const char *key, const char *value, | ||
147 | 131 | size_t value_length) | ||
148 | 132 | { | ||
149 | 133 | return memcached_append(&memc, key, strlen(key), | ||
150 | 134 | value, value_length, 0, 0); | ||
151 | 135 | } | ||
152 | 136 | memcached_return append_by_key(const char *master_key, const char *key, | ||
153 | 137 | const char *value, size_t value_length) | ||
154 | 138 | { | ||
155 | 139 | return memcached_append_by_key(&memc, | ||
156 | 140 | master_key, strlen(master_key), | ||
157 | 141 | key, strlen(key), | ||
158 | 142 | value, value_length, 0, 0); | ||
159 | 143 | } | ||
160 | 144 | memcached_return cas(const char *key, const char *value, | ||
161 | 145 | size_t value_length, uint64_t cas_arg) | ||
162 | 146 | { | ||
163 | 147 | return memcached_cas(&memc, key, strlen(key), | ||
164 | 148 | value, value_length, 0, 0, cas_arg); | ||
165 | 149 | } | ||
166 | 150 | memcached_return cas_by_key(const char *master_key, const char *key, | ||
167 | 151 | const char *value, size_t value_length, | ||
168 | 152 | uint64_t cas_arg) | ||
169 | 153 | { | ||
170 | 154 | return memcached_cas_by_key(&memc, | ||
171 | 155 | master_key, strlen(master_key), | ||
172 | 156 | key, strlen(key), | ||
173 | 157 | value, value_length, | ||
174 | 158 | 0, 0, cas_arg); | ||
175 | 159 | } | ||
176 | 160 | // using 'remove' vs. 'delete' since 'delete' is a keyword | ||
177 | 161 | memcached_return remove(const char *key) | ||
178 | 162 | { | ||
179 | 163 | return memcached_delete (&memc, key, strlen(key), 0); | ||
180 | 164 | |||
181 | 165 | } | ||
182 | 166 | memcached_return delete_by_key(const char *master_key, const char *key) | ||
183 | 167 | { | ||
184 | 168 | return memcached_delete_by_key(&memc, master_key, strlen(master_key), | ||
185 | 169 | key, strlen(key), 0); | ||
186 | 170 | } | ||
188 | 171 | ~Memcached() | 26 | ~Memcached() |
189 | 172 | { | 27 | { |
190 | 173 | memcached_free(&memc); | 28 | memcached_free(&memc); |
191 | 174 | } | 29 | } |
192 | 30 | |||
193 | 31 | bool fetch(std::string &key, | ||
194 | 32 | std::string &ret_val, | ||
195 | 33 | size_t *key_length, | ||
196 | 34 | size_t *value_length, | ||
197 | 35 | uint32_t *flags, | ||
198 | 36 | memcached_return *rc) | ||
199 | 37 | { | ||
200 | 38 | char ret_key[MEMCACHED_MAX_KEY]; | ||
201 | 39 | char *value= memcached_fetch(&memc, ret_key, key_length, | ||
202 | 40 | value_length, flags, rc); | ||
203 | 41 | if (value) | ||
204 | 42 | { | ||
205 | 43 | ret_val.assign(value); | ||
206 | 44 | key.assign(ret_key); | ||
207 | 45 | return true; | ||
208 | 46 | } | ||
209 | 47 | return false; | ||
210 | 48 | } | ||
211 | 49 | |||
212 | 50 | std::string get(const std::string &key, size_t *value_length) | ||
213 | 51 | { | ||
214 | 52 | uint32_t flags; | ||
215 | 53 | memcached_return rc; | ||
216 | 54 | std::string ret_val; | ||
217 | 55 | |||
218 | 56 | char *value= memcached_get(&memc, key.c_str(), key.length(), | ||
219 | 57 | value_length, &flags, &rc); | ||
220 | 58 | if (value) | ||
221 | 59 | { | ||
222 | 60 | ret_val.assign(value); | ||
223 | 61 | } | ||
224 | 62 | return ret_val; | ||
225 | 63 | } | ||
226 | 64 | |||
227 | 65 | std::string get_by_key(const std::string &master_key, | ||
228 | 66 | const std::string &key, | ||
229 | 67 | size_t *value_length) | ||
230 | 68 | { | ||
231 | 69 | uint32_t flags; | ||
232 | 70 | memcached_return rc; | ||
233 | 71 | std::string ret_val; | ||
234 | 72 | |||
235 | 73 | char *value= memcached_get_by_key(&memc, master_key.c_str(), master_key.length(), | ||
236 | 74 | key.c_str(), key.length(), | ||
237 | 75 | value_length, &flags, &rc); | ||
238 | 76 | if (value) | ||
239 | 77 | { | ||
240 | 78 | ret_val.assign(value); | ||
241 | 79 | } | ||
242 | 80 | return ret_val; | ||
243 | 81 | } | ||
244 | 82 | |||
245 | 83 | bool mget(std::vector<std::string> &keys) | ||
246 | 84 | { | ||
247 | 85 | /* | ||
248 | 86 | * Construct an array which will contain the length | ||
249 | 87 | * of each of the strings in the input vector. Also, to | ||
250 | 88 | * interface with the memcached C API, we need to convert | ||
251 | 89 | * the vector of std::string's to a vector of char *. | ||
252 | 90 | */ | ||
253 | 91 | size_t *key_len= static_cast<size_t *>(malloc(keys.size() * sizeof(size_t))); | ||
254 | 92 | if (key_len == NULL) | ||
255 | 93 | { | ||
256 | 94 | return false; | ||
257 | 95 | } | ||
258 | 96 | std::vector<char *> real_keys; | ||
259 | 97 | std::vector<std::string>::iterator it= keys.begin(); | ||
260 | 98 | int i= 0; | ||
261 | 99 | while (it != keys.end()) | ||
262 | 100 | { | ||
263 | 101 | real_keys.push_back(const_cast<char *>((*it).c_str())); | ||
264 | 102 | key_len[i++]= (*it).length(); | ||
265 | 103 | ++it; | ||
266 | 104 | } | ||
267 | 105 | |||
268 | 106 | /* | ||
269 | 107 | * If the std::vector of keys is empty then we cannot | ||
270 | 108 | * call memcached_mget as we will get undefined behavior. | ||
271 | 109 | */ | ||
272 | 110 | if (!real_keys.empty()) | ||
273 | 111 | { | ||
274 | 112 | memcached_return rc= memcached_mget(&memc, &real_keys[0], key_len, | ||
275 | 113 | static_cast<unsigned int>(real_keys.size())); | ||
276 | 114 | return (rc == MEMCACHED_SUCCESS); | ||
277 | 115 | } | ||
278 | 116 | |||
279 | 117 | return false; | ||
280 | 118 | } | ||
281 | 119 | |||
282 | 120 | bool set(const std::string &key, | ||
283 | 121 | const std::string &value, | ||
284 | 122 | time_t expiration, | ||
285 | 123 | uint32_t flags) | ||
286 | 124 | { | ||
287 | 125 | memcached_return rc= memcached_set(&memc, | ||
288 | 126 | key.c_str(), key.length(), | ||
289 | 127 | value.c_str(), value.length(), | ||
290 | 128 | expiration, flags); | ||
291 | 129 | return (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED); | ||
292 | 130 | } | ||
293 | 131 | |||
294 | 132 | bool set_all(std::vector<std::string> &keys, | ||
295 | 133 | std::vector<std::string> &values, | ||
296 | 134 | time_t expiration, | ||
297 | 135 | uint32_t flags) | ||
298 | 136 | { | ||
299 | 137 | if (keys.size() != values.size()) | ||
300 | 138 | { | ||
301 | 139 | return false; | ||
302 | 140 | } | ||
303 | 141 | bool retval= true; | ||
304 | 142 | std::vector<std::string>::iterator key_it= keys.begin(); | ||
305 | 143 | std::vector<std::string>::iterator val_it= values.begin(); | ||
306 | 144 | while (key_it != keys.end()) | ||
307 | 145 | { | ||
308 | 146 | retval= set((*key_it), (*val_it), expiration, flags); | ||
309 | 147 | if (retval == false) | ||
310 | 148 | { | ||
311 | 149 | return retval; | ||
312 | 150 | } | ||
313 | 151 | ++key_it; | ||
314 | 152 | ++val_it; | ||
315 | 153 | } | ||
316 | 154 | return retval; | ||
317 | 155 | } | ||
318 | 156 | |||
319 | 157 | bool set_by_key(const std::string &master_key, | ||
320 | 158 | const std::string &key, | ||
321 | 159 | const std::string &value, | ||
322 | 160 | time_t expiration, | ||
323 | 161 | uint32_t flags) | ||
324 | 162 | { | ||
325 | 163 | memcached_return rc= memcached_set_by_key(&memc, master_key.c_str(), | ||
326 | 164 | master_key.length(), | ||
327 | 165 | key.c_str(), key.length(), | ||
328 | 166 | value.c_str(), value.length(), | ||
329 | 167 | expiration, | ||
330 | 168 | flags); | ||
331 | 169 | return (rc == MEMCACHED_SUCCESS); | ||
332 | 170 | } | ||
333 | 171 | |||
334 | 172 | bool increment(const std::string &key, unsigned int offset, uint64_t *value) | ||
335 | 173 | { | ||
336 | 174 | memcached_return rc= memcached_increment(&memc, key.c_str(), key.length(), | ||
337 | 175 | offset, value); | ||
338 | 176 | return (rc == MEMCACHED_SUCCESS); | ||
339 | 177 | } | ||
340 | 178 | |||
341 | 179 | bool decrement(const std::string &key, unsigned int offset, uint64_t *value) | ||
342 | 180 | { | ||
343 | 181 | memcached_return rc= memcached_decrement(&memc, key.c_str(), | ||
344 | 182 | key.length(), | ||
345 | 183 | offset, value); | ||
346 | 184 | return (rc == MEMCACHED_SUCCESS); | ||
347 | 185 | } | ||
348 | 186 | |||
349 | 187 | |||
350 | 188 | bool add(const std::string &key, const std::string &value) | ||
351 | 189 | { | ||
352 | 190 | memcached_return rc= memcached_add(&memc, key.c_str(), key.length(), | ||
353 | 191 | value.c_str(), value.length(), 0, 0); | ||
354 | 192 | return (rc == MEMCACHED_SUCCESS); | ||
355 | 193 | } | ||
356 | 194 | |||
357 | 195 | bool add_by_key(const std::string &master_key, | ||
358 | 196 | const std::string &key, | ||
359 | 197 | const std::string &value) | ||
360 | 198 | { | ||
361 | 199 | memcached_return rc= memcached_add_by_key(&memc, | ||
362 | 200 | master_key.c_str(), | ||
363 | 201 | master_key.length(), | ||
364 | 202 | key.c_str(), | ||
365 | 203 | key.length(), | ||
366 | 204 | value.c_str(), | ||
367 | 205 | value.length(), | ||
368 | 206 | 0, 0); | ||
369 | 207 | return (rc == MEMCACHED_SUCCESS); | ||
370 | 208 | } | ||
371 | 209 | |||
372 | 210 | bool replace(const std::string &key, const std::string &value) | ||
373 | 211 | { | ||
374 | 212 | memcached_return rc= memcached_replace(&memc, key.c_str(), key.length(), | ||
375 | 213 | value.c_str(), value.length(), | ||
376 | 214 | 0, 0); | ||
377 | 215 | return (rc == MEMCACHED_SUCCESS); | ||
378 | 216 | } | ||
379 | 217 | |||
380 | 218 | bool replace_by_key(const std::string &master_key, | ||
381 | 219 | const std::string &key, | ||
382 | 220 | const std::string &value) | ||
383 | 221 | { | ||
384 | 222 | memcached_return rc= memcached_replace_by_key(&memc, | ||
385 | 223 | master_key.c_str(), | ||
386 | 224 | master_key.length(), | ||
387 | 225 | key.c_str(), | ||
388 | 226 | key.length(), | ||
389 | 227 | value.c_str(), | ||
390 | 228 | value.length(), | ||
391 | 229 | 0, 0); | ||
392 | 230 | return (rc == MEMCACHED_SUCCESS); | ||
393 | 231 | } | ||
394 | 232 | |||
395 | 233 | bool prepend(const std::string &key, const std::string &value) | ||
396 | 234 | { | ||
397 | 235 | memcached_return rc= memcached_prepend(&memc, key.c_str(), key.length(), | ||
398 | 236 | value.c_str(), value.length(), 0, 0); | ||
399 | 237 | return (rc == MEMCACHED_SUCCESS); | ||
400 | 238 | } | ||
401 | 239 | |||
402 | 240 | bool prepend_by_key(const std::string &master_key, | ||
403 | 241 | const std::string &key, | ||
404 | 242 | const std::string &value) | ||
405 | 243 | { | ||
406 | 244 | memcached_return rc= memcached_prepend_by_key(&memc, | ||
407 | 245 | master_key.c_str(), | ||
408 | 246 | master_key.length(), | ||
409 | 247 | key.c_str(), | ||
410 | 248 | key.length(), | ||
411 | 249 | value.c_str(), | ||
412 | 250 | value.length(), | ||
413 | 251 | 0, | ||
414 | 252 | 0); | ||
415 | 253 | return (rc == MEMCACHED_SUCCESS); | ||
416 | 254 | } | ||
417 | 255 | |||
418 | 256 | bool append(const std::string &key, const std::string &value) | ||
419 | 257 | { | ||
420 | 258 | memcached_return rc= memcached_append(&memc, | ||
421 | 259 | key.c_str(), | ||
422 | 260 | key.length(), | ||
423 | 261 | value.c_str(), | ||
424 | 262 | value.length(), | ||
425 | 263 | 0, 0); | ||
426 | 264 | return (rc == MEMCACHED_SUCCESS); | ||
427 | 265 | } | ||
428 | 266 | |||
429 | 267 | bool append_by_key(const std::string &master_key, | ||
430 | 268 | const std::string &key, | ||
431 | 269 | const std::string &value) | ||
432 | 270 | { | ||
433 | 271 | memcached_return rc= memcached_append_by_key(&memc, | ||
434 | 272 | master_key.c_str(), | ||
435 | 273 | master_key.length(), | ||
436 | 274 | key.c_str(), | ||
437 | 275 | key.length(), | ||
438 | 276 | value.c_str(), | ||
439 | 277 | value.length(), | ||
440 | 278 | 0, 0); | ||
441 | 279 | return (rc == MEMCACHED_SUCCESS); | ||
442 | 280 | } | ||
443 | 281 | |||
444 | 282 | bool cas(const std::string &key, | ||
445 | 283 | const std::string &value, | ||
446 | 284 | uint64_t cas_arg) | ||
447 | 285 | { | ||
448 | 286 | memcached_return rc= memcached_cas(&memc, key.c_str(), key.length(), | ||
449 | 287 | value.c_str(), value.length(), | ||
450 | 288 | 0, 0, cas_arg); | ||
451 | 289 | return (rc == MEMCACHED_SUCCESS); | ||
452 | 290 | } | ||
453 | 291 | |||
454 | 292 | bool cas_by_key(const std::string &master_key, | ||
455 | 293 | const std::string &key, | ||
456 | 294 | const std::string &value, | ||
457 | 295 | uint64_t cas_arg) | ||
458 | 296 | { | ||
459 | 297 | memcached_return rc= memcached_cas_by_key(&memc, | ||
460 | 298 | master_key.c_str(), | ||
461 | 299 | master_key.length(), | ||
462 | 300 | key.c_str(), | ||
463 | 301 | key.length(), | ||
464 | 302 | value.c_str(), | ||
465 | 303 | value.length(), | ||
466 | 304 | 0, 0, cas_arg); | ||
467 | 305 | return (rc == MEMCACHED_SUCCESS); | ||
468 | 306 | } | ||
469 | 307 | |||
470 | 308 | // using 'remove' vs. 'delete' since 'delete' is a keyword | ||
471 | 309 | bool remove(const std::string &key) | ||
472 | 310 | { | ||
473 | 311 | memcached_return rc= memcached_delete(&memc, key.c_str(), key.length(), 0); | ||
474 | 312 | return (rc == MEMCACHED_SUCCESS); | ||
475 | 313 | } | ||
476 | 314 | |||
477 | 315 | bool delete_by_key(const std::string &master_key, | ||
478 | 316 | const std::string &key) | ||
479 | 317 | { | ||
480 | 318 | memcached_return rc= memcached_delete_by_key(&memc, | ||
481 | 319 | master_key.c_str(), | ||
482 | 320 | master_key.length(), | ||
483 | 321 | key.c_str(), | ||
484 | 322 | key.length(), | ||
485 | 323 | 0); | ||
486 | 324 | return (rc == MEMCACHED_SUCCESS); | ||
487 | 325 | } | ||
488 | 326 | |||
489 | 327 | bool flush(time_t expiration) | ||
490 | 328 | { | ||
491 | 329 | memcached_return rc= memcached_flush(&memc, expiration); | ||
492 | 330 | return (rc == MEMCACHED_SUCCESS); | ||
493 | 331 | } | ||
494 | 332 | |||
495 | 333 | bool fetch_execute(memcached_execute_function *callback, | ||
496 | 334 | void *context, | ||
497 | 335 | unsigned int num_of_callbacks) | ||
498 | 336 | { | ||
499 | 337 | memcached_return rc= memcached_fetch_execute(&memc, | ||
500 | 338 | callback, | ||
501 | 339 | context, | ||
502 | 340 | num_of_callbacks); | ||
503 | 341 | return (rc == MEMCACHED_SUCCESS); | ||
504 | 342 | } | ||
505 | 343 | |||
506 | 344 | const std::string lib_version() const | ||
507 | 345 | { | ||
508 | 346 | const char *ver= memcached_lib_version(); | ||
509 | 347 | const std::string version(ver); | ||
510 | 348 | return version; | ||
511 | 349 | } | ||
512 | 350 | |||
513 | 351 | private: | ||
514 | 352 | memcached_st memc; | ||
515 | 353 | memcached_result_st result; | ||
516 | 175 | }; | 354 | }; |
517 | 176 | 355 | ||
518 | === modified file 'tests/plus.cpp' | |||
519 | --- tests/plus.cpp 2009-07-07 21:57:24 +0000 | |||
520 | +++ tests/plus.cpp 2009-07-11 19:10:39 +0000 | |||
521 | @@ -16,87 +16,184 @@ | |||
522 | 16 | 16 | ||
523 | 17 | #include "test.h" | 17 | #include "test.h" |
524 | 18 | 18 | ||
525 | 19 | #include <string> | ||
526 | 20 | |||
527 | 21 | using namespace std; | ||
528 | 22 | |||
529 | 19 | extern "C" { | 23 | extern "C" { |
530 | 20 | test_return basic_test(memcached_st *memc); | ||
531 | 21 | uint8_t increment_test(memcached_st *memc); | ||
532 | 22 | test_return basic_master_key_test(memcached_st *memc); | ||
533 | 23 | void *world_create(void); | 24 | void *world_create(void); |
534 | 24 | void world_destroy(void *p); | 25 | void world_destroy(void *p); |
535 | 25 | } | 26 | } |
536 | 26 | 27 | ||
538 | 27 | test_return basic_test(memcached_st *memc) | 28 | static test_return basic_test(memcached_st *memc) |
539 | 28 | { | 29 | { |
540 | 29 | Memcached foo(memc); | 30 | Memcached foo(memc); |
543 | 30 | const char *value_set= "This is some data"; | 31 | const string value_set("This is some data"); |
544 | 31 | char *value; | 32 | string value; |
545 | 32 | size_t value_length; | 33 | size_t value_length; |
546 | 33 | 34 | ||
548 | 34 | foo.set("mine", value_set, strlen(value_set)); | 35 | foo.set("mine", value_set, 0, 0); |
549 | 35 | value= foo.get("mine", &value_length); | 36 | value= foo.get("mine", &value_length); |
550 | 36 | 37 | ||
552 | 37 | assert((memcmp(value, value_set, value_length) == 0)); | 38 | assert((memcmp(value.c_str(), value_set.c_str(), value_length) == 0)); |
553 | 38 | 39 | ||
554 | 39 | return TEST_SUCCESS; | 40 | return TEST_SUCCESS; |
555 | 40 | } | 41 | } |
556 | 41 | 42 | ||
558 | 42 | uint8_t increment_test(memcached_st *memc) | 43 | static test_return increment_test(memcached_st *memc) |
559 | 43 | { | 44 | { |
560 | 44 | Memcached mcach(memc); | 45 | Memcached mcach(memc); |
565 | 45 | memcached_return rc; | 46 | bool rc; |
566 | 46 | const char *key= "inctest"; | 47 | const string key("inctest"); |
567 | 47 | const char *inc_value= "1"; | 48 | const string inc_value("1"); |
568 | 48 | char *ret_value; | 49 | string ret_value; |
569 | 49 | uint64_t int_inc_value; | 50 | uint64_t int_inc_value; |
570 | 50 | uint64_t int_ret_value; | 51 | uint64_t int_ret_value; |
571 | 51 | size_t value_length; | 52 | size_t value_length; |
572 | 52 | 53 | ||
574 | 53 | mcach.set(key, inc_value, strlen(inc_value)); | 54 | mcach.set(key, inc_value, 0, 0); |
575 | 54 | ret_value= mcach.get(key, &value_length); | 55 | ret_value= mcach.get(key, &value_length); |
579 | 55 | printf("\nretvalue %s\n",ret_value); | 56 | printf("\nretvalue %s\n",ret_value.c_str()); |
580 | 56 | int_inc_value= uint64_t(atol(inc_value)); | 57 | int_inc_value= uint64_t(atol(inc_value.c_str())); |
581 | 57 | int_ret_value= uint64_t(atol(ret_value)); | 58 | int_ret_value= uint64_t(atol(ret_value.c_str())); |
582 | 58 | assert(int_ret_value == int_inc_value); | 59 | assert(int_ret_value == int_inc_value); |
583 | 59 | 60 | ||
584 | 60 | rc= mcach.increment(key, 1, &int_ret_value); | 61 | rc= mcach.increment(key, 1, &int_ret_value); |
586 | 61 | assert(rc == MEMCACHED_SUCCESS); | 62 | assert(rc == true); |
587 | 62 | assert(int_ret_value == 2); | 63 | assert(int_ret_value == 2); |
588 | 63 | 64 | ||
589 | 64 | rc= mcach.increment(key, 1, &int_ret_value); | 65 | rc= mcach.increment(key, 1, &int_ret_value); |
591 | 65 | assert(rc == MEMCACHED_SUCCESS); | 66 | assert(rc == true); |
592 | 66 | assert(int_ret_value == 3); | 67 | assert(int_ret_value == 3); |
593 | 67 | 68 | ||
594 | 68 | rc= mcach.increment(key, 5, &int_ret_value); | 69 | rc= mcach.increment(key, 5, &int_ret_value); |
596 | 69 | assert(rc == MEMCACHED_SUCCESS); | 70 | assert(rc == true); |
597 | 70 | assert(int_ret_value == 8); | 71 | assert(int_ret_value == 8); |
598 | 71 | 72 | ||
600 | 72 | return 0; | 73 | return TEST_SUCCESS; |
601 | 73 | } | 74 | } |
602 | 74 | 75 | ||
604 | 75 | test_return basic_master_key_test(memcached_st *memc) | 76 | static test_return basic_master_key_test(memcached_st *memc) |
605 | 76 | { | 77 | { |
612 | 77 | Memcached foo(memc); | 78 | Memcached foo(memc); |
613 | 78 | const char *value_set= "Data for server A"; | 79 | const string value_set("Data for server A"); |
614 | 79 | const char *master_key_a= "server-a"; | 80 | const string master_key_a("server-a"); |
615 | 80 | const char *master_key_b= "server-b"; | 81 | const string master_key_b("server-b"); |
616 | 81 | const char *key= "xyz"; | 82 | const string key("xyz"); |
617 | 82 | char *value; | 83 | string value; |
618 | 83 | size_t value_length; | 84 | size_t value_length; |
619 | 84 | 85 | ||
621 | 85 | foo.set_by_key(master_key_a, key, value_set, strlen(value_set)); | 86 | foo.set_by_key(master_key_a, key, value_set, 0, 0); |
622 | 86 | value= foo.get_by_key(master_key_a, key, &value_length); | 87 | value= foo.get_by_key(master_key_a, key, &value_length); |
623 | 87 | 88 | ||
625 | 88 | assert((memcmp(value, value_set, value_length) == 0)); | 89 | assert((memcmp(value.c_str(), value_set.c_str(), value_length) == 0)); |
626 | 89 | 90 | ||
627 | 90 | value= foo.get_by_key(master_key_b, key, &value_length); | 91 | value= foo.get_by_key(master_key_b, key, &value_length); |
633 | 91 | assert((memcmp(value, value_set, value_length) == 0)); | 92 | assert((memcmp(value.c_str(), value_set.c_str(), value_length) == 0)); |
634 | 92 | 93 | ||
635 | 93 | return TEST_SUCCESS; | 94 | return TEST_SUCCESS; |
636 | 94 | } | 95 | } |
637 | 95 | 96 | ||
638 | 97 | /* Count the results */ | ||
639 | 98 | static memcached_return callback_counter(memcached_st *ptr __attribute__((unused)), | ||
640 | 99 | memcached_result_st *result __attribute__((unused)), | ||
641 | 100 | void *context) | ||
642 | 101 | { | ||
643 | 102 | unsigned int *counter= static_cast<unsigned int *>(context); | ||
644 | 103 | |||
645 | 104 | *counter= *counter + 1; | ||
646 | 105 | |||
647 | 106 | return MEMCACHED_SUCCESS; | ||
648 | 107 | } | ||
649 | 108 | |||
650 | 109 | static test_return mget_result_function(memcached_st *memc) | ||
651 | 110 | { | ||
652 | 111 | Memcached mc(memc); | ||
653 | 112 | bool rc; | ||
654 | 113 | string key1("fudge"); | ||
655 | 114 | string key2("son"); | ||
656 | 115 | string key3("food"); | ||
657 | 116 | vector<string> keys; | ||
658 | 117 | keys.reserve(3); | ||
659 | 118 | keys.push_back(key1); | ||
660 | 119 | keys.push_back(key2); | ||
661 | 120 | keys.push_back(key3); | ||
662 | 121 | unsigned int counter; | ||
663 | 122 | memcached_execute_function callbacks[1]; | ||
664 | 123 | |||
665 | 124 | /* We need to empty the server before we continue the test */ | ||
666 | 125 | rc= mc.flush(0); | ||
667 | 126 | rc= mc.set_all(keys, keys, 50, 9); | ||
668 | 127 | assert(rc == true); | ||
669 | 128 | |||
670 | 129 | rc= mc.mget(keys); | ||
671 | 130 | assert(rc == true); | ||
672 | 131 | |||
673 | 132 | callbacks[0]= &callback_counter; | ||
674 | 133 | counter= 0; | ||
675 | 134 | rc= mc.fetch_execute(callbacks, static_cast<void *>(&counter), 1); | ||
676 | 135 | |||
677 | 136 | assert(counter == 3); | ||
678 | 137 | |||
679 | 138 | return TEST_SUCCESS; | ||
680 | 139 | } | ||
681 | 140 | |||
682 | 141 | static test_return mget_test(memcached_st *memc) | ||
683 | 142 | { | ||
684 | 143 | Memcached mc(memc); | ||
685 | 144 | bool rc; | ||
686 | 145 | memcached_return mc_rc; | ||
687 | 146 | vector<string> keys; | ||
688 | 147 | keys.reserve(3); | ||
689 | 148 | keys.push_back("fudge"); | ||
690 | 149 | keys.push_back("son"); | ||
691 | 150 | keys.push_back("food"); | ||
692 | 151 | uint32_t flags; | ||
693 | 152 | |||
694 | 153 | string return_key; | ||
695 | 154 | size_t return_key_length; | ||
696 | 155 | string return_value; | ||
697 | 156 | size_t return_value_length; | ||
698 | 157 | |||
699 | 158 | /* We need to empty the server before we continue the test */ | ||
700 | 159 | rc= mc.flush(0); | ||
701 | 160 | assert(rc == true); | ||
702 | 161 | |||
703 | 162 | rc= mc.mget(keys); | ||
704 | 163 | assert(rc == true); | ||
705 | 164 | |||
706 | 165 | while (mc.fetch(return_key, return_value, &return_key_length, | ||
707 | 166 | &return_value_length, &flags, &mc_rc)) | ||
708 | 167 | { | ||
709 | 168 | assert(return_value.length() != 0); | ||
710 | 169 | } | ||
711 | 170 | assert(return_value_length == 0); | ||
712 | 171 | assert(mc_rc == MEMCACHED_END); | ||
713 | 172 | |||
714 | 173 | rc= mc.set_all(keys, keys, 50, 9); | ||
715 | 174 | assert(rc == true); | ||
716 | 175 | |||
717 | 176 | rc= mc.mget(keys); | ||
718 | 177 | assert(rc == true); | ||
719 | 178 | |||
720 | 179 | while ((mc.fetch(return_key, return_value, &return_key_length, | ||
721 | 180 | &return_value_length, &flags, &mc_rc))) | ||
722 | 181 | { | ||
723 | 182 | assert(return_value.length() != 0); | ||
724 | 183 | assert(mc_rc == MEMCACHED_SUCCESS); | ||
725 | 184 | assert(return_key_length == return_value_length); | ||
726 | 185 | assert(!memcmp(return_value.c_str(), return_key.c_str(), return_value_length)); | ||
727 | 186 | } | ||
728 | 187 | |||
729 | 188 | return TEST_SUCCESS; | ||
730 | 189 | } | ||
731 | 96 | 190 | ||
732 | 97 | test_st tests[] ={ | 191 | test_st tests[] ={ |
735 | 98 | {"basic", 0, basic_test }, | 192 | { "basic", 0, basic_test }, |
736 | 99 | {"basic_master_key", 0, basic_master_key_test }, | 193 | { "basic_master_key", 0, basic_master_key_test }, |
737 | 194 | { "increment_test", 0, increment_test }, | ||
738 | 195 | { "mget", 1, mget_test }, | ||
739 | 196 | { "mget_result_function", 1, mget_result_function }, | ||
740 | 100 | {0, 0, 0} | 197 | {0, 0, 0} |
741 | 101 | }; | 198 | }; |
742 | 102 | 199 |
So I was thinking that when we actually port the memcached UDF's to Drizzle, we should use the libmemcached C++ interface since Drizzle is a C++ project. Thus, to enable that, I did some refactoring of the libmemcached C++ interface wrapper.
Basically, all I did was the following:
* replace parameters as char * with references to std::string
* use std::vector in places where arrays of pointers were being passed
* modified the return types of numerous API function to be bool instead of memcached_return
* added more test cases to the C++ API test file
I'm just proposing this for merging to get some feedback on the approach I've taken. I can easily keep the existing interface by just overloading those API functions if that is wanted.
-Padraig