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 *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 *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; }