From 26973e55d522e6e35a7618646cbdc7f4bf99e152 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 31 Aug 2003 20:46:56 +0000 Subject: filename hashing implemented git-svn-id: file:///home/lennart/svn/public/syrep/trunk@19 07ea20a6-d2c5-0310-9e02-9ef735347d72 --- src/Makefile | 2 +- src/context.c | 78 +++++++++++++++--------- src/context.h | 12 ++-- src/dbstruct.h | 50 +++++++++++++--- src/dbutil.c | 180 ++++++++++++++++++++++++++++++++++++++++++++++++++------ src/dbutil.h | 13 ++-- src/diff.c | 72 ++++++++++++++++------- src/info.c | 22 ++++--- src/list.c | 67 +++++++-------------- src/makepatch.c | 7 ++- src/merge.c | 26 ++++++-- src/update.c | 39 ++++++++---- src/util.c | 2 +- 13 files changed, 409 insertions(+), 161 deletions(-) (limited to 'src') diff --git a/src/Makefile b/src/Makefile index 9f74fd3..8aefef0 100644 --- a/src/Makefile +++ b/src/Makefile @@ -4,7 +4,7 @@ CC=gcc all: syrep syrep: cache.o update.o util.o syrep.o md5.o md5util.o context.o package.o dbutil.o cmdline.o info.o history.o dump.o list.o diff.o merge.o extract.o makepatch.o cleanup.o - $(CC) -g $^ -o $@ -ldb + $(CC) -g $^ -o $@ -ldb -lz cmdline.c cmdline.h: syrep.ggo Makefile gengetopt --unamed-opts < $< diff --git a/src/context.c b/src/context.c index 7052bad..1249669 100644 --- a/src/context.c +++ b/src/context.c @@ -37,21 +37,27 @@ int db_context_free(struct syrep_db_context* c) { if (c->db_id_meta) c->db_id_meta->close(c->db_id_meta, 0); - if (c->db_md_name) - c->db_md_name->close(c->db_md_name, 0); + if (c->db_md_nrecno) + c->db_md_nrecno->close(c->db_md_nrecno, 0); - if (c->db_name_md) - c->db_name_md->close(c->db_name_md, 0); + if (c->db_nrecno_md) + c->db_nrecno_md->close(c->db_nrecno_md, 0); - if (c->db_md_lastname) - c->db_md_lastname->close(c->db_md_lastname, 0); + if (c->db_md_lastnrecno) + c->db_md_lastnrecno->close(c->db_md_lastnrecno, 0); - if (c->db_name_lastmd) - c->db_name_lastmd->close(c->db_name_lastmd, 0); + if (c->db_nrecno_lastmd) + c->db_nrecno_lastmd->close(c->db_nrecno_lastmd, 0); if (c->db_version_timestamp) c->db_version_timestamp->close(c->db_version_timestamp, 0); + if (c->db_nhash_nrecno) + c->db_nhash_nrecno->close(c->db_nhash_nrecno, 0); + + if (c->db_nrecno_name) + c->db_nrecno_name->close(c->db_nrecno_name, 0); + if (c->package) package_remove(c->package); @@ -65,7 +71,7 @@ int db_context_free(struct syrep_db_context* c) { } -static DB* open_db(const char*path, int dup) { +static DB* open_db(const char*path, int dup, int recno) { int ret; DB* db; @@ -79,7 +85,7 @@ static DB* open_db(const char*path, int dup) { //db->set_pagesize(db, 4096*8); - if ((ret = db->open(db, NULL, path, NULL, DB_BTREE, DB_CREATE, 0664))) { + if ((ret = db->open(db, NULL, path, NULL, recno ? DB_RECNO : DB_BTREE, DB_CREATE, 0664))) { db->err(db, ret, "open(%s)", path); db->close(db, 0); return NULL; @@ -144,29 +150,37 @@ struct syrep_db_context* db_context_open(const char *filename, int force) { } /* Creating database id_meta */ - if (!(c->db_id_meta = open_db(package_get_item(c->package, "id_meta", 1), 0))) + if (!(c->db_id_meta = open_db(package_get_item(c->package, "id_meta", 1), 0, 0))) goto fail; - /* Creating database md_name */ - if (!(c->db_md_name = open_db(package_get_item(c->package, "md_name", 1), 1))) + /* Creating database md_nrecno */ + if (!(c->db_md_nrecno = open_db(package_get_item(c->package, "md_nrecno", 1), 1, 0))) goto fail; - /* Creating database name_md */ - if (!(c->db_name_md = open_db(package_get_item(c->package, "name_md", 1), 1))) + /* Creating database nrecno_md */ + if (!(c->db_nrecno_md = open_db(package_get_item(c->package, "nrecno_md", 1), 1, 0))) goto fail; - /* Creating database name_lastmd */ - if (!(c->db_name_lastmd = open_db(package_get_item(c->package, "name_lastmd", 1), 0))) + /* Creating database nrecno_lastmd */ + if (!(c->db_nrecno_lastmd = open_db(package_get_item(c->package, "nrecno_lastmd", 1), 0, 0))) goto fail; - /* Creating database md_lastname */ - if (!(c->db_md_lastname = open_db(package_get_item(c->package, "md_lastname", 1), 0))) + /* Creating database md_lastnrecno */ + if (!(c->db_md_lastnrecno = open_db(package_get_item(c->package, "md_lastnrecno", 1), 0, 0))) goto fail; /* Creating database version_timestamp */ - if (!(c->db_version_timestamp = open_db(package_get_item(c->package, "version_timestamp", 1), 0))) + if (!(c->db_version_timestamp = open_db(package_get_item(c->package, "version_timestamp", 1), 0, 0))) goto fail; + /* Creating database nhash_nrecno */ + if (!(c->db_nhash_nrecno = open_db(package_get_item(c->package, "nhash_nrecno", 1), 1, 0))) + goto fail; + + /* Creating database nrecno_name */ + if (!(c->db_nrecno_name = open_db(package_get_item(c->package, "nrecno_name", 1), 0, 1))) + goto fail; + return c; @@ -183,21 +197,27 @@ int db_context_save(struct syrep_db_context *c, const char *filename) { if (c->db_id_meta) c->db_id_meta->sync(c->db_id_meta, 0); - if (c->db_md_name) - c->db_md_name->sync(c->db_md_name, 0); + if (c->db_md_nrecno) + c->db_md_nrecno->sync(c->db_md_nrecno, 0); - if (c->db_name_md) - c->db_name_md->sync(c->db_name_md, 0); + if (c->db_nrecno_md) + c->db_nrecno_md->sync(c->db_nrecno_md, 0); - if (c->db_md_lastname) - c->db_md_lastname->sync(c->db_md_lastname, 0); + if (c->db_md_lastnrecno) + c->db_md_lastnrecno->sync(c->db_md_lastnrecno, 0); - if (c->db_name_lastmd) - c->db_name_lastmd->sync(c->db_name_lastmd, 0); + if (c->db_nrecno_lastmd) + c->db_nrecno_lastmd->sync(c->db_nrecno_lastmd, 0); if (c->db_version_timestamp) c->db_version_timestamp->sync(c->db_version_timestamp, 0); - + + if (c->db_nhash_nrecno) + c->db_nhash_nrecno->sync(c->db_nhash_nrecno, 0); + + if (c->db_nrecno_name) + c->db_nrecno_name->sync(c->db_nrecno_name, 0); + if (!(f = fopen(package_get_item(c->package, "timestamp", 1), "w+"))) return -1; diff --git a/src/context.h b/src/context.h index 96f4dcf..0a7aa03 100644 --- a/src/context.h +++ b/src/context.h @@ -28,11 +28,13 @@ struct syrep_db_context { struct package *package; DB *db_id_meta, - *db_md_name, - *db_name_md, - *db_name_lastmd, - *db_md_lastname, - *db_version_timestamp; + *db_md_nrecno, + *db_nrecno_md, + *db_nrecno_lastmd, + *db_md_lastnrecno, + *db_version_timestamp, + *db_nhash_nrecno, + *db_nrecno_name; uint32_t timestamp; uint32_t version; diff --git a/src/dbstruct.h b/src/dbstruct.h index 2df2aed..b5f0c26 100644 --- a/src/dbstruct.h +++ b/src/dbstruct.h @@ -3,22 +3,42 @@ /* $Id$ */ +/*** + This file is part of syrep. + + syrep is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + syrep is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with syrep; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +***/ + #include #include +#include + #include "syrep.h" struct syrep_md { - uint8_t digest[SYREP_DIGESTLENGTH]; + uint8_t digest[SYREP_DIGESTLENGTH]; }; -struct syrep_name { - char path[PATH_MAX+1]; +struct syrep_nrecno { /* name record number */ + db_recno_t recno; }; struct syrep_id { struct syrep_md md; - struct syrep_name name; + struct syrep_nrecno nrecno; }; struct syrep_meta { @@ -34,15 +54,27 @@ struct syrep_version { uint32_t v; }; +struct syrep_nhash { /* name hash */ + uint32_t hash; +}; + +struct syrep_name { + char path[PATH_MAX+1]; +}; + + /* Table layout: * * syrep_id :: syrep_meta => id_meta - * syrep_md :: syrep_name => md_name (DUP) - * syrep_name :: syrep_md => name_md (DUP) + * syrep_md :: syrep_nrecno => md_nrecno (DUP) + * syrep_nrecno :: syrep_md => nrecno_md (DUP) + * syrep_nrecno :: syrep_md => nrecno_lastmd + * syrep_md :: syrep_nrecono => md_lastnrecno + * * syrep_version :: syrep_timestamp => version_timestamp - * syrep_name :: syrep_md => name_lastmd - * syrep_md :: last_md => md_lastmd - * + * + * nhash :: nrecno => nhash_nrecno (DUP) + * nrecno :: name => nrecno_name */ #endif 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 #include +#include + #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; +} diff --git a/src/dbutil.h b/src/dbutil.h index f267e50..dd4acd2 100644 --- a/src/dbutil.h +++ b/src/dbutil.h @@ -24,10 +24,15 @@ #include "dbstruct.h" #include "context.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_last_md_by_name(struct syrep_db_context *c, const struct syrep_name *name, struct syrep_md *md); -int get_current_md_by_name(struct syrep_db_context *c, const struct syrep_name *name, struct syrep_md *md); -int get_current_name_by_md(struct syrep_db_context *c, const struct syrep_md *md, struct syrep_name *name); +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 get_last_md_by_nrecno(struct syrep_db_context *c, const struct syrep_nrecno *nrecno, struct syrep_md *md); +int get_current_md_by_nrecno(struct syrep_db_context *c, const struct syrep_nrecno *nrecno, struct syrep_md *md); +int get_current_nrecno_by_md(struct syrep_db_context *c, const struct syrep_md *md, struct syrep_nrecno *nrecno); uint32_t get_version_timestamp(struct syrep_db_context *c, uint32_t v); +int get_nrecno_by_name(struct syrep_db_context *c, const struct syrep_name *name, struct syrep_nrecno *nrecno, int create); +int get_name_by_nrecno(struct syrep_db_context *c, const struct syrep_nrecno *nrecno, struct syrep_name *name); + +int new_name(struct syrep_db_context *c, const struct syrep_name *name, struct syrep_nrecno *rnrecno); + #endif diff --git a/src/diff.c b/src/diff.c index 8338be9..b722198 100644 --- a/src/diff.c +++ b/src/diff.c @@ -72,29 +72,40 @@ static int add_diff_entry(DB *ddb, struct syrep_name *name, int action, struct s static int foreach(DB *ddb, struct syrep_db_context *c1, struct syrep_db_context *c2, struct syrep_name *name) { struct syrep_md md1, md2; - int md1_valid, md2_valid; + struct syrep_nrecno nrecno1, nrecno2; + int md1_valid = 0, md2_valid = 0; + int nrecno1_valid, nrecno2_valid; + if ((nrecno1_valid = get_nrecno_by_name(c1, name, &nrecno1, 0)) < 0) + return 1; - if ((md1_valid = get_current_md_by_name(c1, name, &md1)) < 0) - return -1; + if (nrecno1_valid) + if ((md1_valid = get_current_md_by_nrecno(c1, &nrecno1, &md1)) < 0) + return -1; - if ((md2_valid = get_current_md_by_name(c2, name, &md2)) < 0) - return -1; + if ((nrecno1_valid = get_nrecno_by_name(c1, name, &nrecno2, 0)) < 0) + return 1; + + if (nrecno2_valid) + if ((md2_valid = get_current_md_by_nrecno(c2, &nrecno2, &md2)) < 0) + return -1; //fprintf(stderr, "FOREACH %i %i %s\n", md1_valid, md2_valid, name->path); if (md1_valid && md2_valid) { - int f1, f2; + int f1 = 0, f2 = 0; /* Same file? */ if (!memcmp(&md1, &md2, sizeof(struct syrep_md))) return 0; - - if ((f1 = get_meta_by_name_md(c1, name, &md2, NULL)) < 0) + + if (nrecno1_valid) + if ((f1 = get_meta_by_nrecno_md(c1, &nrecno1, &md2, NULL)) < 0) + return -1; + + if (nrecno2_valid) + if ((f2 = get_meta_by_nrecno_md(c2, &nrecno2, &md1, NULL)) < 0) return -1; - - if ((f2 = get_meta_by_name_md(c2, name, &md1, NULL)) < 0) - return -1; /* The version in c1 is a newer version of that in c2 */ if (f1 && !f2) @@ -111,9 +122,10 @@ static int foreach(DB *ddb, struct syrep_db_context *c1, struct syrep_db_context struct syrep_meta meta1, meta2; int f1, f2; uint32_t t1, t2; - - if ((md2_valid = get_last_md_by_name(c2, name, &md2)) < 0) - return -1; + + if (nrecno2_valid) + if ((md2_valid = get_last_md_by_nrecno(c2, &nrecno2, &md2)) < 0) + return -1; if (!md2_valid) return add_diff_entry(ddb, name, DIFF_COPY, c1); @@ -121,10 +133,10 @@ static int foreach(DB *ddb, struct syrep_db_context *c1, struct syrep_db_context if (memcmp(&md1, &md2, sizeof(struct syrep_md))) return add_diff_entry(ddb, name, DIFF_COPY, c1); - if ((f1 = get_meta_by_name_md(c1, name, &md1, &meta1)) < 0) + if ((f1 = get_meta_by_nrecno_md(c1, &nrecno1, &md1, &meta1)) < 0) return -1; - if ((f2 = get_meta_by_name_md(c2, name, &md2, &meta2)) < 0) + if ((f2 = get_meta_by_nrecno_md(c2, &nrecno2, &md2, &meta2)) < 0) return -1; if (!f1 || !f2) { @@ -180,6 +192,8 @@ static int enumerate(DB *ddb, struct syrep_db_context *c1, struct syrep_db_conte while ((ret = cursor->c_get(cursor, &key, &data, DB_NEXT)) == 0) { struct syrep_id *id = (struct syrep_id*) key.data; struct syrep_meta *meta = (struct syrep_meta*) data.data; + struct syrep_name name; + int f; assert(id && meta); @@ -190,10 +204,15 @@ static int enumerate(DB *ddb, struct syrep_db_context *c1, struct syrep_db_conte if (meta->last_seen != c1->version) continue; - - if (foreach(ddb, c1, c2, &id->name) < 0) { - fprintf(stderr, "foreach() failed\n"); - goto finish; + + if ((f = get_name_by_nrecno(c1, &id->nrecno, &name)) < 0) + return -1; + + if (f) { + if (foreach(ddb, c1, c2, &name) < 0) { + fprintf(stderr, "foreach() failed\n"); + goto finish; + } } rotdash(); @@ -254,16 +273,25 @@ struct cb_info { static int list_cb(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *p) { struct syrep_md md1, md2; + struct syrep_nrecno nrecno1, nrecno2; int f1, f2; struct cb_info *cb_info = p; assert(name && de); - if ((f1 = get_last_md_by_name(cb_info->c1, name, &md1)) < 0) + if ((f1 = get_nrecno_by_name(cb_info->c1, name, &nrecno1, 0)) < 0) return -1; - if ((f2 = get_last_md_by_name(cb_info->c2, name, &md2)) < 0) + if (f1) + if ((f1 = get_last_md_by_nrecno(cb_info->c1, &nrecno1, &md1)) < 0) + return -1; + + if ((f2 = get_nrecno_by_name(cb_info->c2, name, &nrecno2, 0)) < 0) return -1; + + if (f2) + if ((f2 = get_last_md_by_nrecno(cb_info->c2, &nrecno2, &md2)) < 0) + return -1; if (!(f1 || f2)) { fprintf(stderr, "Diff inconsicteny\n"); diff --git a/src/info.c b/src/info.c index 698088b..f82473d 100644 --- a/src/info.c +++ b/src/info.c @@ -29,17 +29,21 @@ int info(struct syrep_db_context *c) { fprintf(stderr, "Origin: %s\n", c->origin); fprintf(stderr, "Timestamp: %u\n", c->timestamp); fprintf(stderr, "Version: %u\n", c->version); - fprintf(stderr, "Database name_meta: "); + fprintf(stderr, "Database nrecno_meta: "); statistics(c->db_id_meta); - fprintf(stderr, "Database md_name: "); - statistics(c->db_md_name); - fprintf(stderr, "Database name_md: "); - statistics(c->db_name_md); - fprintf(stderr, "Database name_lastmd: "); - statistics(c->db_name_lastmd); - fprintf(stderr, "Database md_lastname: "); - statistics(c->db_md_lastname); + fprintf(stderr, "Database md_nrecno: "); + statistics(c->db_md_nrecno); + fprintf(stderr, "Database nrecno_md: "); + statistics(c->db_nrecno_md); + fprintf(stderr, "Database nrecno_lastmd: "); + statistics(c->db_nrecno_lastmd); + fprintf(stderr, "Database md_lastnrecno: "); + statistics(c->db_md_lastnrecno); fprintf(stderr, "Database version_timestamp: "); statistics(c->db_version_timestamp); + fprintf(stderr, "Database nrecno_name: "); + statistics(c->db_nrecno_name); + fprintf(stderr, "Database nhash_nrecno: "); + statistics(c->db_nhash_nrecno); return 0; } diff --git a/src/list.c b/src/list.c index 333a780..e5fe62f 100644 --- a/src/list.c +++ b/src/list.c @@ -30,13 +30,21 @@ #include "dbutil.h" #include "syrep.h" -static int handle_file(struct syrep_db_context *c, const struct syrep_name *name, const struct syrep_md *md, const struct syrep_meta *meta) { +static int handle_file(struct syrep_db_context *c, const struct syrep_nrecno *nrecno, const struct syrep_md *md, const struct syrep_meta *meta) { struct syrep_meta local_meta; - assert(c && name && md); + struct syrep_name name; + int f; + + assert(c && nrecno && md); + + if ((f = get_name_by_nrecno(c, nrecno, &name)) < 0) + return -1; + assert(f); + if (!meta) { int f; - if ((f = get_meta_by_name_md(c, name, md, &local_meta)) < 0) + if ((f = get_meta_by_nrecno_md(c, nrecno, md, &local_meta)) < 0) return -1; if (f) @@ -52,9 +60,9 @@ static int handle_file(struct syrep_db_context *c, const struct syrep_name *name fhex(md->digest, SYREP_DIGESTLENGTH, d); d[SYREP_DIGESTLENGTH*2] = 0; - printf("%s %s%s", d, name->path, meta->last_seen == c->version ? "\t\t" : "\t(deleted)"); + printf("%s %s%s", d, name.path, meta->last_seen == c->version ? "\t\t" : "\t(deleted)"); } else - printf("\t%s%s", name->path, meta->last_seen == c->version ? "\t\t" : "\t(deleted)"); + printf("\t%s%s", name.path, meta->last_seen == c->version ? "\t\t" : "\t(deleted)"); if (args.show_times_flag) printf( "\t(first-seen: %u; last-seen: %u)\n", meta->first_seen, meta->last_seen); @@ -65,7 +73,7 @@ static int handle_file(struct syrep_db_context *c, const struct syrep_name *name fhex(md->digest, SYREP_DIGESTLENGTH, d); d[SYREP_DIGESTLENGTH*2] = 0; - printf("\t%s", name->path); + printf("\t%s", name.path); } return 0; @@ -76,45 +84,12 @@ int list(struct syrep_db_context *c) { DBC *cursor = NULL; DBT key, data; - -#if 1 - - { - if ((ret = c->db_name_lastmd->cursor(c->db_name_lastmd, NULL, &cursor, 0)) != 0) { - c->db_name_lastmd->err(c->db_name_lastmd, ret, "db_name_lastmd"); - goto finish; - } - - memset(&key, 0, sizeof(key)); - memset(&data, 0, sizeof(data)); - - while ((ret = cursor->c_get(cursor, &key, &data, DB_NEXT)) == 0) { - struct syrep_name *name = (struct syrep_name*) key.data; - struct syrep_md *md = (struct syrep_md*) data.data; - - if (handle_file(c, name, md, NULL) < 0) - fprintf(stderr, "handle_file() failed\n"); - - } - - if (ret != DB_NOTFOUND) { - c->db_name_lastmd->err(c->db_name_lastmd, ret, "name_lastmd::c_get"); - goto finish; - } - - r = 0; - } - - goto finish; - -#endif - if (args.show_by_md_flag) { struct syrep_md previous_md; memset(&previous_md, 0, sizeof(previous_md)); - if ((ret = c->db_md_name->cursor(c->db_md_name, NULL, &cursor, 0)) != 0) { - c->db_md_name->err(c->db_md_name, ret, "md_name"); + if ((ret = c->db_md_nrecno->cursor(c->db_md_nrecno, NULL, &cursor, 0)) != 0) { + c->db_md_nrecno->err(c->db_md_nrecno, ret, "md_nrecno"); goto finish; } @@ -123,7 +98,7 @@ int list(struct syrep_db_context *c) { while ((ret = cursor->c_get(cursor, &key, &data, DB_NEXT)) == 0) { struct syrep_md *md = (struct syrep_md*) key.data; - struct syrep_name *name = (struct syrep_name*) data.data; + struct syrep_nrecno *recno = (struct syrep_nrecno*) data.data; struct syrep_meta meta; if (memcmp(&previous_md, md, sizeof(previous_md))) { @@ -134,15 +109,15 @@ int list(struct syrep_db_context *c) { memcpy(&previous_md, md, sizeof(previous_md)); } - if ((ret = get_meta_by_name_md(c, name, md, &meta)) < 0) + if ((ret = get_meta_by_nrecno_md(c, recno, md, &meta)) < 0) goto finish; - if (handle_file(c, name, md, &meta) < 0) + if (handle_file(c, recno, md, &meta) < 0) fprintf(stderr, "handle_file() failed\n"); } if (ret != DB_NOTFOUND) { - c->db_md_name->err(c->db_md_name, ret, "md_name::c_get"); + c->db_md_nrecno->err(c->db_md_nrecno, ret, "md_nrecno::c_get"); goto finish; } @@ -160,7 +135,7 @@ int list(struct syrep_db_context *c) { while ((ret = cursor->c_get(cursor, &key, &data, DB_NEXT)) == 0) { struct syrep_id *id = (struct syrep_id*) key.data; - if (handle_file(c, &id->name, &id->md, (struct syrep_meta*) data.data) < 0) + if (handle_file(c, &id->nrecno, &id->md, (struct syrep_meta*) data.data) < 0) fprintf(stderr, "handle_file() failed\n"); } diff --git a/src/makepatch.c b/src/makepatch.c index 5ae5b29..8bf1ee5 100644 --- a/src/makepatch.c +++ b/src/makepatch.c @@ -37,6 +37,7 @@ struct cb_info { static int cb(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *p) { struct cb_info *cb_info = p; struct syrep_md md; + struct syrep_nrecno nrecno; char path[PATH_MAX+1]; char d[SYREP_DIGESTLENGTH*2+1]; int f; @@ -46,9 +47,13 @@ static int cb(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *p) if (de->action != DIFF_COPY && de->action != DIFF_CONFLICT) return 0; - if ((f = get_current_md_by_name(cb_info->c1, name, &md)) < 0) + if ((f = get_nrecno_by_name(cb_info->c1, name, &nrecno, 0)) < 0) return -1; + if (f) + if ((f = get_current_md_by_nrecno(cb_info->c1, &nrecno, &md)) < 0) + return -1; + if (!f) return 0; diff --git a/src/merge.c b/src/merge.c index b281b06..206e2d9 100644 --- a/src/merge.c +++ b/src/merge.c @@ -44,6 +44,7 @@ struct cb_info { static int conflict_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *p) { struct cb_info *cb_info = p; struct syrep_md md1, md2; + struct syrep_nrecno nrecno1, nrecno2; int writeback = 0; int f1, f2; char path[PATH_MAX+1]; @@ -53,11 +54,19 @@ static int conflict_phase(DB *ddb, struct syrep_name *name, struct diff_entry *d if (de->action != DIFF_CONFLICT) return 0; - if ((f1 = get_current_md_by_name(cb_info->c1, name, &md1)) < 0) + if ((f1 = get_nrecno_by_name(cb_info->c1, name, &nrecno1, 0)) < 0) return -1; - if ((f2 = get_current_md_by_name(cb_info->c2, name, &md2)) < 0) + if (f1) + if ((f1 = get_current_md_by_nrecno(cb_info->c1, &nrecno1, &md1)) < 0) + return -1; + + if ((f2 = get_nrecno_by_name(cb_info->c2, name, &nrecno1, 0)) < 0) return -1; + + if (f2) + if ((f2 = get_current_md_by_nrecno(cb_info->c2, &nrecno2, &md2)) < 0) + return -1; snprintf(path, sizeof(path), "%s/%s", cb_info->root, name->path); @@ -161,6 +170,7 @@ static char *escape_path(const char *path, char *dst, unsigned l) { static int copy_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *p) { struct cb_info *cb_info = p; struct syrep_name name2; + struct syrep_nrecno nrecno, nrecno2; struct syrep_md md; char path[PATH_MAX+1]; int f; @@ -176,9 +186,13 @@ static int copy_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, v snprintf(path, sizeof(path), "%s/%s", cb_info->root, name->path); - if ((f = get_current_md_by_name(cb_info->c1, name, &md)) < 0) + if ((f = get_nrecno_by_name(cb_info->c1, name, &nrecno, 0)) < 0) return -1; + if (f) + if ((f = get_current_md_by_nrecno(cb_info->c1, &nrecno, &md)) < 0) + return -1; + if (!f) { fprintf(stderr, "Diff invalid!\n"); return -1; @@ -187,8 +201,12 @@ static int copy_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, v fhex(md.digest, SYREP_DIGESTLENGTH, d); d[SYREP_DIGESTLENGTH*2] = 0; - if ((f = get_current_name_by_md(cb_info->c2, &md, &name2)) < 0) + if ((f = get_current_nrecno_by_md(cb_info->c2, &md, &nrecno2)) < 0) return -1; + + if (f) + if ((f = get_name_by_nrecno(cb_info->c2, &nrecno2, &name2)) < 0) + return -1; if (f) { char path2[PATH_MAX+1]; diff --git a/src/update.c b/src/update.c index 0c65d4c..06986f9 100644 --- a/src/update.c +++ b/src/update.c @@ -57,32 +57,38 @@ static int dbput(DB* db, const void *k, int klen, const void*d, int dlen, int f) static int write_entry(struct syrep_db_context *c, const struct syrep_name *name, const struct syrep_md *md, const struct syrep_meta *meta) { struct syrep_id id; + struct syrep_nrecno nrecno; int f; - assert(c && c->db_id_meta && c->db_md_name && c->db_name_md && c->db_md_lastname && c->db_name_lastmd && name && md && meta); + assert(c && c->db_id_meta && c->db_md_nrecno && c->db_nrecno_md && c->db_md_lastnrecno && c->db_nrecno_lastmd && name && md && meta); + if ((f = get_nrecno_by_name(c, name, &nrecno, 1)) < 0) + return -1; + + assert(f); + /*** Update id_meta ***/ 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)); if (dbput(c->db_id_meta, &id, sizeof(struct syrep_id), meta, sizeof(struct syrep_meta), 0) < 0) return -1; - /*** Update md_name ***/ - if (dbput(c->db_md_name, md, sizeof(struct syrep_md), name, sizeof(struct syrep_name), DB_NODUPDATA) < 0) + /*** Update md_nrecno ***/ + if (dbput(c->db_md_nrecno, md, sizeof(struct syrep_md), &nrecno, sizeof(struct syrep_nrecno), DB_NODUPDATA) < 0) return -1; - /*** Update name_md ***/ - if (dbput(c->db_name_md, name, sizeof(struct syrep_name), md, sizeof(struct syrep_md), DB_NODUPDATA) < 0) + /*** Update nrecno_md ***/ + if (dbput(c->db_nrecno_md, &nrecno, sizeof(struct syrep_nrecno), md, sizeof(struct syrep_md), DB_NODUPDATA) < 0) return -1; - /*** Update md_lastname ***/ - if (dbput(c->db_md_lastname, md, sizeof(struct syrep_md), name, sizeof(struct syrep_name), 0) < 0) + /*** Update md_lastnrecno ***/ + if (dbput(c->db_md_lastnrecno, md, sizeof(struct syrep_md), &nrecno, sizeof(struct syrep_nrecno), 0) < 0) return -1; - /*** Update name_lastmd ***/ - if ((f = dbput(c->db_name_lastmd, name, sizeof(struct syrep_name), md, sizeof(struct syrep_md), 0)) < 0) + /*** Update nrecno_lastmd ***/ + if ((f = dbput(c->db_nrecno_lastmd, &nrecno, sizeof(struct syrep_nrecno), md, sizeof(struct syrep_md), 0)) < 0) return -1; //fprintf(stderr, "Insert: %s %i\n", name->path, f); @@ -95,15 +101,22 @@ static int handle_file(struct syrep_db_context *c, uint32_t version, const char int r; struct syrep_meta meta; struct syrep_name name; + struct syrep_nrecno nrecno; memset(&name, 0, sizeof(name)); strncpy(name.path, path, PATH_MAX); - memset(&meta, 0, sizeof(meta)); - - if ((r = get_meta_by_name_md(c, &name, md, &meta)) < 0) + if ((r = get_nrecno_by_name(c, &name, &nrecno, 0)) < 0) return -1; + if (r) { + + memset(&meta, 0, sizeof(meta)); + + if ((r = get_meta_by_nrecno_md(c, &nrecno, md, &meta)) < 0) + return -1; + } + if (r) { /* File is alread known */ if (meta.last_seen != c->version) { /* File was deleted preiously */ diff --git a/src/util.c b/src/util.c index a7118ac..ef1680a 100644 --- a/src/util.c +++ b/src/util.c @@ -18,7 +18,7 @@ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ***/ -//#define USE_SENDFILE +#define USE_SENDFILE #include #include -- cgit