業務で libmemcached を利用した小さなモジュールを作ることになった。このライブラリにはC++インタフェースも用意されているのでCとC++の両方で試してみる。
環境は CentOS 5.6 (x86_64) , gcc4.4, libmemcached-devel
* インストール
remiレポジトリから新しいバージョンを入れる
$ sudo yum install libmemcached-devel.x86_64 --enablerepo=remi
* 各基本操作(set, get, delete)を行う C版
[cpp]
// libmemcached_test.c
#include int main(void) { // 初期化 // set // get // delete // get // 解放 memcached_get 内で malloc が行われるので free で解放するのを忘れずに。また、key が存在しない場合は NOT FOUND が、memcachedに接続出来ない場合などは FAILURE が返る。 あと、libmemcachedは関係ないけど以下のような警告が出た場合は文字列の扱いを見直す必要がある。 どうやら gcc4.2 から(? 文字列の扱いに厳しくなっていて、const を付けるべき所はちゃんと付けないとだめらしい。見かけない警告だったので少し焦ったけど、そういえば会社の開発環境は gcc4.1 だったかもしれない。 次はC++インタフェースを使う。APIの使い方は libmmecached/memcached.hpp を読んで確認。 * 各基本操作(set, get, delete)を行う C++版 int main(void) { // set
#include
#include
#include
memcached_st *memc;
memcached_server_st *servers = NULL;
memcached_return rc;
const char* server_list = “localhost:11211”;
const char* key= “key”;
const char* value= “value”;
char* retval = NULL;
size_t len = 0;
time_t expire = 0;
uint32_t flags = 0;
memc = memcached_create(NULL);
servers = memcached_servers_parse(server_list);
rc = memcached_server_push(memc, servers);
memcached_server_list_free(servers); // すぐに解放してOK
if(rc == MEMCACHED_SUCCESS) {
printf(“added server successfully\n”);
} else {
printf(“couldn’t add server: %s\n”, memcached_strerror(memc, rc));
}
rc = memcached_set(memc, key, strlen(key), value, strlen(value), expire, flags);
if(rc == MEMCACHED_SUCCESS) {
printf(“key stored successfully\n”);
} else {
printf(“couldn’t store key: %s\n”, memcached_strerror(memc, rc));
}
retval = memcached_get(memc, key, strlen(key), &len, &flags, &rc);
if(rc == MEMCACHED_SUCCESS) {
printf(“key got successfully\n”);
printf(“value: %s\n”, retval);
} else {
printf(“couldn’t get key: %s\n”, memcached_strerror(memc, rc));
}
free(retval); // 忘れないように!!
rc = memcached_delete(memc, key, strlen(key), expire);
if(rc == MEMCACHED_SUCCESS) {
printf(“key deleted successfully\n”);
} else {
printf(“couldn’t delete key: %s\n”, memcached_strerror(memc, rc));
}
retval = memcached_get(memc, key, strlen(key), &len, &flags, &rc);
if(rc == MEMCACHED_SUCCESS) {
printf(“key got successfully\n”);
printf(“value: %s\n”, retval);
} else if(rc == MEMCACHED_NOTFOUND) { // keyが存在しない
printf(“couldn’t get key (not found): %s\n”, memcached_strerror(memc, rc));
} else if(rc == MEMCACHED_FAILURE) { // memcachedに接続できない
printf(“couldn’t get key (failure): %s\n”, memcached_strerror(memc, rc));
}
free(retval);
memcached_free(memc);
return 0;
}
[/cpp]
* コンパイル, 実行 (+ valgrindでメモリリークのチェック)
$ gcc44 -o -libmemcached_test libmemcached.c -L/usr/lib64 -lmemcached
$ valgrind ./libmemcached_test
==10510== Memcheck, a memory error detector
==10510== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==10510== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==10510== Command: ./libmemcached_test
==10510==
added server successfully
key stored successfully
key got successfully
value: value
key deleted successfully
couldn't get key (not found): NOT FOUND
==10510==
==10510== HEAP SUMMARY:
==10510== in use at exit: 0 bytes in 0 blocks
==10510== total heap usage: 54 allocs, 54 frees, 42,214 bytes allocated
==10510==
==10510== All heap blocks were freed -- no leaks are possible
==10510==
==10510== For counts of detected and suppressed errors, rerun with: -v
==10510== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
deprecated conversion from string constant to ‘char*’
[cpp]
#include
// ヘッダは memcached.h ではなく memcached.hpp を include
#include
using namespace std;
try {
// Memcache インスタンス生成
// 内部で memcached_create などが呼ばれて初期化処理が行われる
memcache::Memcache memc(“localhost:11211”);
string key = “mykey”;
string value_str = “myvalue”;
// value は std::string ではなく std::vector
vector
vector
time_t expire = 0;
uint32_t flags = 0;
// bool set(const std::string &key, const std::vector
// time_t expiration, uint32_t flags)
if(memc.set(key, value, expire, flags)) {
cout<<"key stored successfully"<
if(memc.get(key, retval)) {
cout<<"key got successfully"<