developer's diary

最近はc#のエントリが多いです

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