summaryrefslogtreecommitdiffstats
path: root/src/dbutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dbutil.c')
-rw-r--r--src/dbutil.c180
1 files changed, 163 insertions, 17 deletions
diff --git a/src/dbutil.c b/src/dbutil.c
index 407593a..535b665 100644
--- a/src/dbutil.c
+++ b/src/dbutil.c
@@ -22,18 +22,20 @@
#include <assert.h>
#include <time.h>
+#include <zlib.h>
+
#include "dbutil.h"
#include "util.h"
-int get_meta_by_name_md(struct syrep_db_context *c, const struct syrep_name*name, const struct syrep_md *md, struct syrep_meta *meta) {
+int get_meta_by_nrecno_md(struct syrep_db_context *c, const struct syrep_nrecno*nrecno, const struct syrep_md *md, struct syrep_meta *meta) {
int ret;
struct syrep_id id;
DBT key, data;
- assert(c && c->db_id_meta && name);
+ assert(c && c->db_id_meta && nrecno);
memset(&id, 0, sizeof(id));
- memcpy(&id.name, name, sizeof(struct syrep_name));
+ memcpy(&id.nrecno, nrecno, sizeof(struct syrep_nrecno));
memcpy(&id.md, md, sizeof(struct syrep_md));
memset(&key, 0, sizeof(key));
@@ -59,7 +61,7 @@ int get_meta_by_name_md(struct syrep_db_context *c, const struct syrep_name*name
}
-int get_current_name_by_md(struct syrep_db_context *c, const struct syrep_md *md, struct syrep_name *name) {
+int get_current_nrecno_by_md(struct syrep_db_context *c, const struct syrep_md *md, struct syrep_nrecno *nrecno) {
int ret, f;
struct syrep_meta meta;
DBT key, data;
@@ -69,17 +71,17 @@ int get_current_name_by_md(struct syrep_db_context *c, const struct syrep_md *md
key.data = (void*) md;
key.size = sizeof(struct syrep_md);
- if ((ret = c->db_md_lastname->get(c->db_md_lastname, NULL, &key, &data, 0))) {
+ if ((ret = c->db_md_lastnrecno->get(c->db_md_lastnrecno, NULL, &key, &data, 0))) {
if (ret == DB_NOTFOUND)
return 0;
- c->db_md_lastname->err(c->db_md_lastname, ret, "md_lastname::get()");
+ c->db_md_lastnrecno->err(c->db_md_lastnrecno, ret, "md_lastnrecno::get()");
return -1;
}
assert(data.data);
- if ((f = get_meta_by_name_md(c, (struct syrep_name*) data.data, md, &meta)) < 0)
+ if ((f = get_meta_by_nrecno_md(c, (struct syrep_nrecno*) data.data, md, &meta)) < 0)
return -1;
if (!f) {
@@ -90,28 +92,28 @@ int get_current_name_by_md(struct syrep_db_context *c, const struct syrep_md *md
if (meta.last_seen != c->version)
return 0;
- if (name)
- memcpy(name, data.data, sizeof(struct syrep_name));
+ if (nrecno)
+ memcpy(nrecno, data.data, sizeof(struct syrep_nrecno));
return 1;
}
-int get_last_md_by_name(struct syrep_db_context *c, const struct syrep_name *name, struct syrep_md *md) {
+int get_last_md_by_nrecno(struct syrep_db_context *c, const struct syrep_nrecno *nrecno, struct syrep_md *md) {
int ret;
DBT key, data;
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
- key.data = (void*) name;
- key.size = sizeof(struct syrep_name);
+ key.data = (void*) nrecno;
+ key.size = sizeof(struct syrep_nrecno);
- if ((ret = c->db_name_lastmd->get(c->db_name_lastmd, NULL, &key, &data, 0))) {
+ if ((ret = c->db_nrecno_lastmd->get(c->db_nrecno_lastmd, NULL, &key, &data, 0))) {
if (ret == DB_NOTFOUND) {
return 0;
}
- c->db_name_lastmd->err(c->db_name_lastmd, ret, "name_lastmd::get()");
+ c->db_nrecno_lastmd->err(c->db_nrecno_lastmd, ret, "nrecno_lastmd::get()");
return -1;
}
@@ -124,18 +126,18 @@ int get_last_md_by_name(struct syrep_db_context *c, const struct syrep_name *nam
}
-int get_current_md_by_name(struct syrep_db_context *c, const struct syrep_name *name, struct syrep_md *md) {
+int get_current_md_by_nrecno(struct syrep_db_context *c, const struct syrep_nrecno *nrecno, struct syrep_md *md) {
struct syrep_md lmd;
struct syrep_meta meta;
int f;
- if ((f = get_last_md_by_name(c, name, &lmd)) < 0)
+ if ((f = get_last_md_by_nrecno(c, nrecno, &lmd)) < 0)
return -1;
if (!f)
return 0;
- if ((f = get_meta_by_name_md(c, name, &lmd, &meta)) < 0)
+ if ((f = get_meta_by_nrecno_md(c, nrecno, &lmd, &meta)) < 0)
return -1;
if (!f) {
@@ -185,3 +187,147 @@ uint32_t get_version_timestamp(struct syrep_db_context *c, uint32_t v) {
return timestamp->t;
}
+int get_name_by_nrecno(struct syrep_db_context *c, const struct syrep_nrecno *nrecno, struct syrep_name *name) {
+ DBT key, data;
+ int ret;
+
+ assert(c && nrecno);
+
+ memset(&key, 0, sizeof(key));
+ memset(&data, 0, sizeof(data));
+
+ key.data = (void*) &nrecno->recno;
+ key.size = sizeof(nrecno->recno);
+
+ if ((ret = c->db_nrecno_name->get(c->db_nrecno_name, NULL, &key, &data, 0))) {
+ if (ret == DB_NOTFOUND)
+ return 0;
+
+ c->db_nrecno_name->err(c->db_nrecno_name, ret, "nrecno_name::get");
+ return -1;
+ }
+
+ if (name) {
+ memset(name, 0, sizeof(struct syrep_name));
+ strncpy(name->path, data.data, MIN(PATH_MAX, data.size));
+ }
+
+ return 1;
+}
+
+static uint32_t csum_name(const struct syrep_name *name) {
+ uint32_t a;
+
+ assert(name);
+
+ a = adler32(0, NULL, 0);
+ a = adler32(a, name->path, strlen(name->path));
+
+ return a;
+}
+
+int get_nrecno_by_name(struct syrep_db_context *c, const struct syrep_name *rname, struct syrep_nrecno *rnrecno, int create) {
+ struct syrep_nhash nhash;
+ DBT key, data;
+ DBC *cursor = NULL;
+ int r = -1, ret;
+
+ assert(c && rname);
+
+ if ((ret = c->db_nhash_nrecno->cursor(c->db_nhash_nrecno, NULL, &cursor, 0)) != 0) {
+ c->db_nhash_nrecno->err(c->db_nhash_nrecno, ret, "nhash_nrecno");
+ goto finish;
+ }
+
+ memset(&key, 0, sizeof(key));
+ memset(&data, 0, sizeof(data));
+
+ nhash.hash = csum_name(rname);
+ key.data = &nhash;
+ key.size = sizeof(nhash);
+
+ ret = cursor->c_get(cursor, &key, &data, DB_SET);
+
+ for(;;) {
+ struct syrep_nrecno nrecno;
+ struct syrep_name name;
+ int f;
+
+ if (ret != 0) {
+ if (ret == DB_NOTFOUND) {
+
+ r = 0;
+ goto finish;
+ }
+
+ c->db_nhash_nrecno->err(c->db_nhash_nrecno, ret, "nhash_nrecno::get");
+ goto finish;
+ }
+
+ memcpy(&nrecno, data.data, sizeof(nrecno));
+
+ if ((f = get_name_by_nrecno(c, &nrecno, &name)) < 0)
+ goto finish;
+
+ if (f && !strcmp(name.path, rname->path)) {
+ if (rnrecno)
+ memcpy(rnrecno, &nrecno, sizeof(struct syrep_nrecno));
+
+ r = 1;
+ goto finish;
+ }
+
+ ret = cursor->c_get(cursor, &key, &data, DB_NEXT);
+ }
+
+finish:
+
+ if (cursor)
+ cursor->c_close(cursor);
+
+ if (!r && create)
+ r = new_name(c, rname, rnrecno) < 0 ? -1 : 1;
+
+ return r;
+}
+
+int new_name(struct syrep_db_context *c, const struct syrep_name *name, struct syrep_nrecno *rnrecno) {
+ struct syrep_nhash nhash;
+ struct syrep_nrecno nrecno;
+ int ret;
+ DBT key, data;
+ assert(c && name);
+
+ memset(&key, 0, sizeof(key));
+ memset(&data, 0, sizeof(data));
+
+ data.data = (void*) name->path;
+ data.size = strlen(name->path);
+
+ if ((ret = c->db_nrecno_name->put(c->db_nrecno_name, NULL, &key, &data, DB_APPEND))) {
+ c->db_nrecno_name->err(c->db_nrecno_name, ret, "nrecno_name::put");
+ return -1;
+ }
+
+ nrecno.recno = *((db_recno_t*) data.data);
+
+ memset(&key, 0, sizeof(key));
+ memset(&data, 0, sizeof(data));
+
+ nhash.hash = csum_name(name);
+ key.data = &nhash;
+ key.size = sizeof(nhash);
+
+ data.data = &nrecno;
+ data.size = sizeof(nrecno);
+
+ if ((ret = c->db_nhash_nrecno->put(c->db_nhash_nrecno, NULL, &key, &data, 0))) {
+ c->db_nhash_nrecno->err(c->db_nhash_nrecno, ret, "nhash_nrecno::put");
+ return -1;
+ }
+
+ if (rnrecno)
+ memcpy(rnrecno, &nrecno, sizeof(struct syrep_nrecno));
+
+ return 0;
+}