int si_schemerecover(sischeme *s, sr *r) { sdscheme c; sd_schemeinit(&c); char path[PATH_MAX]; snprintf(path, sizeof(path), "%s/scheme", s->path); int version_storage_set = 0; int rc; rc = sd_schemerecover(&c, r, path); if (ssunlikely(rc == -1)) goto error; ssiter i; ss_iterinit(sd_schemeiter, &i); rc = ss_iteropen(sd_schemeiter, &i, r, &c, 1); if (ssunlikely(rc == -1)) goto error; while (ss_iterhas(sd_schemeiter, &i)) { sdschemeopt *opt = ss_iterof(sd_schemeiter, &i); switch (opt->id) { case SI_SCHEME_VERSION: break; case SI_SCHEME_VERSION_STORAGE: { if (opt->size != sizeof(srversion)) goto error; srversion *version = (srversion*)sd_schemesz(opt); if (! sr_versionstorage_check(version)) goto error_format; version_storage_set = 1; break; } case SI_SCHEME_SCHEME: { sf_schemefree(&s->scheme, r->a); sf_schemeinit(&s->scheme); ssbuf buf; ss_bufinit(&buf); rc = sf_schemeload(&s->scheme, r->a, sd_schemesz(opt), opt->size); if (ssunlikely(rc == -1)) goto error; rc = sf_schemevalidate(&s->scheme, r->a); if (ssunlikely(rc == -1)) goto error; ss_buffree(&buf, r->a); break; } case SI_SCHEME_NODE_SIZE: s->compaction.node_size = sd_schemeu64(opt); break; case SI_SCHEME_NODE_PAGE_SIZE: s->compaction.node_page_size = sd_schemeu32(opt); break; case SI_SCHEME_COMPRESSION: { char *name = sd_schemesz(opt); ssfilterif *cif = ss_filterof(name); if (ssunlikely(cif == NULL)) goto error; s->compression_if = cif; s->compression = s->compression_if != &ss_nonefilter; ss_free(r->a, s->compression_sz); s->compression_sz = ss_strdup(r->a, cif->name); if (ssunlikely(s->compression_sz == NULL)) goto error; break; } case SI_SCHEME_EXPIRE: s->expire = sd_schemeu32(opt); break; default: /* skip unknown */ break; } ss_iternext(sd_schemeiter, &i); } if (ssunlikely(! version_storage_set)) goto error_format; sd_schemefree(&c, r); return 0; error_format: sr_error(r->e, "%s", "incompatible storage format version"); error: sd_schemefree(&c, r); 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; }
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; }
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 si_schemerecover(sischeme *s, sr *r) { sdscheme c; sd_schemeinit(&c); char path[PATH_MAX]; snprintf(path, sizeof(path), "%s/scheme", s->path); int rc; rc = sd_schemerecover(&c, r, path); if (ssunlikely(rc == -1)) goto error; ssiter i; ss_iterinit(sd_schemeiter, &i); rc = ss_iteropen(sd_schemeiter, &i, r, &c, 1); if (ssunlikely(rc == -1)) goto error; while (ss_iterhas(sd_schemeiter, &i)) { sdschemeopt *opt = ss_iterof(sd_schemeiter, &i); switch (opt->id) { case SI_SCHEME_FORMAT: s->fmt = sd_schemeu32(opt); char *name; if (s->fmt == SF_KV) name = "kv"; else if (s->fmt == SF_DOCUMENT) name = "document"; else goto error; ss_free(r->a, s->fmt_sz); s->fmt_sz = ss_strdup(r->a, name); if (ssunlikely(s->fmt_sz == NULL)) goto error; break; case SI_SCHEME_FORMAT_STORAGE: s->fmt_storage = sd_schemeu32(opt); break; case SI_SCHEME_SCHEME: { sr_schemefree(&s->scheme, r->a); sr_schemeinit(&s->scheme); ssbuf buf; ss_bufinit(&buf); rc = sr_schemeload(&s->scheme, r->a, sd_schemesz(opt), opt->size); if (ssunlikely(rc == -1)) goto error; ss_buffree(&buf, r->a); break; } case SI_SCHEME_NODE_SIZE: s->node_size = sd_schemeu64(opt); break; case SI_SCHEME_NODE_PAGE_SIZE: s->node_page_size = sd_schemeu32(opt); break; case SI_SCHEME_COMPRESSION_KEY: s->compression_key = sd_schemeu32(opt); break; case SI_SCHEME_COMPRESSION: { char *name = sd_schemesz(opt); ssfilterif *cif = ss_filterof(name); if (ssunlikely(cif == NULL)) goto error; s->compression_if = cif; s->compression = s->compression_if != &ss_nonefilter; ss_free(r->a, s->compression_sz); s->compression_sz = ss_strdup(r->a, cif->name); if (ssunlikely(s->compression_sz == NULL)) goto error; break; } case SI_SCHEME_COMPRESSION_BRANCH: { char *name = sd_schemesz(opt); ssfilterif *cif = ss_filterof(name); if (ssunlikely(cif == NULL)) goto error; s->compression_branch_if = cif; s->compression_branch = s->compression_branch_if != &ss_nonefilter; ss_free(r->a, s->compression_branch_sz); s->compression_branch_sz = ss_strdup(r->a, cif->name); if (ssunlikely(s->compression_branch_sz == NULL)) goto error; break; } case SI_SCHEME_AMQF: s->amqf = sd_schemeu32(opt); break; case SI_SCHEME_CACHE_MODE: s->cache_mode = sd_schemeu32(opt); break; case SI_SCHEME_EXPIRE: s->expire = sd_schemeu32(opt); break; default: /* skip unknown */ break; } ss_iternext(sd_schemeiter, &i); } sd_schemefree(&c, r); return 0; error: sd_schemefree(&c, r); return -1; }