C初心者がmemcached-1.4.5を追いかける。(25)
C初心者がmemcached-1.4.5を追いかける。(24)の続き
ソースはコチラにてDLしました。
getoptで受け取ったパラメータによって処理を行っている部分を追いかける。
memcached.c(4416行目あたり)
case 'C' : settings.use_cas = false; break;
"C" /* Disable use of CAS */
settings.use_casをfalseに設定
settings.use_cas のデフォルトはtrue memcached.c(177行目あたり)
static void settings_init(void) { settings.use_cas = true;
CオプションはどうもCAS(Compare and Swap)を無効にするオプションなよう。
第4回 memcachedのCASとmixiでの運用動向|gihyo.jp … 技術評論社に詳しく書いてある。
CASは更新カウントとか更新フラグとか更新バージョンとか更新日時のようなもの。楽観的ロックを実装するための実装っぽい。
ITEM_set_casとITEM_get_casをgrepするとそれらしいロジックが出てくる。
#ITEM_set_cas items.c(301): ITEM_set_cas(it, (settings.use_cas) ? get_cas_id() : 0); memcached.c(1889): ITEM_set_cas(it, c->binary_header.request.cas); memcached.c(1949): ITEM_set_cas(it, c->binary_header.request.cas); memcached.c(2751): ITEM_set_cas(it, req_cas_id); memcached.c(2870): ITEM_set_cas(it, (settings.use_cas) ? get_cas_id() : 0); memcached.h(82): #define ITEM_set_cas(i,v) { if *1; memcached.c(1193): rsp->message.header.response.cas = htonll(ITEM_get_cas(it)); memcached.c(1905): if (ITEM_get_cas(it) != 0) { memcached.c(2014): if (cas == 0 || cas == ITEM_get_cas(it)) { memcached.c(2127): else if (ITEM_get_cas(it) == ITEM_get_cas(old_it)) { memcached.c(2144): (unsigned long long)ITEM_get_cas(old_it), memcached.c(2145): (unsigned long long)ITEM_get_cas(it)); memcached.c(2158): if (ITEM_get_cas(it) != 0) { memcached.c(2160): if (ITEM_get_cas(it) != ITEM_get_cas(old_it)) { memcached.c(2202): c->cas = ITEM_get_cas(it); memcached.c(2214): c->cas = ITEM_get_cas(it); memcached.c(2569): it->nbytes, ITEM_get_cas(it)); memcached.c(2592): (unsigned long long)ITEM_get_cas(it)); memcached.c(2606): it->nbytes, ITEM_get_cas(it)); memcached.h(80): #define ITEM_get_cas(i) ((uint64_t)(((i)->it_flags & ITEM_CAS) ? \
memcached.c(2160)とかそのまんまかも。
/* * Validate CAS */ if (ITEM_get_cas(it) != 0) { // CAS much be equal if (ITEM_get_cas(it) != ITEM_get_cas(old_it)) { stored = EXISTS; } }
ちなみにITEM_set_casとITEM_get_casはヘッダファイルに定義されているマクロ関数。
memcached.h(82行目あたり)
/* warning: don't use these macros with a function, as it evals its arg twice */ #define ITEM_get_cas(i) ((uint64_t)(((i)->it_flags & ITEM_CAS) ? \ *(uint64_t*)&((i)->end[0]) : 0x0)) #define ITEM_set_cas(i,v) { if ((i)->it_flags & ITEM_CAS) { \ *(uint64_t*)&((i)->end[0]) = v; } }
続きは↓
C初心者がmemcached-1.4.5を追いかける。(26)(bオプション)へ
*1:i)->it_flags & ITEM_CAS) { \ #ITEM_get_cas memcached.c(805): uint64_t cas = ITEM_get_cas(it); memcached.c(1023): c->binary_header.request.cas == ITEM_get_cas(it))) { memcached.c(1044): c->cas = ITEM_get_cas(it); memcached.c(1061): c->cas = ITEM_get_cas(it); memcached.c(1107): uint64_t cas = ITEM_get_cas(it); memcached.c(1186): it->nbytes, ITEM_get_cas(it