developer's diary

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

C初心者がmemcached-1.4.5を追いかける。(28)

C初心者がmemcached-1.4.5を追いかける。(27)の続き
ソースはコチラにてDLしました。

getoptで受け取ったパラメータによって処理を行っている部分を追いかける。

memcached.c(4436行目あたり)

        case 'I':
            unit = optarg[strlen(optarg)-1];
            if (unit == 'k' || unit == 'm' ||
                unit == 'K' || unit == 'M') {
                optarg[strlen(optarg)-1] = '\0';
                size_max = atoi(optarg);
                if (unit == 'k' || unit == 'K')
                    size_max *= 1024;
                if (unit == 'm' || unit == 'M')
                    size_max *= 1024 * 1024;
                settings.item_size_max = size_max;
            } else {
                settings.item_size_max = atoi(optarg);
            }
            if (settings.item_size_max < 1024) {
                fprintf(stderr, "Item max size cannot be less than 1024 bytes.\n");
                return 1;
            }
            if (settings.item_size_max > 1024 * 1024 * 128) {
                fprintf(stderr, "Cannot set item size limit higher than 128 mb.\n");
                return 1;
            }
            if (settings.item_size_max > 1024 * 1024) {
                fprintf(stderr, "WARNING: Setting item max size above 1MB is not"
                    " recommended!\n"
                    " Raising this limit increases the minimum memory requirements\n"
                    " and will decrease your memory efficiency.\n"
                );
            }
            break;
          "I:"  /* Max item size */

今回はIオプションの部分

unit = optarg[strlen(optarg)-1];で引数の最後の文字をunitに入れている

            unit = optarg[strlen(optarg)-1];
            if (unit == 'k' || unit == 'm' ||
                unit == 'K' || unit == 'M') {
                optarg[strlen(optarg)-1] = '\0';
                size_max = atoi(optarg);
                if (unit == 'k' || unit == 'K')
                    size_max *= 1024;
                if (unit == 'm' || unit == 'M')
                    size_max *= 1024 * 1024;
                settings.item_size_max = size_max;
            } else {
                settings.item_size_max = atoi(optarg);
            }

最後の文字が、
'k' or 'K' の場合、残りの文字に1024を掛けてKbyteのバイト数をsettings.item_size_maxに設定
'm' or 'M' の場合、残りの文字に1024*1024を行いMbyteのバイト数をsettings.item_size_maxに設定
最後の文字が上記意外の場合直接settings.item_size_maxに設定している

残りのif文で入力値のチェックを行っている。
・1024未満の場合エラー
・128MBを越える場合エラー
・!MBを越える場合ワーニング

            if (settings.item_size_max < 1024) {
                fprintf(stderr, "Item max size cannot be less than 1024 bytes.\n");
                return 1;
            }
            if (settings.item_size_max > 1024 * 1024 * 128) {
                fprintf(stderr, "Cannot set item size limit higher than 128 mb.\n");
                return 1;
            }
            if (settings.item_size_max > 1024 * 1024) {
                fprintf(stderr, "WARNING: Setting item max size above 1MB is not"
                    " recommended!\n"
                    " Raising this limit increases the minimum memory requirements\n"
                    " and will decrease your memory efficiency.\n"
                );
            }

settings.item_size_max のデフォルトは1MB

    settings.item_size_max = 1024 * 1024; /* The famous 1MB upper limit. */

使用箇所は
slabs_init関数(slabs.c)の中

slabs.c:119:    while (++i < POWER_LARGEST && size <= settings.item_size_max / factor) {
slabs.c:125:        slabclass[i].perslab = settings.item_size_max / slabclass[i].size;
slabs.c:134:    slabclass[power_largest].size = settings.item_size_max;