Example #1
0
static lcb_error_t
do_store3(lcb_t instance, const void *cookie,
    const lcb_CMDBASE *cmd, int is_durstore)
{
    mc_PIPELINE *pipeline;
    mc_PACKET *packet;
    mc_REQDATA *rdata;
    mc_CMDQUEUE *cq = &instance->cmdq;
    int hsize;
    int should_compress = 0;
    lcb_error_t err;

    lcb_storage_t operation;
    lcb_U32 flags;
    const lcb_VALBUF *vbuf;
    lcb_datatype_t datatype;

    protocol_binary_request_set scmd;
    protocol_binary_request_header *hdr = &scmd.message.header;

    if (!is_durstore) {
        const lcb_CMDSTORE *simple_cmd = (const lcb_CMDSTORE *)cmd;
        operation = simple_cmd->operation;
        flags = simple_cmd->flags;
        vbuf = &simple_cmd->value;
        datatype = simple_cmd->datatype;
    } else {
        const lcb_CMDSTOREDUR *durcmd = (const lcb_CMDSTOREDUR *)cmd;
        operation = durcmd->operation;
        flags = durcmd->flags;
        vbuf = &durcmd->value;
        datatype = durcmd->datatype;
    }

    if (LCB_KEYBUF_IS_EMPTY(&cmd->key)) {
        return LCB_EMPTY_KEY;
    }

    err = get_esize_and_opcode(
        operation, &hdr->request.opcode, &hdr->request.extlen);
    if (err != LCB_SUCCESS) {
        return err;
    }

    switch (operation) {
    case LCB_APPEND:
    case LCB_PREPEND:
        if (cmd->exptime || flags) {
            return LCB_OPTIONS_CONFLICT;
        }
        break;
    case LCB_ADD:
        if (cmd->cas) {
            return LCB_OPTIONS_CONFLICT;
        }
        break;
    default:
        break;
    }

    hsize = hdr->request.extlen + sizeof(*hdr);

    err = mcreq_basic_packet(cq, (const lcb_CMDBASE *)cmd, hdr,
        hdr->request.extlen, &packet, &pipeline, MCREQ_BASICPACKET_F_FALLBACKOK);

    if (err != LCB_SUCCESS) {
        return err;
    }

    should_compress = can_compress(instance, pipeline, vbuf, datatype);
    if (should_compress) {
        int rv = mcreq_compress_value(pipeline, packet, &vbuf->u_buf.contig);
        if (rv != 0) {
            mcreq_release_packet(pipeline, packet);
            return LCB_CLIENT_ENOMEM;
        }
    } else {
        mcreq_reserve_value(pipeline, packet, vbuf);
    }

    if (is_durstore) {
        int duropts = 0;
        lcb_U16 persist_u , replicate_u;
        const lcb_CMDSTOREDUR *dcmd = (const lcb_CMDSTOREDUR *)cmd;
        DURSTORECTX *dctx = calloc(1, sizeof(*dctx));

        persist_u = dcmd->persist_to;
        replicate_u = dcmd->replicate_to;
        if (dcmd->replicate_to == -1 || dcmd->persist_to == -1) {
            duropts = LCB_DURABILITY_VALIDATE_CAPMAX;
        }

        err = lcb_durability_validate(instance, &persist_u, &replicate_u, duropts);
        if (err != LCB_SUCCESS) {
            mcreq_wipe_packet(pipeline, packet);
            mcreq_release_packet(pipeline, packet);
            return err;
        }

        dctx->instance = instance;
        dctx->persist_to = persist_u;
        dctx->replicate_to = replicate_u;
        packet->u_rdata.exdata = &dctx->base;
        packet->flags |= MCREQ_F_REQEXT;

        dctx->base.cookie = cookie;
        dctx->base.procs = &storedur_procs;
    }

    rdata = MCREQ_PKT_RDATA(packet);
    rdata->cookie = cookie;
    rdata->start = gethrtime();

    scmd.message.body.expiration = htonl(cmd->exptime);
    scmd.message.body.flags = htonl(flags);
    hdr->request.magic = PROTOCOL_BINARY_REQ;
    hdr->request.cas = cmd->cas;
    hdr->request.datatype = PROTOCOL_BINARY_RAW_BYTES;

    if (should_compress || (datatype & LCB_VALUE_F_SNAPPYCOMP)) {
        hdr->request.datatype |= PROTOCOL_BINARY_DATATYPE_COMPRESSED;
    }
    if (datatype & LCB_VALUE_F_JSON) {
        hdr->request.datatype |= PROTOCOL_BINARY_DATATYPE_JSON;
    }

    hdr->request.opaque = packet->opaque;
    hdr->request.bodylen = htonl(
            hdr->request.extlen + ntohs(hdr->request.keylen)
            + get_value_size(packet));

    memcpy(SPAN_BUFFER(&packet->kh_span), scmd.bytes, hsize);
    mcreq_sched_add(pipeline, packet);
    TRACE_STORE_BEGIN(hdr, (lcb_CMDSTORE* )cmd);
    return LCB_SUCCESS;
}
Example #2
0
LIBCOUCHBASE_API
lcb_error_t
lcb_store3(lcb_t instance, const void *cookie, const lcb_CMDSTORE *cmd)
{
    mc_PIPELINE *pipeline;
    mc_PACKET *packet;
    mc_REQDATA *rdata;
    mc_CMDQUEUE *cq = &instance->cmdq;
    int hsize;
    int should_compress = 0;
    lcb_error_t err;

    protocol_binary_request_set scmd;
    protocol_binary_request_header *hdr = &scmd.message.header;

    if (LCB_KEYBUF_IS_EMPTY(&cmd->key)) {
        return LCB_EMPTY_KEY;
    }

    err = get_esize_and_opcode(
            cmd->operation, &hdr->request.opcode, &hdr->request.extlen);
    if (err != LCB_SUCCESS) {
        return err;
    }

    hsize = hdr->request.extlen + sizeof(*hdr);

    err = mcreq_basic_packet(cq, (const lcb_CMDBASE *)cmd, hdr,
        hdr->request.extlen, &packet, &pipeline, MCREQ_BASICPACKET_F_FALLBACKOK);

    if (err != LCB_SUCCESS) {
        return err;
    }

    should_compress = can_compress(instance, pipeline, cmd);
    if (should_compress) {
        int rv = mcreq_compress_value(pipeline, packet, &cmd->value.u_buf.contig);
        if (rv != 0) {
            mcreq_release_packet(pipeline, packet);
            return LCB_CLIENT_ENOMEM;
        }
    } else {
        mcreq_reserve_value(pipeline, packet, &cmd->value);
    }

    rdata = &packet->u_rdata.reqdata;
    rdata->cookie = cookie;
    rdata->start = gethrtime();

    scmd.message.body.expiration = htonl(cmd->exptime);
    scmd.message.body.flags = htonl(cmd->flags);
    hdr->request.magic = PROTOCOL_BINARY_REQ;
    hdr->request.cas = cmd->cas;
    hdr->request.datatype = PROTOCOL_BINARY_RAW_BYTES;

    if (should_compress || (cmd->datatype & LCB_VALUE_F_SNAPPYCOMP)) {
        hdr->request.datatype |= PROTOCOL_BINARY_DATATYPE_COMPRESSED;
    }
    if (cmd->datatype & LCB_VALUE_F_JSON) {
        hdr->request.datatype |= PROTOCOL_BINARY_DATATYPE_JSON;
    }

    hdr->request.opaque = packet->opaque;
    hdr->request.bodylen = htonl(
            hdr->request.extlen + ntohs(hdr->request.keylen)
            + get_value_size(packet));

    memcpy(SPAN_BUFFER(&packet->kh_span), scmd.bytes, hsize);
    mcreq_sched_add(pipeline, packet);
    TRACE_STORE_BEGIN(hdr, cmd);
    return LCB_SUCCESS;
}