static inline int se_txwrite(setx *t, sev *o, uint8_t flags) { se *e = se_of(&t->o); sedb *db = se_cast(o->o.parent, sedb*, SEDB); /* validate req */ if (ssunlikely(t->t.state == SXPREPARE)) { sr_error(&e->error, "%s", "transaction is in 'prepare' state (read-only)"); goto error; } /* validate database status */ int status = se_status(&db->status); switch (status) { case SE_SHUTDOWN: if (ssunlikely(! se_dbvisible(db, t->t.id))) { sr_error(&e->error, "%s", "database is invisible for the transaction"); goto error; } break; case SE_RECOVER: case SE_ONLINE: break; default: goto error; } if (flags == SVUPDATE && !sf_updatehas(&db->scheme.fmt_update)) flags = 0; /* prepare object */ svv *v; int rc = se_dbv(db, o, 0, &v); if (ssunlikely(rc == -1)) goto error; v->flags = flags; v->log = o->log; sv vp; sv_init(&vp, &sv_vif, v, NULL); so_destroy(&o->o); /* ensure quota */ int size = sizeof(svv) + sv_size(&vp); ss_quota(&e->quota, SS_QADD, size); /* concurrent index only */ rc = sx_set(&t->t, &db->coindex, v); if (ssunlikely(rc == -1)) { ss_quota(&e->quota, SS_QREMOVE, size); return -1; } return 0; error: so_destroy(&o->o); return -1; }
static int se_complete(sescheduler *s, setask *t) { ss_mutexlock(&s->lock); sedb *db = t->db; if (db) se_dbunref(db, 1); switch (t->plan.plan) { case SI_BRANCH: case SI_AGE: case SI_CHECKPOINT: s->workers_branch--; break; case SI_BACKUP: case SI_BACKUPEND: s->workers_backup--; break; case SI_GC: s->workers_gc--; break; case SI_SHUTDOWN: case SI_DROP: s->workers_gc_db--; so_destroy(&db->o); break; } if (t->rotate == 1) s->rotate = 0; if (t->req) s->req = 0; ss_mutexunlock(&s->lock); return 0; }
static inline int se_txwrite(setx *t, sedocument *o, uint8_t flags) { se *e = se_of(&t->o); sedb *db = se_cast(o->o.parent, sedb*, SEDB); int auto_close = o->created <= 1; /* validate database status */ if (ssunlikely(! se_active(e))) goto error; /* ensure memory quota */ int rc; rc = sr_quota(&e->quota, &e->stat); if (ssunlikely(rc)) { sr_error(&e->error, "%s", "memory quota limit reached"); goto error; } /* create document */ rc = se_document_create(o); if (ssunlikely(rc == -1)) goto error; rc = se_document_validate(o, &db->o, flags); if (ssunlikely(rc == -1)) goto error; svv *v = o->v.v; sv_vref(v); v->log = o->log; /* destroy document object */ if (auto_close) so_destroy(&o->o); /* concurrent index only */ rc = sx_set(&t->t, &db->coindex, v); if (ssunlikely(rc == -1)) return -1; return 0; error: if (auto_close) so_destroy(&o->o); return -1; }
void web_node_destroy(WEB_NODE* web_node) { web_node_free(web_node, web_node->root); so_destroy(&web_node->items); }
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; }