static inline int si_getresult(siread *q, sv *v, int compare) { int rc; if (compare) { rc = sr_compare(q->r->scheme, sv_pointer(v), sv_size(v), q->key, q->keysize); if (ssunlikely(rc != 0)) return 0; } if (q->prefix) { rc = sr_compareprefix(q->r->scheme, q->prefix, q->prefixsize, sv_pointer(v), sv_size(v)); if (ssunlikely(! rc)) return 0; } if (ssunlikely(q->has)) return sv_lsn(v) > q->vlsn; if (ssunlikely(sv_is(v, SVDELETE))) return 2; rc = si_readdup(q, v); if (ssunlikely(rc == -1)) return -1; return 1; }
so *se_read(sedb *db, sedocument *o, sx *x, uint64_t vlsn, sicache *cache) { se *e = se_of(&db->o); uint64_t start = ss_utime(); /* prepare the key */ int auto_close = o->created <= 1; int rc = se_document_createkey(o); if (ssunlikely(rc == -1)) goto error; rc = se_document_validate_ro(o, &db->o); if (ssunlikely(rc == -1)) goto error; if (ssunlikely(! se_active(e))) goto error; sv vup; sv_init(&vup, &sv_vif, NULL, NULL); sedocument *ret = NULL; /* concurrent */ if (x && o->order == SS_EQ) { /* note: prefix is ignored during concurrent * index search */ int rc = sx_get(x, &db->coindex, &o->v, &vup); if (ssunlikely(rc == -1 || rc == 2 /* delete */)) goto error; if (rc == 1 && !sv_is(&vup, SVUPSERT)) { ret = (sedocument*)se_document_new(e, &db->o, &vup); if (sslikely(ret)) { ret->cold_only = o->cold_only; ret->created = 1; ret->orderset = 1; ret->flagset = 1; } else { sv_vunref(db->r, vup.v); } if (auto_close) so_destroy(&o->o); return &ret->o; } } else { sx_get_autocommit(&e->xm, &db->coindex); } /* prepare read cache */ int cachegc = 0; if (cache == NULL) { cachegc = 1; cache = si_cachepool_pop(&e->cachepool); if (ssunlikely(cache == NULL)) { if (vup.v) sv_vunref(db->r, vup.v); sr_oom(&e->error); goto error; } } sv_vref(o->v.v); /* do read */ siread rq; si_readopen(&rq, db->index, cache, o->order, vlsn, sv_pointer(&o->v), vup.v, o->prefix_copy, o->prefix_size, o->cold_only, 0, start); rc = si_read(&rq); si_readclose(&rq); /* prepare result */ if (rc == 1) { ret = (sedocument*)se_readresult(e, &rq); if (ret) o->prefix_copy = NULL; } /* cleanup */ if (o->v.v) sv_vunref(db->r, o->v.v); if (vup.v) sv_vunref(db->r, vup.v); if (ret == NULL && rq.result.v) sv_vunref(db->r, rq.result.v); if (cachegc && cache) si_cachepool_push(cache); if (auto_close) so_destroy(&o->o); return &ret->o; error: if (auto_close) so_destroy(&o->o); return NULL; }