예제 #1
0
파일: process.c 프로젝트: sagar0/pelikan
static void
_process_get(struct response *rsp, struct request *req)
{
    struct bstring *key;
    struct response *r = rsp;
    uint32_t i;

    INCR(process_metrics, get);
    /* use chained responses, move to the next response if key is found. */
    for (i = 0; i < array_nelem(req->keys); ++i) {
        INCR(process_metrics, get_key);
        key = array_get(req->keys, i);
        if (_get_key(r, key)) {
            req->nfound++;
            r->cas = false;
            r = STAILQ_NEXT(r, next);
            if (r == NULL) {
                INCR(process_metrics, get_ex);
                log_warn("get response incomplete due to lack of rsp objects");
                return;
            }
            INCR(process_metrics, get_key_hit);
        } else {
            INCR(process_metrics, get_key_miss);
        }
    }
    r->type = RSP_END;

    log_verb("get req %p processed, %d out of %d keys found", req, req->nfound, i);
}
예제 #2
0
static inline void
_klog_write_get(struct request *req, struct response *rsp, char *buf, int len)
{
    struct response *nr = rsp;
    int suffix_len;
    uint32_t i;
    struct bstring *key;

    for (i = 0; i < array_nelem(req->keys); ++i) {
        key = array_get(req->keys, i);

        if (nr->type != RSP_END && bstring_compare(key, &nr->key) == 0) {
            /* key was found, rsp at nr */
            suffix_len = cc_scnprintf(buf + len, KLOG_MAX_LEN - len, KLOG_GET_FMT,
                                      req_strings[req->type].len, req_strings[req->type].data,
                                      key->len, key->data, rsp->type, _get_val_rsp_len(nr, key));
            nr = STAILQ_NEXT(nr, next);
        } else {
            /* key not found */
            suffix_len = cc_scnprintf(buf + len, KLOG_MAX_LEN - len, KLOG_GET_FMT,
                                      req_strings[req->type].len, req_strings[req->type].data,
                                      key->len, key->data, RSP_UNKNOWN, 0);
        }

        ASSERT(len + suffix_len <= KLOG_MAX_LEN);

        if (log_write(klogger, buf, len + suffix_len)) {
            INCR(klog_metrics, klog_logged);
        } else {
            INCR(klog_metrics, klog_discard);
        }
    }

    ASSERT(nr ->type == RSP_END);
}
예제 #3
0
파일: compose.c 프로젝트: sagar0/pelikan
int
compose_req(struct buf **buf, struct request *req)
{
    request_type_t type = req->type;
    struct bstring *str = &req_strings[type];
    struct bstring *key = req->keys->data;
    int noreply_len = req->noreply * NOREPLY_LEN;
    int cas_len = (req->type == REQ_CAS) ? CC_UINT64_MAXLEN : 0;
    uint32_t i;
    int sz, n = 0;

    switch (type) {
    case REQ_FLUSH:
    case REQ_QUIT:
        if (_check_buf_size(buf, str->len) != COMPOSE_OK) {
            goto error;
        }
        n += _write_bstring(buf, str);
        break;

    case REQ_GET:
    case REQ_GETS:
        for (i = 0, sz = 0; i < array_nelem(req->keys); i++) {
            key = array_get(req->keys, i);
            sz += 1 + key->len;
        }
        if (_check_buf_size(buf, str->len + sz + CRLF_LEN) != COMPOSE_OK) {
            goto error;
        }
        n += _write_bstring(buf, str);
        for (i = 0; i < array_nelem(req->keys); i++) {
            n += _delim(buf);
            n += _write_bstring(buf, (struct bstring *)array_get(req->keys, i));
        }
        n += _crlf(buf);
        break;

    case REQ_DELETE:
        if (_check_buf_size(buf, str->len + key->len + noreply_len + CRLF_LEN)
                != COMPOSE_OK) {
            goto error;
        }
        n += _write_bstring(buf, str);
        n += _write_bstring(buf, key);
        if (req->noreply) {
            n += _noreply(buf);
        }
        n += _crlf(buf);
        break;

    case REQ_SET:
    case REQ_ADD:
    case REQ_REPLACE:
    case REQ_APPEND:
    case REQ_PREPEND:
    case REQ_CAS:
        /* here we may overestimate the size of message header because we
         * estimate the int size based on max value
         */
        if (_check_buf_size(buf, str->len + key->len + CC_UINT32_MAXLEN * 3 +
                    cas_len + req->vstr.len + noreply_len + CRLF_LEN * 2)
                != COMPOSE_OK) {
            goto error;
        }
        n += _write_bstring(buf, str);
        n += _write_bstring(buf, key);
        n += _delim(buf);
        n += _write_uint64(buf, req->flag);
        n += _delim(buf);
        n += _write_uint64(buf, req->expiry);
        n += _delim(buf);
        n += _write_uint64(buf, req->vstr.len);
        if (type == REQ_CAS) {
            n += _delim(buf);
            n += _write_uint64(buf, req->vcas);
        }
        if (req->noreply) {
            n += _noreply(buf);
        }
        n += _crlf(buf);
        n += _write_bstring(buf, &req->vstr);
        n += _crlf(buf);
        break;

    case REQ_INCR:
    case REQ_DECR:
        if (_check_buf_size(buf, str->len + key->len + CC_UINT64_MAXLEN +
                    noreply_len + CRLF_LEN) != COMPOSE_OK) {
            goto error;
        }
        n += _write_bstring(buf, str);
        n += _write_bstring(buf, key);
        n += _delim(buf);
        n += _write_uint64(buf, req->delta);
        if (req->noreply) {
            n += _noreply(buf);
        }
        n += _crlf(buf);
        break;

    default:
        NOT_REACHED();
        break;
    }

    INCR(compose_req_metrics, request_compose);

    return n;

error:
    INCR(compose_req_metrics, request_compose_ex);

    return COMPOSE_ENOMEM;
}
예제 #4
0
int main(void)
{
    array a;
    size_t i, nelem = 10000;
    void *dummy;

    /* First a growable array */
    if ((a = array_new(nelem / 10, 1)) == NULL) {
        perror("array_new");
        return 1;
    }

    for (i = 0; i < nelem; i++) {
        dummy = (void*)(i+1);
        if (!array_add(a, dummy)) {
            perror("array_add");
            return 1;
        }
    }

    if (array_nelem(a) != nelem) {
        fprintf(stderr, "Mismatch between number of actual and expected items\n");
        return 1;
    }

    for (i = 0; i < nelem; i++) {
        if (array_get(a, i) == NULL) {
            fprintf(stderr, "Could not get array item %lu\n", (unsigned long)i);
            return 1;
        }
    }

    array_free(a, NULL);

    /* Now for a non-growable array */
    if ((a = array_new(nelem / 10, 0)) == NULL) {
        perror("array_new");
        return 1;
    }

    for (i = 0; i < nelem / 10; i++) {
        dummy = (void*)(i+1);
        if (!array_add(a, dummy)) {
            perror("array_add");
            return 1;
        }
    }

    /* Now we've filled all slots, the next call should fail */
    if (array_add(a, dummy) != 0) {
        fprintf(stderr, "Able to add to array which is full!\n");
        return 1;
    }

    if (array_nelem(a) != nelem / 10) {
        fprintf(stderr, "Mismatch between number of actual and expected items\n");
        return 1;
    }

    for (i = 0; i < nelem / 10; i++) {
        if (array_get(a, i) == NULL) {
            fprintf(stderr, "Could not get array item %lu\n", (unsigned long)i);
            return 1;
        }
    }

    array_free(a, NULL);
    return 0;
}