Example #1
0
void *st_document_generate(stgenerator *g, sf fmt, stlist *l, void *db,
                         uint32_t seed,
                         uint32_t seed_value)
{
	svv *v = st_svv_seed(g, seed, seed_value);
	if (ssunlikely(v == NULL))
		return NULL;
	assert(l->svv == 1);
	int rc = ss_bufadd(&l->list, g->r->a, &v, sizeof(svv**));
	if (ssunlikely(rc == -1)) {
		sv_vfree(g->r, v);
		return NULL;
	}
	void *o = sp_document(db);
	t( o != NULL );
	switch (fmt) {
	case SF_KV: {
		int i = 0;
		while (i < g->r->scheme->count) {
			rc = sp_setstring(o, g->r->scheme->parts[i].name,
			                  sf_key(sv_vpointer(v), i),
			                  sf_keysize(sv_vpointer(v), i));
			t( rc == 0 );
			i++;
		}
		if ((g->value_start + g->value_end) > 0) {
			rc = sp_setstring(o, "value",
			                  sf_value(g->r->fmt, sv_vpointer(v), g->r->scheme->count),
			                  sf_valuesize(g->r->fmt, sv_vpointer(v), v->size,
			                               g->r->scheme->count));
			t( rc == 0 );
		}
		break;
	}
	case SF_DOCUMENT: {
		char *vpointer = sv_vpointer(v);
		int i = 0;
		while (i < g->r->scheme->count) {
			rc = sp_setstring(o, g->r->scheme->parts[i].name,
			                  sf_key(vpointer, i),
			                  sf_keysize(vpointer, i));
			t( rc == 0 );
			i++;
		}
		rc = sp_setstring(o, "value", vpointer, v->size);
		t( rc == 0 );
		break;
	}
	}
	return o;
}
Example #2
0
int se_document_create(sedocument *o, uint8_t flags)
{
	sedb *db = (sedb*)o->o.parent;
	se *e = se_of(&db->o);

	assert(o->created == 0);
	assert(o->v == NULL);

	/* create document from raw data */
	if (o->raw) {
		o->v = sv_vbuildraw(db->r, o->raw);
		if (ssunlikely(o->v == NULL))
			return sr_oom(&e->error);
		o->created = 1;
		return 0;
	}

	/* ensure all keys are set */
	if (ssunlikely(o->fields_count_keys != db->scheme->scheme.keys_count))
		return sr_error(&e->error, "%s", "incomplete key");

	/* set auto fields */
	uint32_t timestamp = UINT32_MAX;
	if (db->scheme->scheme.has_timestamp) {
		timestamp = ss_timestamp();
		sf_autoset(&db->scheme->scheme, o->fields, &timestamp);
	}

	o->v = sv_vbuild(db->r, o->fields);
	if (ssunlikely(o->v == NULL))
		return sr_oom(&e->error);
	sf_flagsset(db->r->scheme, sv_vpointer(o->v), flags);
	o->created = 1;
	return 0;
}
Example #3
0
void st_document_eq(stgenerator *g, sf fmt, void *o,
                  uint32_t seed,
                  uint32_t seed_value)
{
	svv *v = st_svv_seed(g, seed, seed_value);
	if (ssunlikely(v == NULL)) {
		t(0);
		return;
	}
	switch (fmt) {
	case SF_KV: {
		int i = 0;
		int size = 0;
		while (i < g->r->scheme->count) {
			void *ptr = sp_getstring(o, g->r->scheme->parts[i].name, &size);
			t( ptr != NULL );
			t( size == sf_keysize(sv_vpointer(v), i) );
			t( memcmp(ptr, sf_key(sv_vpointer(v), i), size) == 0 );
			i++;
		}
		void *ptr = sp_getstring(o, "value", &size);
		if ((g->value_start + g->value_end) > 0) {
			t( ptr != NULL );
			t( size == sf_valuesize(g->r->fmt, sv_vpointer(v), v->size,
			                        g->r->scheme->count) );
			t( memcmp(ptr, sf_value(g->r->fmt, sv_vpointer(v), g->r->scheme->count),
			          size) == 0 );
		} else {
			t( ptr == NULL );
		}
		break;
	}
	case SF_DOCUMENT: {
		int i = 0;
		int size = 0;
		while (i < g->r->scheme->count) {
			void *ptr = sp_getstring(o, g->r->scheme->parts[i].name, &size);
			t( ptr != NULL );
			t( size == sf_keysize(sv_vpointer(v), i) );
			t( memcmp(ptr, sf_key(sv_vpointer(v), i), size) == 0 );
			i++;
		}
		void *ptr = sp_getstring(o, "value", &size);
		t( ptr != NULL );
		if ((g->value_start + g->value_end) > 0) {
			int vsize = sf_valuesize(g->r->fmt, ptr, size, g->r->scheme->count);
			t( vsize == sf_valuesize(g->r->fmt, sv_vpointer(v), v->size,
			                         g->r->scheme->count) );
			ptr = sf_value(g->r->fmt, ptr, g->r->scheme->count);
			t( memcmp(ptr, sf_value(g->r->fmt, sv_vpointer(v),
			          g->r->scheme->count), vsize) == 0 );
		}
		break;
	}
	}
	sv_vfree(g->r, v);
}
Example #4
0
static int
si_redistribute(si *index, sr *r, sdc *c, sinode *node, ssbuf *result)
{
	(void)index;
	svindex *vindex = si_nodeindex(node);
	ssiter i;
	ss_iterinit(sv_indexiter, &i);
	ss_iteropen(sv_indexiter, &i, r, vindex, SS_GTE, NULL, 0);
	while (ss_iterhas(sv_indexiter, &i))
	{
		sv *v = ss_iterof(sv_indexiter, &i);
		int rc = ss_bufadd(&c->b, r->a, &v->v, sizeof(svv**));
		if (ssunlikely(rc == -1))
			return sr_oom_malfunction(r->e);
		ss_iternext(sv_indexiter, &i);
	}
	if (ssunlikely(ss_bufused(&c->b) == 0))
		return 0;
	ss_iterinit(ss_bufiterref, &i);
	ss_iteropen(ss_bufiterref, &i, &c->b, sizeof(svv*));
	ssiter j;
	ss_iterinit(ss_bufiterref, &j);
	ss_iteropen(ss_bufiterref, &j, result, sizeof(sinode*));
	sinode *prev = ss_iterof(ss_bufiterref, &j);
	ss_iternext(ss_bufiterref, &j);
	while (1)
	{
		sinode *p = ss_iterof(ss_bufiterref, &j);
		if (p == NULL) {
			assert(prev != NULL);
			while (ss_iterhas(ss_bufiterref, &i)) {
				svv *v = ss_iterof(ss_bufiterref, &i);
				v->next = NULL;
				sv_indexset(&prev->i0, r, v);
				ss_iternext(ss_bufiterref, &i);
			}
			break;
		}
		while (ss_iterhas(ss_bufiterref, &i))
		{
			svv *v = ss_iterof(ss_bufiterref, &i);
			v->next = NULL;
			sdindexpage *page = sd_indexmin(&p->self.index);
			int rc = sr_compare(r->scheme, sv_vpointer(v), v->size,
			                    sd_indexpage_min(&p->self.index, page),
			                    page->sizemin);
			if (ssunlikely(rc >= 0))
				break;
			sv_indexset(&prev->i0, r, v);
			ss_iternext(ss_bufiterref, &i);
		}
		if (ssunlikely(! ss_iterhas(ss_bufiterref, &i)))
			break;
		prev = p;
		ss_iternext(ss_bufiterref, &j);
	}
	assert(ss_iterof(ss_bufiterref, &i) == NULL);
	return 0;
}
Example #5
0
static inline svv*
getv(svindex *i, sr *r, uint64_t vlsn, svv *key) {
	ssrbnode *n = NULL;
	int rc = sv_indexmatch(&i->i, r->scheme, sv_vpointer(key), sv_vsize(key), &n);
	if (rc == 0 && n) {
		return sv_visible(sscast(n, svv, node), vlsn);
	}
	return NULL;
}
Example #6
0
static void
sv_indexiter_lt_eq(void)
{
	svindex i;
	t( sv_indexinit(&i) == 0 );

	int keya = 7;
	int keyb = 5;
	int keyc = 2;
	svv *va = st_svv(&st_r.g, NULL, 0, 0, keya);
	t( sv_indexset(&i, &st_r.r, va) == 0 );
	svv *vb = st_svv(&st_r.g, NULL, 0, 0, keyb);
	t( sv_indexset(&i, &st_r.r, vb) == 0 );
	svv *vc = st_svv(&st_r.g, NULL, 0, 0, keyc);
	t( sv_indexset(&i, &st_r.r, vc) == 0 );

	ssiter it;
	ss_iterinit(sv_indexiter, &it);
	ss_iteropen(sv_indexiter, &it, &st_r.r, &i, SS_LT, sv_vpointer(va), va->size);
	t( ss_iteratorhas(&it) != 0 );
	sv *v = ss_iteratorof(&it);
	t( v->v == vb );

	ss_iterinit(sv_indexiter, &it);
	ss_iteropen(sv_indexiter, &it, &st_r.r, &i, SS_LT, sv_vpointer(vb), vb->size);
	t( ss_iteratorhas(&it) != 0 );
	v = ss_iteratorof(&it);
	t( v->v == vc );

	ss_iterinit(sv_indexiter, &it);
	ss_iteropen(sv_indexiter, &it, &st_r.r, &i, SS_LT, sv_vpointer(vc), vc->size);
	t( ss_iteratorhas(&it) == 0 );
	v = ss_iteratorof(&it);
	t( v == NULL );

	sv_indexfree(&i, &st_r.r);
}
Example #7
0
int sx_get(sx *x, sxindex *index, svv *key, svv **result)
{
	ssrbnode *n = NULL;
	int rc;
	rc = sx_match(&index->i, index->r->scheme,
	              sv_vpointer(key), 0, &n);
	if (! (rc == 0 && n))
		goto add;
	sxv *head = sscast(n, sxv, node);
	sxv *v = sx_vmatch(head, x->id);
	if (v == NULL)
		goto add;
	if (ssunlikely(sv_vflags(v->v, index->r) & SVGET))
		return 0;
	if (ssunlikely(sv_vflags(v->v, index->r) & SVDELETE))
		return 2;
	*result = sv_vbuildraw(index->r, sv_vpointer(v->v));
	if (ssunlikely(*result == NULL)) {
		sr_oom(index->r->e);
		rc = -1;
	} else {
		rc = 1;
	}
	return rc;

add:
	/* track a start of the latest read sequence in the
	 * transactional log */
	if (x->log_read == -1)
		x->log_read = sv_logcount(x->log);
	rc = sx_set(x, index, key);
	if (ssunlikely(rc == -1))
		return -1;
	sv_vref(key);
	return 0;
}
Example #8
0
static inline void
si_redistribute_set(si *index, sr *r, svv *v)
{
	/* match node */
	ssiter i;
	ss_iterinit(si_iter, &i);
	ss_iteropen(si_iter, &i, r, index, SS_GTE, sv_vpointer(v));
	sinode *node = ss_iterof(si_iter, &i);
	assert(node != NULL);
	/* update node */
	svindex *vindex = si_nodeindex(node);
	sv_indexset(vindex, r, v);
	node->used += sv_vsize(v, &index->r);
	/* schedule node */
	si_plannerupdate(&index->p, node);
}
Example #9
0
static void
sv_indexiter_gte_empty(void)
{
	svindex i;
	t( sv_indexinit(&i) == 0 );

	svv *key = st_svv(&st_r.g, &st_r.gc, 0, 0, 7);
	ssiter it;
	ss_iterinit(sv_indexiter, &it);
	ss_iteropen(sv_indexiter, &it, &st_r.r, &i, SS_GTE, sv_vpointer(key), key->size);
	t( ss_iteratorhas(&it) == 0 );
	sv *v = ss_iteratorof(&it);
	t( v == NULL );

	sv_indexfree(&i, &st_r.r);
}
Example #10
0
int se_reqread(sereq *r)
{
	sereqarg *arg = &r->arg;
	sedb *db = (sedb*)r->db;
	uint32_t keysize;
	void *key;
	if (sslikely(arg->v.v)) {
		keysize = sv_size(&arg->v);
		key = sv_pointer(&arg->v);
	} else {
		keysize = 0;
		key = NULL;
	}
	char *prefix;
	uint32_t prefixsize;
	if (arg->vprefix.v) {
		void *vptr = sv_vpointer(arg->vprefix.v);
		prefix = sf_key(vptr, 0);
		prefixsize = sf_keysize(vptr, 0);
	} else {
		prefix = NULL;
		prefixsize = 0;
	}
	if (sslikely(arg->vlsn_generate))
		arg->vlsn = sr_seq(db->r.seq, SR_LSN);
	sitx x;
	si_begin(&x, &db->index, 1);
	siread q;
	si_readopen(&q, &x, arg->cache,
	            arg->order,
	            arg->vlsn,
	            prefix,
	            prefixsize, key, keysize);
	if (arg->update)
		si_readupdate(&q, &arg->vup, arg->update_eq);
	if (arg->cache_only)
		si_readcache_only(&q);
	if (arg->has)
		si_readhas(&q);
	r->rc = si_read(&q);
	r->read_disk  = q.read_disk;
	r->read_cache = q.read_cache;
	r->v = q.result.v;
	si_readclose(&q);
	si_commit(&x);
	return r->rc;
}
Example #11
0
static inline void
si_redistribute_set(si *index, sr *r, uint64_t now, svv *v)
{
	index->update_time = now;
	/* match node */
	ssiter i;
	ss_iterinit(si_iter, &i);
	ss_iteropen(si_iter, &i, r, index, SS_ROUTE, sv_vpointer(v), v->size);
	sinode *node = ss_iterof(si_iter, &i);
	assert(node != NULL);
	/* update node */
	svindex *vindex = si_nodeindex(node);
	sv_indexset(vindex, r, v);
	node->update_time = index->update_time;
	node->used += sv_vsize(v);
	/* schedule node */
	si_plannerupdate(&index->p, SI_BRANCH, node);
}
Example #12
0
int se_document_createkey(sedocument *o)
{
	sedb *db = (sedb*)o->o.parent;
	se *e = se_of(&db->o);

	if (o->created)
		return 0;
	assert(o->v == NULL);

	/* set prefix */
	if (o->prefix) {
		if (db->scheme->scheme.keys[0]->type != SS_STRING)
			return sr_error(&e->error, "%s", "prefix search is only "
			                "supported for a string key");
		void *copy = ss_malloc(&e->a, o->prefix_size);
		if (ssunlikely(copy == NULL))
			return sr_oom(&e->error);
		memcpy(copy, o->prefix, o->prefix_size);
		o->prefix_copy = copy;
	}

	/* set unspecified min/max keys, depending on
	 * iteration order */
	if (ssunlikely(o->fields_count_keys != db->scheme->scheme.keys_count))
	{
		if (o->prefix && o->fields_count_keys == 0) {
			memset(o->fields, 0, sizeof(o->fields));
			o->fields[0].pointer = o->prefix;
			o->fields[0].size = o->prefix_size;
		}
		sf_limitapply(&db->limit, &db->scheme->scheme,
		              o->fields, o->order);
		o->fields_count = db->scheme->scheme.fields_count;
		o->fields_count_keys = db->scheme->scheme.keys_count;
	}

	o->v = sv_vbuild(db->r, o->fields);
	if (ssunlikely(o->v == NULL))
		return sr_oom(&e->error);
	sf_flagsset(db->r->scheme, sv_vpointer(o->v), SVGET);
	o->created = 1;
	return 0;
}
Example #13
0
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;
}
Example #14
0
static char*
sv_vifpointer(sv *v) {
	return sv_vpointer(((svv*)v->v));
}
Example #15
0
static char*
sx_vifpointer(sv *v) {
	return sv_vpointer(((sxv*)v->v)->v);
}
Example #16
0
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;
}
Example #17
0
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;
}
Example #18
0
		} else {
			sx_untrack(v);
			ss_free(m->asxv, v);
		}
	}

	/* rollback latest reads */
	sx_rollback_svp(x, &i, 0);

	sx_promote(x, SXCOMMIT);
	sx_end(x);
	return SXCOMMIT;
}

ss_rbget(sx_match,
         sr_compare(scheme, sv_vpointer((sscast(n, sxv, node))->v),
                    (sscast(n, sxv, node))->v->size,
                    key, keysize))

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);