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); /* 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 == SVUPSERT && !sf_upserthas(&db->scheme.fmt_upsert)) flags = 0; /* prepare document */ 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 = sv_vsize(v); 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 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; }