sxstate sx_set_autocommit(sxmanager *m, sxindex *index, sx *x, svlog *log, svv *v) { if (sslikely(m->count_rw == 0)) { sx_init(m, x, log); svlogv lv; lv.index_id = index->dsn; lv.next = UINT32_MAX; lv.v = v; lv.ptr = NULL; sv_logadd(x->log, index->r, &lv); sr_seq(index->r->seq, SR_TSNNEXT); sx_promote(x, SX_COMMIT); return SX_COMMIT; } sx_begin(m, x, SX_RW, log, 0); int rc = sx_set(x, index, v); if (ssunlikely(rc == -1)) { sx_rollback(x); return SX_ROLLBACK; } sxstate s = sx_prepare(x, NULL, NULL); switch (s) { case SX_PREPARE: s = sx_commit(x); break; case SX_LOCK: s = sx_rollback(x); break; case SX_ROLLBACK: break; default: assert(0); } return s; }
sxstate sx_set_autocommit(sxmanager *m, sxindex *index, sx *x, svv *v) { if (sslikely(m->count_rw == 0)) { sx_init(m, x); svlogv lv; lv.id = index->dsn; lv.next = UINT32_MAX; sv_init(&lv.v, &sv_vif, v, NULL); sv_logadd(&x->log, m->r->a, &lv, index->ptr); sr_seq(m->r->seq, SR_TSNNEXT); return SXCOMMIT; } sx_begin(m, x, SXRW, 0); int rc = sx_set(x, index, v); if (ssunlikely(rc == -1)) { sx_rollback(x); return SXROLLBACK; } sxstate s = sx_prepare(x, NULL, NULL); if (sslikely(s == SXPREPARE)) sx_commit(x); else if (s == SXLOCK) sx_rollback(x); return s; }
static void alloclogv(svlog *log, sr *r, uint64_t lsn, uint8_t flags, int key) { sfv pv; pv.key = (char*)&key; pv.r.size = sizeof(uint32_t); pv.r.offset = 0; svv *v = sv_vbuild(r, &pv, 1, NULL, 0); v->lsn = lsn; v->flags = flags; svlogv logv; logv.id = 0; logv.next = 0; sv_init(&logv.v, &sv_vif, v, NULL); sv_logadd(log, r->a, &logv, NULL); }
static void alloclogv(svlog *log, sr *r, uint8_t flags, int key) { sfv pv[2]; pv[0].pointer = (char*)&key; pv[0].size = sizeof(uint32_t); pv[1].pointer = NULL; pv[1].size = 0; svv *v = sv_vbuild(r, pv); v->flags = flags; svlogv logv; logv.id = 0; logv.next = 0; sv_init(&logv.v, &sv_vif, v, NULL); sv_logadd(log, r->a, &logv, NULL); }
int sx_set(sx *x, sxindex *index, svv *version) { sxmanager *m = x->manager; sr *r = m->r; if (! (version->flags & SVGET)) { x->log_read = -1; } /* allocate mvcc container */ sxv *v = sx_valloc(m->asxv, version); if (ssunlikely(v == NULL)) { ss_quota(r->quota, SS_QREMOVE, sv_vsize(version)); sv_vfree(r, version); return -1; } v->id = x->id; v->index = index; svlogv lv; lv.id = index->dsn; lv.next = UINT32_MAX; sv_init(&lv.v, &sx_vif, v, NULL); /* update concurrent index */ ssrbnode *n = NULL; int rc = sx_match(&index->i, index->r->scheme, sv_vpointer(version), version->size, &n); if (ssunlikely(rc == 0 && n)) { /* exists */ } else { int pos = rc; /* unique */ v->lo = sv_logcount(&x->log); rc = sv_logadd(&x->log, r->a, &lv, index->ptr); if (ssunlikely(rc == -1)) { sr_oom(r->e); goto error; } ss_rbset(&index->i, n, pos, &v->node); return 0; } sxv *head = sscast(n, sxv, node); /* match previous update made by current * transaction */ sxv *own = sx_vmatch(head, x->id); if (ssunlikely(own)) { if (ssunlikely(version->flags & SVUPDATE)) { sr_error(r->e, "%s", "only one update statement is " "allowed per a transaction key"); goto error; } /* replace old document with the new one */ lv.next = sv_logat(&x->log, own->lo)->next; v->lo = own->lo; if (ssunlikely(sx_vaborted(own))) sx_vabort(v); sx_vreplace(own, v); if (sslikely(head == own)) ss_rbreplace(&index->i, &own->node, &v->node); /* update log */ sv_logreplace(&x->log, v->lo, &lv); ss_quota(r->quota, SS_QREMOVE, sv_vsize(own->v)); sx_vfree(r, m->asxv, own); return 0; } /* update log */ v->lo = sv_logcount(&x->log); rc = sv_logadd(&x->log, r->a, &lv, index->ptr); if (ssunlikely(rc == -1)) { sr_oom(r->e); goto error; } /* add version */ sx_vlink(head, v); return 0; error: ss_quota(r->quota, SS_QREMOVE, sv_vsize(v->v)); sx_vfree(r, m->asxv, v); return -1; }
int sx_set(sx *x, sxindex *index, svv *version) { sxmanager *m = x->manager; sr *r = index->r; svlogv lv; lv.index_id = index->dsn; lv.next = UINT32_MAX; lv.v = version; lv.ptr = NULL; /* allocate mvcc container */ sxv *v = sx_valloc(&m->pool, version); if (ssunlikely(v == NULL)) { sv_vunref(r, version); return -1; } v->id = x->id; v->index = index; lv.ptr = v; if (! (sv_vflags(version, index->r) & SVGET)) x->log_read = -1; /* update concurrent index */ ssrbnode *n = NULL; int rc; rc = sx_match(&index->i, index->r->scheme, sv_vpointer(version), 0, &n); if (ssunlikely(rc == 0 && n)) { /* exists */ } else { int pos = rc; /* unique */ v->lo = sv_logcount(x->log); rc = sv_logadd(x->log, r, &lv); if (ssunlikely(rc == -1)) { sr_oom(r->e); goto error; } ss_rbset(&index->i, n, pos, &v->node); return 0; } sxv *head = sscast(n, sxv, node); /* match previous update made by current * transaction */ sxv *own = sx_vmatch(head, x->id); if (ssunlikely(own)) { if (ssunlikely(sv_vflags(version, index->r) & SVUPSERT)) { sr_error(r->e, "%s", "only one upsert statement is " "allowed per a transaction key"); goto error; } /* replace old document with the new one */ lv.next = sv_logat(x->log, own->lo)->next; v->lo = own->lo; if (ssunlikely(sx_vaborted(own))) sx_vabort(v); sx_vreplace(own, v); if (sslikely(head == own)) ss_rbreplace(&index->i, &own->node, &v->node); /* update log */ sv_logreplace(x->log, r, v->lo, &lv); sx_vfree(&m->pool, r, own); return 0; } /* update log */ v->lo = sv_logcount(x->log); rc = sv_logadd(x->log, r, &lv); if (ssunlikely(rc == -1)) { sr_oom(r->e); goto error; } /* add version */ sx_vlink(head, v); return 0; error: sx_vfree(&m->pool, r, v); return -1; }
int sx_set(sx *t, sxindex *index, svv *version) { sxmanager *m = t->manager; /* allocate mvcc container */ sxv *v = sx_valloc(m->asxv, version); if (ssunlikely(v == NULL)) { sv_vfree(m->a, version); return -1; } v->id = t->id; v->index = index; svlogv lv; lv.id = index->dsn; lv.vgc = NULL; lv.next = UINT32_MAX; sv_init(&lv.v, &sx_vif, v, NULL); /* update concurrent index */ ssrbnode *n = NULL; int rc = sx_match(&index->i, index->scheme, sv_vpointer(version), version->size, &n); if (ssunlikely(rc == 0 && n)) { /* exists */ } else { /* unique */ v->lo = sv_logcount(&t->log); if (ssunlikely((sv_logadd(&t->log, m->a, &lv, index->ptr)) == -1)) { rc = sr_oom(index->r->e); } else { ss_rbset(&index->i, n, rc, &v->node); rc = 0; } return rc; } sxv *head = sscast(n, sxv, node); /* match previous update made by current * transaction */ sxv *own = sx_vmatch(head, t->id); if (ssunlikely(own)) { if (ssunlikely(version->flags & SVUPDATE)) { sr_error(index->r->e, "%s", "only one update statement is " "allowed per a transaction key"); sx_vfree(m->a, m->asxv, v); return -1; } /* replace old object with the new one */ lv.next = sv_logat(&t->log, own->lo)->next; v->lo = own->lo; sx_vreplace(own, v); if (sslikely(head == own)) ss_rbreplace(&index->i, &own->node, &v->node); /* update log */ sv_logreplace(&t->log, v->lo, &lv); sx_vfree(m->a, m->asxv, own); return 0; } /* update log */ rc = sv_logadd(&t->log, m->a, &lv, index->ptr); if (ssunlikely(rc == -1)) { sx_vfree(m->a, m->asxv, v); return sr_oom(index->r->e); } /* add version */ sx_vlink(head, v); return 0; }