int lcbvb_map_key(lcbvb_CONFIG *cfg, const void *key, lcb_SIZE nkey, int *vbid, int *srvix) { if (cfg->dtype == LCBVB_DIST_KETAMA) { *srvix = map_ketama(cfg, key, nkey); *vbid = 0; return 0; } else { *vbid = lcbvb_k2vb(cfg, key, nkey); *srvix = lcbvb_vbmaster(cfg, *vbid); } return 0; }
LIBCOUCHBASE_API lcb_error_t lcb_rget3(lcb_t instance, const void *cookie, const lcb_CMDGETREPLICA *cmd) { /** * Because we need to direct these commands to specific servers, we can't * just use the 'basic_packet()' function. */ mc_CMDQUEUE *cq = &instance->cmdq; const void *hk; lcb_size_t nhk; int vbid; protocol_binary_request_header req; unsigned r0, r1; rget_cookie *rck = NULL; if (LCB_KEYBUF_IS_EMPTY(&cmd->key)) { return LCB_EMPTY_KEY; } mcreq_extract_hashkey(&cmd->key, &cmd->hashkey, MCREQ_PKT_BASESIZE, &hk, &nhk); vbid = lcbvb_k2vb(cq->config, hk, nhk); /** Get the vbucket by index */ if (cmd->strategy == LCB_REPLICA_SELECT) { r0 = r1 = cmd->index; } else if (cmd->strategy == LCB_REPLICA_ALL) { r0 = 0; r1 = instance->nreplicas; } else { /* first */ r0 = r1 = 0; } if (r1 < r0 || r1 >= cq->npipelines) { return LCB_NO_MATCHING_SERVER; } /* Initialize the cookie */ rck = calloc(1, sizeof(*rck)); rck->base.cookie = cookie; rck->base.start = gethrtime(); rck->base.callback = rget_callback; rck->strategy = cmd->strategy; rck->r_cur = r0; rck->r_max = instance->nreplicas; rck->instance = instance; rck->vbucket = vbid; /* Initialize the packet */ req.request.magic = PROTOCOL_BINARY_REQ; req.request.opcode = PROTOCOL_BINARY_CMD_GET_REPLICA; req.request.datatype = PROTOCOL_BINARY_RAW_BYTES; req.request.vbucket = htons((lcb_uint16_t)vbid); req.request.cas = 0; req.request.extlen = 0; req.request.keylen = htons((lcb_uint16_t)cmd->key.contig.nbytes); req.request.bodylen = htonl((lcb_uint32_t)cmd->key.contig.nbytes); do { int curix; mc_PIPELINE *pl; mc_PACKET *pkt; curix = lcbvb_vbreplica(cq->config, vbid, r0); if (curix == -1) { return LCB_NO_MATCHING_SERVER; } pl = cq->pipelines[curix]; pkt = mcreq_allocate_packet(pl); if (!pkt) { return LCB_CLIENT_ENOMEM; } pkt->u_rdata.exdata = &rck->base; pkt->flags |= MCREQ_F_REQEXT; mcreq_reserve_key(pl, pkt, sizeof(req.bytes), &cmd->key); req.request.opaque = pkt->opaque; rck->remaining++; mcreq_write_hdr(pkt, &req); mcreq_sched_add(pl, pkt); } while (++r0 < r1); return LCB_SUCCESS; }
static lcb_error_t obs_ctxadd(lcb_MULTICMD_CTX *mctx, const lcb_CMDOBSERVE *cmd) { const void *hk; lcb_SIZE nhk; int vbid; unsigned maxix; int ii; OBSERVECTX *ctx = CTX_FROM_MULTI(mctx); lcb_t instance = ctx->instance; mc_CMDQUEUE *cq = &instance->cmdq; if (LCB_KEYBUF_IS_EMPTY(&cmd->key)) { return LCB_EMPTY_KEY; } if (cq->config == NULL) { return LCB_CLIENT_ETMPFAIL; } if (LCBVB_DISTTYPE(LCBT_VBCONFIG(instance)) != LCBVB_DIST_VBUCKET) { return LCB_NOT_SUPPORTED; } mcreq_extract_hashkey(&cmd->key, &cmd->_hashkey, 24, &hk, &nhk); vbid = lcbvb_k2vb(cq->config, hk, nhk); maxix = LCBVB_NREPLICAS(cq->config); for (ii = -1; ii < (int)maxix; ++ii) { struct observe_st *rr; lcb_U16 vb16, klen16; int ix; if (ii == -1) { ix = lcbvb_vbmaster(cq->config, vbid); if (ix < 0) { return LCB_NO_MATCHING_SERVER; } } else { ix = lcbvb_vbreplica(cq->config, vbid, ii); if (ix < 0) { continue; } } lcb_assert(ix < (int)ctx->nrequests); rr = ctx->requests + ix; if (!rr->allocated) { if (!init_request(rr)) { return LCB_CLIENT_ENOMEM; } } vb16 = htons((lcb_U16)vbid); klen16 = htons((lcb_U16)cmd->key.contig.nbytes); lcb_string_append(&rr->body, &vb16, sizeof vb16); lcb_string_append(&rr->body, &klen16, sizeof klen16); lcb_string_append(&rr->body, cmd->key.contig.bytes, cmd->key.contig.nbytes); ctx->remaining++; if (cmd->cmdflags & LCB_CMDOBSERVE_F_MASTER_ONLY) { break; } } return LCB_SUCCESS; }
LIBCOUCHBASE_API int vbucket_get_vbucket_by_key(lcbvb_CONFIG *cfg, const void *k, lcb_SIZE nk) { return lcbvb_k2vb(cfg, k, nk); }