Exemple #1
0
static void *se_worker(void *arg)
{
	seworker *self = arg;
	se *o = self->arg;
	for (;;)
	{
		int rc = se_active(o);
		if (ssunlikely(rc == 0))
			break;
		rc = se_scheduler(&o->sched, self);
		if (ssunlikely(rc == -1))
			break;
		if (ssunlikely(rc == 0))
			ss_sleep(10000000); /* 10ms */
	}
	return NULL;
}
Exemple #2
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;
}
Exemple #3
0
static int
se_dispatch(sescheduler *s, seworker *w, setask *t)
{
	ss_trace(&w->trace, "%s", "dispatcher");
	se *e = (se*)s->env;
	int block = t->req == 1;
	do {
		int rc = se_active(e);
		if (ssunlikely(rc == 0))
			break;
		sereq *req = se_reqdispatch(e, block);
		if (req) {
			se_execute(req);
			se_reqready(req);
		}
	} while (block);
	return 0;
}
Exemple #4
0
static void *se_worker(void *arg)
{
	ssthread *self = arg;
	se *e = self->arg;
	seworker *worker = se_workerpool_pop(&e->sched.workers, &e->r);
	if (ssunlikely(worker == NULL))
		return NULL;
	for (;;)
	{
		int rc = se_active(e);
		if (ssunlikely(rc == 0))
			break;
		rc = se_scheduler(&e->sched, worker);
		if (ssunlikely(rc == -1))
			break;
		if (ssunlikely(rc == 0))
			ss_sleep(10000000); /* 10ms */
	}
	se_workerpool_push(&e->sched.workers, worker);
	return NULL;
}
Exemple #5
0
static int
se_dispatch(sescheduler *s, seworker *w, setask *t)
{
	ss_trace(&w->trace, "%s", "dispatcher");
	se *e = (se*)s->env;
	int block = t->req == 1;
	do {
		int rc = se_active(e);
		if (ssunlikely(rc == 0))
			break;
		sereq *req = se_reqdispatch(e, block);
		if (req) {
			switch (req->op) {
			case SE_REQREAD:
				se_execute_read(req);
				break;
			default: assert(0);
			}
			se_reqready(req);
		}
	} while (block);
	return 0;
}
Exemple #6
0
static void*
se_worker(void *arg)
{
	ssthread *self = arg;
	se *e = self->arg;
	ss_thread_setname(self, "worker");
	ss_vfsioprio_low(&e->vfs);
	scworker *w = sc_workerpool_pop(&e->scheduler.wp, &e->r);
	if (ssunlikely(w == NULL))
		return NULL;
	for (;;)
	{
		int rc = se_active(e);
		if (ssunlikely(rc == 0))
			break;
		rc = sc_step(&e->scheduler, w, sx_vlsn(&e->xm));
		if (ssunlikely(rc == -1))
			break;
		if (ssunlikely(rc == 0))
			ss_sleep(10000000); /* 10ms */
	}
	sc_workerpool_push(&e->scheduler.wp, w);
	return NULL;
}
Exemple #7
0
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;
}