⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memcached.c

📁 memcached是一个高性能的分布式的内存对象缓存系统
💻 C
📖 第 1 页 / 共 5 页
字号:
        struct mallinfo info;        char *pos = temp;        info = mallinfo();        pos += sprintf(pos, "STAT arena_size %d\r\n", info.arena);        pos += sprintf(pos, "STAT free_chunks %d\r\n", info.ordblks);        pos += sprintf(pos, "STAT fastbin_blocks %d\r\n", info.smblks);        pos += sprintf(pos, "STAT mmapped_regions %d\r\n", info.hblks);        pos += sprintf(pos, "STAT mmapped_space %d\r\n", info.hblkhd);        pos += sprintf(pos, "STAT max_total_alloc %d\r\n", info.usmblks);        pos += sprintf(pos, "STAT fastbin_space %d\r\n", info.fsmblks);        pos += sprintf(pos, "STAT total_alloc %d\r\n", info.uordblks);        pos += sprintf(pos, "STAT total_free %d\r\n", info.fordblks);        pos += sprintf(pos, "STAT releasable_space %d\r\nEND", info.keepcost);        out_string(c, temp);        return;    }#endif /* HAVE_STRUCT_MALLINFO */#endif /* HAVE_MALLOC_H */    if (strcmp(subcommand, "maps") == 0) {        char *wbuf;        int wsize = 8192; /* should be enough */        int fd;        int res;        if (!(wbuf = (char *)malloc(wsize))) {            out_string(c, "SERVER_ERROR out of memory");            return;        }        fd = open("/proc/self/maps", O_RDONLY);        if (fd == -1) {            out_string(c, "SERVER_ERROR cannot open the maps file");            free(wbuf);            return;        }        res = read(fd, wbuf, wsize - 6);  /* 6 = END\r\n\0 */        if (res == wsize - 6) {            out_string(c, "SERVER_ERROR buffer overflow");            free(wbuf); close(fd);            return;        }        if (res == 0 || res == -1) {            out_string(c, "SERVER_ERROR can't read the maps file");            free(wbuf); close(fd);            return;        }        memcpy(wbuf + res, "END\r\n", 6);        c->write_and_free = wbuf;        c->wcurr = wbuf;        c->wbytes = res + 5; // Don't write the terminal '\0'        conn_set_state(c, conn_write);        c->write_and_go = conn_read;        close(fd);        return;    }    if (strcmp(subcommand, "cachedump") == 0) {        char *buf;        unsigned int bytes, id, limit = 0;        if(ntokens < 5) {            out_string(c, "CLIENT_ERROR bad command line");            return;        }        id = strtoul(tokens[2].value, NULL, 10);        limit = strtoul(tokens[3].value, NULL, 10);        if(errno == ERANGE) {            out_string(c, "CLIENT_ERROR bad command line format");            return;        }        buf = item_cachedump(id, limit, &bytes);        if (buf == 0) {            out_string(c, "SERVER_ERROR out of memory");            return;        }        c->write_and_free = buf;        c->wcurr = buf;        c->wbytes = bytes;        conn_set_state(c, conn_write);        c->write_and_go = conn_read;        return;    }    if (strcmp(subcommand, "slabs") == 0) {        int bytes = 0;        char *buf = slabs_stats(&bytes);        if (!buf) {            out_string(c, "SERVER_ERROR out of memory");            return;        }        c->write_and_free = buf;        c->wcurr = buf;        c->wbytes = bytes;        conn_set_state(c, conn_write);        c->write_and_go = conn_read;        return;    }    if (strcmp(subcommand, "items") == 0) {        char buffer[4096];        item_stats(buffer, 4096);        out_string(c, buffer);        return;    }    if (strcmp(subcommand, "detail") == 0) {        if (ntokens < 4)            process_stats_detail(c, "");  /* outputs the error message */        else            process_stats_detail(c, tokens[2].value);        return;    }    if (strcmp(subcommand, "sizes") == 0) {        int bytes = 0;        char *buf = item_stats_sizes(&bytes);        if (! buf) {            out_string(c, "SERVER_ERROR out of memory");            return;        }        c->write_and_free = buf;        c->wcurr = buf;        c->wbytes = bytes;        conn_set_state(c, conn_write);        c->write_and_go = conn_read;        return;    }    out_string(c, "ERROR");}/* ntokens is overwritten here... shrug.. */static inline void process_get_command(conn *c, token_t *tokens, size_t ntokens) {    char *key;    size_t nkey;    int i = 0;    item *it;    token_t *key_token = &tokens[KEY_TOKEN];    assert(c != NULL);    if (settings.managed) {        int bucket = c->bucket;        if (bucket == -1) {            out_string(c, "CLIENT_ERROR no BG data in managed mode");            return;        }        c->bucket = -1;        if (buckets[bucket] != c->gen) {            out_string(c, "ERROR_NOT_OWNER");            return;        }    }    do {        while(key_token->length != 0) {            key = key_token->value;            nkey = key_token->length;            if(nkey > KEY_MAX_LENGTH) {                out_string(c, "CLIENT_ERROR bad command line format");                return;            }            STATS_LOCK();            stats.get_cmds++;            STATS_UNLOCK();            it = item_get(key, nkey);            if (settings.detail_enabled) {                stats_prefix_record_get(key, NULL != it);            }            if (it) {                if (i >= c->isize) {                    item **new_list = realloc(c->ilist, sizeof(item *) * c->isize * 2);                    if (new_list) {                        c->isize *= 2;                        c->ilist = new_list;                    } else break;                }                /*                 * Construct the response. Each hit adds three elements to the                 * outgoing data list:                 *   "VALUE "                 *   key                 *   " " + flags + " " + data length + "\r\n" + data (with \r\n)                 */                if (add_iov(c, "VALUE ", 6) != 0 ||                    add_iov(c, ITEM_key(it), it->nkey) != 0 ||                    add_iov(c, ITEM_suffix(it), it->nsuffix + it->nbytes) != 0)                    {                        break;                    }                if (settings.verbose > 1)                    fprintf(stderr, ">%d sending key %s\n", c->sfd, ITEM_key(it));                /* item_get() has incremented it->refcount for us */                STATS_LOCK();                stats.get_hits++;                STATS_UNLOCK();                item_update(it);                *(c->ilist + i) = it;                i++;            } else {                STATS_LOCK();                stats.get_misses++;                STATS_UNLOCK();            }            key_token++;        }        /*         * If the command string hasn't been fully processed, get the next set         * of tokens.         */        if(key_token->value != NULL) {            ntokens = tokenize_command(key_token->value, tokens, MAX_TOKENS);            key_token = tokens;        }    } while(key_token->value != NULL);    c->icurr = c->ilist;    c->ileft = i;    if (settings.verbose > 1)        fprintf(stderr, ">%d END\n", c->sfd);    add_iov(c, "END\r\n", 5);    if (c->udp && build_udp_headers(c) != 0) {        out_string(c, "SERVER_ERROR out of memory");    }    else {        conn_set_state(c, conn_mwrite);        c->msgcurr = 0;    }    return;}static void process_update_command(conn *c, token_t *tokens, const size_t ntokens, int comm) {    char *key;    size_t nkey;    int flags;    time_t exptime;    int vlen;    item *it;    assert(c != NULL);    if (tokens[KEY_TOKEN].length > KEY_MAX_LENGTH) {        out_string(c, "CLIENT_ERROR bad command line format");        return;    }    key = tokens[KEY_TOKEN].value;    nkey = tokens[KEY_TOKEN].length;    flags = strtoul(tokens[2].value, NULL, 10);    exptime = strtol(tokens[3].value, NULL, 10);    vlen = strtol(tokens[4].value, NULL, 10);    if(errno == ERANGE || ((flags == 0 || exptime == 0) && errno == EINVAL)) {        out_string(c, "CLIENT_ERROR bad command line format");        return;    }    if (settings.detail_enabled) {        stats_prefix_record_set(key);    }    if (settings.managed) {        int bucket = c->bucket;        if (bucket == -1) {            out_string(c, "CLIENT_ERROR no BG data in managed mode");            return;        }        c->bucket = -1;        if (buckets[bucket] != c->gen) {            out_string(c, "ERROR_NOT_OWNER");            return;        }    }    it = item_alloc(key, nkey, flags, realtime(exptime), vlen+2);    if (it == 0) {        if (! item_size_ok(nkey, flags, vlen + 2))            out_string(c, "SERVER_ERROR object too large for cache");        else            out_string(c, "SERVER_ERROR out of memory");        /* swallow the data line */        c->write_and_go = conn_swallow;        c->sbytes = vlen + 2;        return;    }    c->item_comm = comm;    c->item = it;    c->ritem = ITEM_data(it);    c->rlbytes = it->nbytes;    conn_set_state(c, conn_nread);}static void process_arithmetic_command(conn *c, token_t *tokens, const size_t ntokens, const int incr) {    char temp[32];    item *it;    unsigned int delta;    char *key;    size_t nkey;    assert(c != NULL);    if(tokens[KEY_TOKEN].length > KEY_MAX_LENGTH) {        out_string(c, "CLIENT_ERROR bad command line format");        return;    }    key = tokens[KEY_TOKEN].value;    nkey = tokens[KEY_TOKEN].length;    if (settings.managed) {        int bucket = c->bucket;        if (bucket == -1) {            out_string(c, "CLIENT_ERROR no BG data in managed mode");            return;        }        c->bucket = -1;        if (buckets[bucket] != c->gen) {            out_string(c, "ERROR_NOT_OWNER");            return;        }    }    delta = strtoul(tokens[2].value, NULL, 10);    if(errno == ERANGE) {        out_string(c, "CLIENT_ERROR bad command line format");        return;    }    it = item_get(key, nkey);    if (!it) {        out_string(c, "NOT_FOUND");        return;    }    out_string(c, add_delta(it, incr, delta, temp));    item_remove(it);         /* release our reference */}/* * adds a delta value to a numeric item. * * it    item to adjust * incr  true to increment value, false to decrement * delta amount to adjust value by * buf   buffer for response string * * returns a response string to send back to the client. */char *do_add_delta(item *it, int incr, unsigned int delta, char *buf) {    char *ptr;    unsigned int value;    int res;    ptr = ITEM_data(it);    while ((*ptr != '\0') && (*ptr < '0' && *ptr > '9')) ptr++;    // BUG: can't be true    value = strtol(ptr, NULL, 10);    if(errno == ERANGE) {        return "CLIENT_ERROR cannot increment or decrement non-numeric value";    }    if (incr != 0)        value += delta;    else {        if (delta >= value) value = 0;        else value -= delta;    }    snprintf(buf, 32, "%u", value);    res = strlen(buf);    if (res + 2 > it->nbytes) { /* need to realloc */        item *new_it;        new_it = do_item_alloc(ITEM_key(it), it->nkey, atoi(ITEM_suffix(it) + 1), it->exptime, res + 2 );        if (new_it == 0) {            return "SERVER_ERROR out of memory";        }        memcpy(ITEM_data(new_it), buf, res);        memcpy(ITEM_data(new_it) + res, "\r\n", 3);        do_item_replace(it, new_it);        do_item_remove(new_it);       /* release our reference */    } else { /* replace in-place */        memcpy(ITEM_data(it), buf, res);        memset(ITEM_data(it) + res, ' ', it->nbytes - res - 2);    }    return buf;}static void process_delete_command(conn *c, token_t *tokens, const size_t ntokens) {    char *key;    size_t nkey;    item *it;    time_t exptime = 0;    assert(c != NULL);    if (settings.managed) {        int bucket = c->bucket;        if (bucket == -1) {            out_string(c, "CLIENT_ERROR no BG data in managed mode");            return;        }        c->bucket = -1;        if (buckets[bucket] != c->gen) {            out_string(c, "ERROR_NOT_OWNER");            return;        }    }    key = tokens[KEY_TOKEN].value;    nkey = tokens[KEY_TOKEN].length;    if(nkey > KEY_MAX_LENGTH) {        out_string(c, "CLIENT_ERROR bad command line format");        return;    }    if(ntokens == 4) {        exptime = strtol(tokens[2].value, NULL, 10);        if(errno == ERANGE) {            out_string(c, "CLIENT_ERROR bad command line format");            return;        }    }    if (settings.detail_enabled) {        stats_prefix_record_delete(key);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -