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