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; }
void lcbdur_update_item(lcb_DURITEM *item, int flags, int srvix) { lcbdur_SERVINFO *info; lcb_t instance; int is_master; const mc_SERVER *server; if (!flags || item->done) { return; } info = lcbdur_ent_getinfo(item, srvix); if (!info) { lcb_log(LOGARGS(item->parent, DEBUG), "Ignoring response from server %d. Not a master or replica for vBucket %d", srvix, item->vbid); return; } instance = item->parent->instance; is_master = lcbvb_vbmaster(LCBT_VBCONFIG(instance), item->vbid) == srvix; server = LCBT_GET_SERVER(instance, srvix); memset(info, 0, sizeof(*info)); info->server = server; if (flags & LCBDUR_UPDATE_PERSISTED) { info->persisted = 1; RESFLD(item, npersisted)++; if (is_master) { RESFLD(item, persisted_master) = 1; } } if (flags & LCBDUR_UPDATE_REPLICATED) { info->exists = 1; if (is_master) { RESFLD(item, exists_master) = 1; } else { RESFLD(item, nreplicated)++; } } if (lcbdur_ent_check_done(item)) { RESFLD(item, rc) = LCB_SUCCESS; lcbdur_ent_finish(item); } }
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; }
static void H_observe(mc_PIPELINE *pipeline, mc_PACKET *request, packet_info *response, lcb_error_t immerr) { lcb_t root = pipeline->parent->cqdata; uint32_t ttp; uint32_t ttr; lcb_size_t pos; lcbvb_CONFIG* config; const char *end, *ptr; mc_REQDATAEX *rd = request->u_rdata.exdata; lcb_RESPOBSERVE resp = { 0 }; MK_ERROR(root, &resp, response, immerr); if (resp.rc != LCB_SUCCESS) { if (! (request->flags & MCREQ_F_INVOKED)) { rd->procs->handler(pipeline, request, resp.rc, NULL); } return; } /** The CAS field is split into TTP/TTR values */ ptr = (char *)&response->res.response.cas; memcpy(&ttp, ptr, sizeof(ttp)); memcpy(&ttr, ptr + sizeof(ttp), sizeof(ttp)); ttp = ntohl(ttp); ttr = ntohl(ttr); /** Actual payload sequence of (vb, nkey, key). Repeats multiple times */ ptr = response->payload; end = (char *)ptr + PACKET_NBODY(response); config = pipeline->parent->config; for (pos = 0; ptr < end; pos++) { lcb_cas_t cas; lcb_uint8_t obs; lcb_uint16_t nkey, vb; const char *key; memcpy(&vb, ptr, sizeof(vb)); vb = ntohs(vb); ptr += sizeof(vb); memcpy(&nkey, ptr, sizeof(nkey)); nkey = ntohs(nkey); ptr += sizeof(nkey); key = (const char *)ptr; ptr += nkey; obs = *((lcb_uint8_t *)ptr); ptr += sizeof(obs); memcpy(&cas, ptr, sizeof(cas)); ptr += sizeof(cas); resp.key = key; resp.nkey = nkey; resp.cas = cas; resp.status = obs; resp.ismaster = pipeline->index == lcbvb_vbmaster(config, vb); resp.ttp = 0; resp.ttr = 0; TRACE_OBSERVE_PROGRESS(response, &resp); if (! (request->flags & MCREQ_F_INVOKED)) { rd->procs->handler(pipeline, request, resp.rc, &resp); } } TRACE_OBSERVE_END(response); }
LIBCOUCHBASE_API int vbucket_get_master(lcbvb_CONFIG *cfg, int vb) { return lcbvb_vbmaster(cfg, vb); }