Exemplo n.º 1
0
static int
se_schedule_plan(sescheduler *s, siplan *plan, sedb **dbret)
{
	int start = s->rr;
	int limit = s->count;
	int i = start;
	int rc_inprogress = 0;
	int rc;
	*dbret = NULL;
first_half:
	while (i < limit) {
		sedb *db = s->i[i];
		if (ssunlikely(! se_dbactive(db))) {
			i++;
			continue;
		}
		rc = si_plan(&db->index, plan);
		switch (rc) {
		case 1:
			s->rr = i;
			*dbret = db;
			return 1;
		case 2: rc_inprogress = rc;
		case 0: break;
		}
		i++;
	}
	if (i > start) {
		i = 0;
		limit = start;
		goto first_half;
	}
	s->rr = 0;
	return rc_inprogress;
}
Exemplo n.º 2
0
static inline int
sc_plan(sc *s, sctask *task, int id)
{
	scdb *db = sc_current(s);
	uint32_t prio = s->prio[id];
	if (db->workers[id] >= prio)
		return SI_PRETRY;
	return si_plan(db->index, &task->plan);
}
Exemplo n.º 3
0
int se_scheduler_branch(void *arg)
{
	sedb *db = arg;
	se *e = se_of(&db->o);
	srzone *z = se_zoneof(e);
	seworker stub;
	se_workerstub_init(&stub);
	int rc;
	while (1) {
		uint64_t vlsn = sx_vlsn(&e->xm);
		siplan plan = {
			.explain   = SI_ENONE,
			.plan      = SI_BRANCH,
			.a         = z->branch_wm,
			.b         = 0,
			.c         = 0,
			.node      = NULL
		};
		rc = si_plan(&db->index, &plan);
		if (rc == 0)
			break;
		rc = si_execute(&db->index, &stub.dc, &plan, vlsn);
		if (ssunlikely(rc == -1))
			break;
	}
	se_workerstub_free(&stub, &db->r);
	return rc;
}

int se_scheduler_compact(void *arg)
{
	sedb *db = arg;
	se *e = se_of(&db->o);
	srzone *z = se_zoneof(e);
	seworker stub;
	se_workerstub_init(&stub);
	int rc;
	while (1) {
		uint64_t vlsn = sx_vlsn(&e->xm);
		siplan plan = {
			.explain   = SI_ENONE,
			.plan      = SI_COMPACT,
			.a         = z->compact_wm,
			.b         = z->compact_mode,
			.c         = 0,
			.node      = NULL
		};
		rc = si_plan(&db->index, &plan);
		if (rc == 0)
			break;
		rc = si_execute(&db->index, &stub.dc, &plan, vlsn);
		if (ssunlikely(rc == -1))
			break;
	}
	se_workerstub_free(&stub, &db->r);
	return rc;
}

int se_scheduler_checkpoint(void *arg)
{
	se *o = arg;
	sescheduler *s = &o->sched;
	uint64_t lsn = sr_seq(&o->seq, SR_LSN);
	ss_mutexlock(&s->lock);
	s->checkpoint_lsn = lsn;
	s->checkpoint = 1;
	ss_mutexunlock(&s->lock);
	return 0;
}
Exemplo n.º 4
0
int sc_ctl_branch(sc *s, uint64_t vlsn, si *index)
{
	sr *r = s->r;
	int rc = sr_statusactive(r->status);
	if (ssunlikely(rc == 0))
		return 0;
	srzone *z = sr_zoneof(r);
	scworker *w = sc_workerpool_pop(&s->wp, r);
	if (ssunlikely(w == NULL))
		return -1;
	while (1) {
		uint64_t vlsn_lru = si_lru_vlsn(index);
		siplan plan = {
			.explain   = SI_ENONE,
			.plan      = SI_BRANCH,
			.a         = z->branch_wm,
			.b         = 0,
			.c         = 0,
			.node      = NULL
		};
		rc = si_plan(index, &plan);
		if (rc == 0)
			break;
		rc = si_execute(index, &w->dc, &plan, vlsn, vlsn_lru);
		if (ssunlikely(rc == -1))
			break;
	}
	sc_workerpool_push(&s->wp, w);
	return rc;
}

int sc_ctl_compact(sc *s, uint64_t vlsn, si *index)
{
	sr *r = s->r;
	int rc = sr_statusactive(r->status);
	if (ssunlikely(rc == 0))
		return 0;
	srzone *z = sr_zoneof(r);
	scworker *w = sc_workerpool_pop(&s->wp, r);
	if (ssunlikely(w == NULL))
		return -1;
	while (1) {
		uint64_t vlsn_lru = si_lru_vlsn(index);
		siplan plan = {
			.explain   = SI_ENONE,
			.plan      = SI_COMPACT,
			.a         = z->compact_wm,
			.b         = z->compact_mode,
			.c         = 0,
			.node      = NULL
		};
		rc = si_plan(index, &plan);
		if (rc == 0)
			break;
		rc = si_execute(index, &w->dc, &plan, vlsn, vlsn_lru);
		if (ssunlikely(rc == -1))
			break;
	}
	sc_workerpool_push(&s->wp, w);
	return rc;
}

int sc_ctl_compact_index(sc *s, uint64_t vlsn, si *index)
{
	sr *r = s->r;
	int rc = sr_statusactive(r->status);
	if (ssunlikely(rc == 0))
		return 0;
	srzone *z = sr_zoneof(r);
	scworker *w = sc_workerpool_pop(&s->wp, r);
	if (ssunlikely(w == NULL))
		return -1;
	while (1) {
		uint64_t vlsn_lru = si_lru_vlsn(index);
		siplan plan = {
			.explain   = SI_ENONE,
			.plan      = SI_COMPACT_INDEX,
			.a         = z->branch_wm,
			.b         = 0,
			.c         = 0,
			.node      = NULL
		};
		rc = si_plan(index, &plan);
		if (rc == 0)
			break;
		rc = si_execute(index, &w->dc, &plan, vlsn, vlsn_lru);
		if (ssunlikely(rc == -1))
			break;
	}
	sc_workerpool_push(&s->wp, w);
	return rc;
}

int sc_ctl_anticache(sc *s)
{
	uint64_t asn = sr_seq(s->r->seq, SR_ASNNEXT);
	ss_mutexlock(&s->lock);
	s->anticache_asn = asn;
	s->anticache_storage = s->anticache_limit;
	s->anticache = 1;
	ss_mutexunlock(&s->lock);
	return 0;
}
Exemplo n.º 5
0
int se_scheduler_branch(void *arg)
{
	sedb *db = arg;
	se *e = se_of(&db->o);
	srzone *z = se_zoneof(e);
	seworker *w = se_workerpool_pop(&e->sched.workers, &e->r);
	if (ssunlikely(w == NULL))
		return -1;
	int rc;
	while (1) {
		uint64_t vlsn = sx_vlsn(&e->xm);
		uint64_t vlsn_lru = si_lru_vlsn(&db->index);
		siplan plan = {
			.explain   = SI_ENONE,
			.plan      = SI_BRANCH,
			.a         = z->branch_wm,
			.b         = 0,
			.c         = 0,
			.node      = NULL
		};
		rc = si_plan(&db->index, &plan);
		if (rc == 0)
			break;
		rc = si_execute(&db->index, &w->dc, &plan, vlsn, vlsn_lru);
		if (ssunlikely(rc == -1))
			break;
	}
	se_workerpool_push(&e->sched.workers, w);
	return rc;
}

int se_scheduler_compact(void *arg)
{
	sedb *db = arg;
	se *e = se_of(&db->o);
	srzone *z = se_zoneof(e);
	seworker *w = se_workerpool_pop(&e->sched.workers, &e->r);
	if (ssunlikely(w == NULL))
		return -1;
	int rc;
	while (1) {
		uint64_t vlsn = sx_vlsn(&e->xm);
		uint64_t vlsn_lru = si_lru_vlsn(&db->index);
		siplan plan = {
			.explain   = SI_ENONE,
			.plan      = SI_COMPACT,
			.a         = z->compact_wm,
			.b         = z->compact_mode,
			.c         = 0,
			.node      = NULL
		};
		rc = si_plan(&db->index, &plan);
		if (rc == 0)
			break;
		rc = si_execute(&db->index, &w->dc, &plan, vlsn, vlsn_lru);
		if (ssunlikely(rc == -1))
			break;
	}
	se_workerpool_push(&e->sched.workers, w);
	return rc;
}

int se_scheduler_compact_index(void *arg)
{
	sedb *db = arg;
	se *e = se_of(&db->o);
	srzone *z = se_zoneof(e);
	seworker *w = se_workerpool_pop(&e->sched.workers, &e->r);
	if (ssunlikely(w == NULL))
		return -1;
	int rc;
	while (1) {
		uint64_t vlsn = sx_vlsn(&e->xm);
		uint64_t vlsn_lru = si_lru_vlsn(&db->index);
		siplan plan = {
			.explain   = SI_ENONE,
			.plan      = SI_COMPACT_INDEX,
			.a         = z->branch_wm,
			.b         = 0,
			.c         = 0,
			.node      = NULL
		};
		rc = si_plan(&db->index, &plan);
		if (rc == 0)
			break;
		rc = si_execute(&db->index, &w->dc, &plan, vlsn, vlsn_lru);
		if (ssunlikely(rc == -1))
			break;
	}
	se_workerpool_push(&e->sched.workers, w);
	return rc;
}

int se_scheduler_anticache(void *arg)
{
	se *o = arg;
	sescheduler *s = &o->sched;
	uint64_t asn = sr_seq(&o->seq, SR_ASNNEXT);
	ss_mutexlock(&s->lock);
	s->anticache_asn = asn;
	s->anticache_storage = o->conf.anticache;
	s->anticache = 1;
	ss_mutexunlock(&s->lock);
	return 0;
}
Exemplo n.º 6
0
static inline siplannerrc
sc_do(sc *s, sctask *task)
{
	siplannerrc rc;
	scdb *db = task->db;
	sicompaction *c = &db->index->scheme.compaction;

	ss_trace(&task->w->trace, "%s", "schedule");

	/* checkpoint */
	if (db->checkpoint) {
		task->plan.plan = SI_CHECKPOINT;
		task->plan.a = db->checkpoint_vlsn;
		rc = si_plan(db->index, &task->plan);
		switch (rc) {
		case SI_PMATCH:
			return rc;
		case SI_PNONE:
			sc_task_checkpoint_done(db, task->time);
			break;
		case SI_PRETRY:
			break;
		}
	}

	/* node delayed gc */
	task->plan.plan = SI_NODEGC;
	rc = si_plan(db->index, &task->plan);
	if (rc == SI_PMATCH)
		return rc;

	/* backup */
	if (db->backup)
	{
		/* backup procedure.
		 *
		 * state 0 (start)
		 * -------
		 *
		 * a. disable log gc
		 * b. mark to start backup (state 1)
		 *
		 * state 1 (background, delayed start)
		 * -------
		 *
		 * a. create backup_path/<bsn.incomplete> directory
		 * b. create database directories
		 * c. create log directory
		 * d. state 2
		 *
		 * state 2 (background, copy)
		 * -------
		 *
		 * a. schedule and execute node backup which bsn < backup_bsn
		 * b. state 3
		 *
		 * state 3 (background, completion)
		 * -------
		 *
		 * a. rotate log file
		 * b. copy log files
		 * c. enable log gc, schedule gc
		 * d. rename <bsn.incomplete> into <bsn>
		 * e. set last backup, set COMPLETE
		 *
		*/

		/* state 2 */
		task->plan.plan = SI_BACKUP;
		task->plan.a = s->backup_bsn;
		rc = sc_plan(s, task, SC_QBACKUP);
		switch (rc) {
		case SI_PMATCH:
			db->workers[SC_QBACKUP]++;
			task->db = db;
			return SI_PMATCH;
		case SI_PNONE:
			sc_task_backup_done(task->db);
			assert(s->backup_in_progress > 0);
			s->backup_in_progress--;
			/* state 3 */
			if (s->backup_in_progress == 0)
				task->backup = 1;
			break;
		case SI_PRETRY:
			break;
		}
	}

	/* expire */
	if (db->expire) {
		task->plan.plan = SI_EXPIRE;
		task->plan.a = db->index->scheme.expire;
		rc = sc_plan(s, task, SC_QEXPIRE);
		switch (rc) {
		case SI_PMATCH:
			db->workers[SC_QEXPIRE]++;
			return SI_PMATCH;
		case SI_PNONE:
			sc_task_expire_done(db, task->time);
			break;
		case SI_PRETRY:
			break;
		}
	}

	/* garbage-collection */
	if (db->gc) {
		task->plan.plan = SI_GC;
		task->plan.a = task->vlsn;
		task->plan.b = c->gc_wm;
		rc = sc_plan(s, task, SC_QGC);
		switch (rc) {
		case SI_PMATCH:
			db->workers[SC_QGC]++;
			return SI_PMATCH;
		case SI_PNONE:
			sc_task_gc_done(db, task->time);
			break;
		case SI_PRETRY:
			break;
		}
	}

	/* compaction */
	task->plan.plan = SI_COMPACTION;
	rc = si_plan(db->index, &task->plan);
	if (rc == SI_PMATCH)
		return SI_PMATCH;

	si_planinit(&task->plan);
	return SI_PNONE;
}