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, ×tamp); } 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; }
static void se_cursorfree(so *o) { assert(o->destroyed); se *e = se_of(o); ss_free(&e->a, o); }
static void se_document_free(so *o) { assert(o->destroyed); se *e = se_of(o); ss_free(&e->a, o); }
int se_reqwrite(sereq *r) { sereqarg *arg = &r->arg; svlog *log = r->arg.log; se *e = se_of(r->object); /* set lsn */ sl_prepare(&e->lp, log, arg->lsn); /* log write */ if (! arg->recover) { sltx tl; sl_begin(&e->lp, &tl); int rc = sl_write(&tl, log); if (ssunlikely(rc == -1)) { sl_rollback(&tl); r->rc = -1; return -1; } sl_commit(&tl); } /* commit */ if (sslikely(arg->vlsn_generate)) arg->vlsn = sx_vlsn(&e->xm); uint64_t now = ss_utime(); svlogindex *i = (svlogindex*)log->index.s; svlogindex *end = (svlogindex*)log->index.p; while (i < end) { sedb *db = i->ptr; sitx ti; si_begin(&ti, &db->index, arg->vlsn, now, log, i); si_write(&ti, arg->recover); si_commit(&ti); i++; } return 0; }
static void se_confkv_free(so *o) { seconfkv *v = (seconfkv*)o; se *e = se_of(o); ss_buffree(&v->key, &e->a); ss_buffree(&v->value, &e->a); ss_free(&e->a, v); }
static int se_dbscheme_init(sedb *db, char *name, int size) { se *e = se_of(&db->o); /* database id */ uint32_t id = sr_seq(&e->seq, SR_DSN); sr_seq(&e->seq, SR_DSNNEXT); /* prepare index scheme */ sischeme *scheme = db->scheme; if (size == 0) size = strlen(name); scheme->name = ss_malloc(&e->a, size + 1); if (ssunlikely(scheme->name == NULL)) goto error; memcpy(scheme->name, name, size); scheme->name[size] = 0; scheme->id = id; scheme->sync = 2; scheme->mmap = 0; scheme->storage = SI_SCACHE; scheme->node_size = 64 * 1024 * 1024; scheme->node_compact_load = 0; scheme->node_page_size = 128 * 1024; scheme->node_page_checksum = 1; scheme->compression_copy = 0; scheme->compression_cold = 0; scheme->compression_cold_if = &ss_nonefilter; scheme->compression_hot = 0; scheme->compression_hot_if = &ss_nonefilter; scheme->temperature = 0; scheme->expire = 0; scheme->amqf = 0; scheme->fmt_storage = SF_RAW; scheme->lru = 0; scheme->lru_step = 128 * 1024; scheme->buf_gc_wm = 1024 * 1024; scheme->storage_sz = ss_strdup(&e->a, "cache"); if (ssunlikely(scheme->storage_sz == NULL)) goto error; scheme->compression_cold_sz = ss_strdup(&e->a, scheme->compression_cold_if->name); if (ssunlikely(scheme->compression_cold_sz == NULL)) goto error; scheme->compression_hot_sz = ss_strdup(&e->a, scheme->compression_hot_if->name); if (ssunlikely(scheme->compression_hot_sz == NULL)) goto error; sf_upsertinit(&scheme->fmt_upsert); sf_schemeinit(&scheme->scheme); return 0; error: sr_oom(&e->error); return -1; }
static inline int se_txwrite(setx *t, sev *o, uint8_t flags) { se *e = se_of(&t->o); sedb *db = se_cast(o->o.parent, sedb*, SEDB); /* validate req */ if (ssunlikely(t->t.state == SXPREPARE)) { sr_error(&e->error, "%s", "transaction is in 'prepare' state (read-only)"); goto error; } /* validate database status */ int status = se_status(&db->status); switch (status) { case SE_SHUTDOWN: if (ssunlikely(! se_dbvisible(db, t->t.id))) { sr_error(&e->error, "%s", "database is invisible for the transaction"); goto error; } break; case SE_RECOVER: case SE_ONLINE: break; default: goto error; } if (flags == SVUPDATE && !sf_updatehas(&db->scheme.fmt_update)) flags = 0; /* prepare object */ svv *v; int rc = se_dbv(db, o, 0, &v); if (ssunlikely(rc == -1)) goto error; v->flags = flags; v->log = o->log; sv vp; sv_init(&vp, &sv_vif, v, NULL); so_destroy(&o->o); /* ensure quota */ int size = sizeof(svv) + sv_size(&vp); ss_quota(&e->quota, SS_QADD, size); /* concurrent index only */ rc = sx_set(&t->t, &db->coindex, v); if (ssunlikely(rc == -1)) { ss_quota(&e->quota, SS_QREMOVE, size); return -1; } return 0; error: so_destroy(&o->o); return -1; }
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; }
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; }
static int se_dbscheme_init(sedb *db, char *name, int size) { se *e = se_of(&db->o); /* database id */ uint32_t id = sr_seq(&e->seq, SR_DSN); sr_seq(&e->seq, SR_DSNNEXT); /* prepare index scheme */ sischeme *scheme = db->scheme; if (size == 0) size = strlen(name); scheme->name = ss_malloc(&e->a, size + 1); if (ssunlikely(scheme->name == NULL)) goto error; memcpy(scheme->name, name, size); scheme->name[size] = 0; scheme->id = id; scheme->sync = 1; scheme->mmap = 1; scheme->direct_io = 0; scheme->direct_io_page_size = 4096; scheme->direct_io_buffer_size = 8 * 1024 * 1024; scheme->compression = 0; scheme->compression_if = &ss_nonefilter; scheme->expire = 0; scheme->buf_gc_wm = 1024 * 1024; scheme->compression_sz = ss_strdup(&e->a, scheme->compression_if->name); if (ssunlikely(scheme->compression_sz == NULL)) goto error; sf_upsertinit(&scheme->upsert); sf_schemeinit(&scheme->scheme); return 0; error: sr_oom(&e->error); return -1; }
static int se_dbscheme_set(sedb *db) { se *e = se_of(&db->o); sischeme *s = si_scheme(db->index); /* set default scheme */ int rc; if (s->scheme.fields_count == 0) { sffield *field = sf_fieldnew(&e->a, "key"); if (ssunlikely(field == NULL)) return sr_oom(&e->error); rc = sf_fieldoptions(field, &e->a, "string,key(0)"); if (ssunlikely(rc == -1)) { sf_fieldfree(field, &e->a); return sr_oom(&e->error); } rc = sf_schemeadd(&s->scheme, &e->a, field); if (ssunlikely(rc == -1)) { sf_fieldfree(field, &e->a); return sr_oom(&e->error); } field = sf_fieldnew(&e->a, "value"); if (ssunlikely(field == NULL)) return sr_oom(&e->error); rc = sf_fieldoptions(field, &e->a, "string"); if (ssunlikely(rc == -1)) { sf_fieldfree(field, &e->a); return sr_oom(&e->error); } rc = sf_schemeadd(&s->scheme, &e->a, field); if (ssunlikely(rc == -1)) { sf_fieldfree(field, &e->a); return sr_oom(&e->error); } } /* validate scheme and set keys */ rc = sf_schemevalidate(&s->scheme, &e->a); if (ssunlikely(rc == -1)) { sr_error(&e->error, "incomplete scheme", s->name); return -1; } /* validate io settings */ if (s->mmap && s->direct_io) { sr_error(&e->error, "%s", "incompatible options: mmap and direct_io"); return -1; } /* compression */ s->compression_if = ss_filterof(s->compression_sz); if (ssunlikely(s->compression_if == NULL)) { sr_error(&e->error, "unknown compression type '%s'", s->compression_sz); return -1; } s->compression = s->compression_if != &ss_nonefilter; /* path */ if (s->path == NULL) { char path[1024]; snprintf(path, sizeof(path), "%s/%s", e->rep_conf->path, s->name); s->path = ss_strdup(&e->a, path); if (ssunlikely(s->path == NULL)) return sr_oom(&e->error); } /* backup path */ s->path_backup = e->rep_conf->path_backup; if (e->rep_conf->path_backup) { s->path_backup = ss_strdup(&e->a, e->rep_conf->path_backup); if (ssunlikely(s->path_backup == NULL)) return sr_oom(&e->error); } /* compaction settings */ sicompaction *c = &s->compaction; /* convert periodic times from sec to usec */ c->gc_period_us = c->gc_period * 1000000; c->expire_period_us = c->expire_period * 1000000; /* .. */ db->r->scheme = &s->scheme; db->r->upsert = &s->upsert; db->r->stat = &db->stat; db->r->av = &db->a; db->r->ptr = db->index; return 0; }
c->gc_period_us = c->gc_period * 1000000; c->expire_period_us = c->expire_period * 1000000; /* .. */ db->r->scheme = &s->scheme; db->r->upsert = &s->upsert; db->r->stat = &db->stat; db->r->av = &db->a; db->r->ptr = db->index; return 0; } int se_dbopen(so *o) { sedb *db = se_cast(o, sedb*, SEDB); se *e = se_of(&db->o); assert(sr_status(&e->status) == SR_RECOVER); int rc; rc = se_dbscheme_set(db); if (ssunlikely(rc == -1)) return -1; sx_indexset(&db->coindex, db->scheme->id); sr_log(&e->log, "loading database '%s'", db->scheme->path); rc = si_open(db->index); if (ssunlikely(rc == -1)) { sr_statusset(&e->status, SR_MALFUNCTION); return -1; } db->created = rc; sc_register(&e->scheduler, db->index); return 0;
static int se_dbscheme_set(sedb *db) { se *e = se_of(&db->o); sischeme *s = si_scheme(db->index); /* set default scheme */ int rc; if (s->scheme.fields_count == 0) { sffield *field = sf_fieldnew(&e->a, "key"); if (ssunlikely(field == NULL)) return sr_oom(&e->error); rc = sf_fieldoptions(field, &e->a, "string,key(0)"); if (ssunlikely(rc == -1)) { sf_fieldfree(field, &e->a); return sr_oom(&e->error); } rc = sf_schemeadd(&s->scheme, &e->a, field); if (ssunlikely(rc == -1)) { sf_fieldfree(field, &e->a); return sr_oom(&e->error); } field = sf_fieldnew(&e->a, "value"); if (ssunlikely(field == NULL)) return sr_oom(&e->error); rc = sf_fieldoptions(field, &e->a, "string"); if (ssunlikely(rc == -1)) { sf_fieldfree(field, &e->a); return sr_oom(&e->error); } rc = sf_schemeadd(&s->scheme, &e->a, field); if (ssunlikely(rc == -1)) { sf_fieldfree(field, &e->a); return sr_oom(&e->error); } } /* validate scheme and set keys */ rc = sf_schemevalidate(&s->scheme, &e->a); if (ssunlikely(rc == -1)) { sr_error(&e->error, "incomplete scheme", s->name); return -1; } /* storage */ if (strcmp(s->storage_sz, "cache") == 0) { s->storage = SI_SCACHE; } else if (strcmp(s->storage_sz, "anti-cache") == 0) { s->storage = SI_SANTI_CACHE; } else if (strcmp(s->storage_sz, "in-memory") == 0) { s->storage = SI_SIN_MEMORY; } else { sr_error(&e->error, "unknown storage type '%s'", s->storage_sz); return -1; } /* compression_copy */ if (s->compression_copy) { s->fmt_storage = SF_SPARSE; } /* compression cold */ s->compression_cold_if = ss_filterof(s->compression_cold_sz); if (ssunlikely(s->compression_cold_if == NULL)) { sr_error(&e->error, "unknown compression type '%s'", s->compression_cold_sz); return -1; } s->compression_cold = s->compression_cold_if != &ss_nonefilter; /* compression hot */ s->compression_hot_if = ss_filterof(s->compression_hot_sz); if (ssunlikely(s->compression_hot_if == NULL)) { sr_error(&e->error, "unknown compression type '%s'", s->compression_hot_sz); return -1; } s->compression_hot = s->compression_hot_if != &ss_nonefilter; /* path */ if (s->path == NULL) { char path[1024]; snprintf(path, sizeof(path), "%s/%s", e->conf.path, s->name); s->path = ss_strdup(&e->a, path); if (ssunlikely(s->path == NULL)) return sr_oom(&e->error); } /* backup path */ s->path_backup = e->conf.backup_path; if (e->conf.backup_path) { s->path_backup = ss_strdup(&e->a, e->conf.backup_path); if (ssunlikely(s->path_backup == NULL)) return sr_oom(&e->error); } db->r->scheme = &s->scheme; db->r->fmt_storage = s->fmt_storage; db->r->fmt_upsert = &s->fmt_upsert; return 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; }
#include <libsc.h> #include <libse.h> static void se_cursorfree(so *o) { assert(o->destroyed); se *e = se_of(o); ss_free(&e->a, o); } static int se_cursordestroy(so *o) { secursor *c = se_cast(o, secursor*, SECURSOR); se *e = se_of(&c->o); sx_rollback(&c->t); if (c->cache) si_cachepool_push(c->cache); sr_statcursor(&e->stat, c->start, c->read_disk, c->read_cache, c->ops); so_mark_destroyed(&c->o); so_poolgc(&e->cursor, &c->o); return 0; } static void* se_cursorget(so *o, so *v) {
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; }
static int se_dbscheme_set(sedb *db) { se *e = se_of(&db->o); sischeme *s = &db->scheme; /* storage */ if (strcmp(s->storage_sz, "cache") == 0) { s->storage = SI_SCACHE; } else if (strcmp(s->storage_sz, "anti-cache") == 0) { s->storage = SI_SANTI_CACHE; } else if (strcmp(s->storage_sz, "in-memory") == 0) { s->storage = SI_SIN_MEMORY; } else { sr_error(&e->error, "unknown storage type '%s'", s->storage_sz); return -1; } /* format */ if (strcmp(s->fmt_sz, "kv") == 0) { s->fmt = SF_KV; } else if (strcmp(s->fmt_sz, "document") == 0) { s->fmt = SF_DOCUMENT; } else { sr_error(&e->error, "unknown format type '%s'", s->fmt_sz); return -1; } /* upsert and format */ if (sf_upserthas(&s->fmt_upsert)) { if (s->fmt == SF_DOCUMENT) { sr_error(&e->error, "%s", "incompatible options: format=document " "and upsert function"); return -1; } if (s->cache_mode) { sr_error(&e->error, "%s", "incompatible options: cache_mode=1 " "and upsert function"); return -1; } } /* compression_key */ if (s->compression_key) { if (s->fmt == SF_DOCUMENT) { sr_error(&e->error, "%s", "incompatible options: format=document " "and compression_key=1"); return -1; } s->fmt_storage = SF_SKEYVALUE; } /* compression */ s->compression_if = ss_filterof(s->compression_sz); if (ssunlikely(s->compression_if == NULL)) { sr_error(&e->error, "unknown compression type '%s'", s->compression_sz); return -1; } s->compression = s->compression_if != &ss_nonefilter; /* compression branch */ s->compression_branch_if = ss_filterof(s->compression_branch_sz); if (ssunlikely(s->compression_branch_if == NULL)) { sr_error(&e->error, "unknown compression type '%s'", s->compression_branch_sz); return -1; } s->compression_branch = s->compression_branch_if != &ss_nonefilter; /* path */ if (s->path == NULL) { char path[1024]; snprintf(path, sizeof(path), "%s/%s", e->conf.path, s->name); s->path = ss_strdup(&e->a, path); if (ssunlikely(s->path == NULL)) return sr_oom(&e->error); } /* backup path */ s->path_backup = e->conf.backup_path; if (e->conf.backup_path) { s->path_backup = ss_strdup(&e->a, e->conf.backup_path); if (ssunlikely(s->path_backup == NULL)) return sr_oom(&e->error); } /* cache */ if (s->cache_sz) { sedb *cache = (sedb*)se_dbmatch(e, s->cache_sz); if (ssunlikely(cache == NULL)) { sr_error(&e->error, "could not find cache database '%s'", s->cache_sz); return -1; } if (ssunlikely(cache == db)) { sr_error(&e->error, "bad cache database '%s'", s->cache_sz); return -1; } if (! cache->scheme.cache_mode) { sr_error(&e->error, "database '%s' is not in cache mode", s->cache_sz); return -1; } if (! sr_schemeeq(&db->scheme.scheme, &cache->scheme.scheme)) { sr_error(&e->error, "database and cache '%s' scheme mismatch", s->cache_sz); return -1; } se_dbref(cache, 0); db->cache = cache; } db->r.scheme = &s->scheme; db->r.fmt = s->fmt; db->r.fmt_storage = s->fmt_storage; db->r.fmt_upsert = &s->fmt_upsert; return 0; }
#include <libsf.h> #include <libsr.h> #include <libso.h> #include <libsv.h> #include <libsl.h> #include <libsd.h> #include <libsi.h> #include <libsx.h> #include <libsy.h> #include <libse.h> static int se_vdestroy(so *o) { sev *v = se_cast(o, sev*, SEV); se *e = se_of(o); if (v->v.v) sv_vfree(&e->a, (svv*)v->v.v); v->v.v = NULL; se_mark_destroyed(&v->o); ss_free(&e->a_v, v); return 0; } static sfv* se_vsetpart(sev *v, char *path, void *pointer, int size) { se *e = se_of(&v->o); sedb *db = (sedb*)v->o.parent; srkey *part = sr_schemefind(&db->scheme.scheme, path); if (ssunlikely(part == NULL))
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; }
static int se_dbscheme_init(sedb *db, char *name) { se *e = se_of(&db->o); /* prepare index scheme */ sischeme *scheme = &db->scheme; scheme->name = ss_strdup(&e->a, name); if (ssunlikely(scheme->name == NULL)) goto e0; scheme->id = sr_seq(&e->seq, SR_DSNNEXT); scheme->sync = 2; scheme->mmap = 0; scheme->storage = SI_SCACHE; scheme->cache_mode = 0; scheme->cache_sz = NULL; scheme->node_size = 64 * 1024 * 1024; scheme->node_compact_load = 0; scheme->node_page_size = 128 * 1024; scheme->node_page_checksum = 1; scheme->compression_key = 0; scheme->compression = 0; scheme->compression_if = &ss_nonefilter; scheme->compression_branch = 0; scheme->compression_branch_if = &ss_nonefilter; scheme->amqf = 0; scheme->fmt = SF_KV; scheme->fmt_storage = SF_SRAW; scheme->path_fail_on_exists = 0; scheme->path_fail_on_drop = 1; scheme->lru = 0; scheme->lru_step = 128 * 1024; scheme->buf_gc_wm = 1024 * 1024; scheme->storage_sz = ss_strdup(&e->a, "cache"); if (ssunlikely(scheme->storage_sz == NULL)) goto e1; scheme->compression_sz = ss_strdup(&e->a, scheme->compression_if->name); if (ssunlikely(scheme->compression_sz == NULL)) goto e1; scheme->compression_branch_sz = ss_strdup(&e->a, scheme->compression_branch_if->name); if (ssunlikely(scheme->compression_branch_sz == NULL)) goto e1; sf_upsertinit(&scheme->fmt_upsert); scheme->fmt_sz = ss_strdup(&e->a, "kv"); if (ssunlikely(scheme->fmt_sz == NULL)) goto e1; /* init single key part as string */ int rc; sr_schemeinit(&scheme->scheme); srkey *part = sr_schemeadd(&scheme->scheme); rc = sr_keysetname(part, &e->a, "key"); if (ssunlikely(rc == -1)) goto e1; rc = sr_keyset(part, &e->a, "string"); if (ssunlikely(rc == -1)) goto e1; return 0; e1: si_schemefree(&db->scheme, &db->r); e0: sr_oom(&e->error); return -1; }
static void* se_asyncbegin(so *o) { se *e = se_of(o); return se_txnew(e, 1); }