From cc2d609dfca7192305ad477b8c2b52cfdc1aa9be Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 31 Aug 2011 15:31:06 +0930 Subject: [PATCH 1/1] tdb2: unify tdb1_traverse into tdb_traverse Switch on the TDB_VERSION1 flag; we now only do a tdb1_traverse_read on a read-only database, as there is no tdb2 equivalent. --- ccan/tdb2/private.h | 5 +++++ ccan/tdb2/tdb1.h | 6 ------ ccan/tdb2/tdb1_tdb.c | 4 ++-- ccan/tdb2/tdb1_traverse.c | 20 ++++++++++++------- ccan/tdb2/test/run-tdb1-3G-file.c | 6 +++--- ccan/tdb2/test/run-tdb1-nested-traverse.c | 8 +++++--- .../test/run-tdb1-no-lock-during-traverse.c | 6 +++--- .../test/run-tdb1-traverse-in-transaction.c | 4 ++-- ccan/tdb2/traverse.c | 7 +++++++ 9 files changed, 40 insertions(+), 26 deletions(-) diff --git a/ccan/tdb2/private.h b/ccan/tdb2/private.h index fb04656d..98e26c17 100644 --- a/ccan/tdb2/private.h +++ b/ccan/tdb2/private.h @@ -646,6 +646,11 @@ int tdb1_allrecord_unlock(struct tdb_context *tdb, int ltype); int tdb1_transaction_recover(struct tdb_context *tdb); int tdb1_transaction_cancel(struct tdb_context *tdb); +/* tdb1_traverse.c: */ +int tdb1_traverse(struct tdb_context *tdb, + int (*)(struct tdb_context *, TDB_DATA, TDB_DATA, void *), + void *private_data); + /* tdb1_tdb.c: */ int tdb1_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); enum TDB_ERROR tdb1_fetch(struct tdb_context *tdb, TDB_DATA key, diff --git a/ccan/tdb2/tdb1.h b/ccan/tdb2/tdb1.h index da77e27c..4b0e454d 100644 --- a/ccan/tdb2/tdb1.h +++ b/ccan/tdb2/tdb1.h @@ -36,8 +36,6 @@ #endif -typedef int (*tdb1_traverse_func)(struct tdb_context *, TDB_DATA, TDB_DATA, void *); - void tdb1_set_max_dead(struct tdb_context *tdb, int max_dead); int tdb1_parse_record(struct tdb_context *tdb, TDB_DATA key, @@ -49,10 +47,6 @@ TDB_DATA tdb1_firstkey(struct tdb_context *tdb); TDB_DATA tdb1_nextkey(struct tdb_context *tdb, TDB_DATA key); -int tdb1_traverse(struct tdb_context *tdb, tdb1_traverse_func fn, void *private_data); - -int tdb1_traverse_read(struct tdb_context *tdb, tdb1_traverse_func fn, void *private_data); - int tdb1_lockall(struct tdb_context *tdb); int tdb1_unlockall(struct tdb_context *tdb); diff --git a/ccan/tdb2/tdb1_tdb.c b/ccan/tdb2/tdb1_tdb.c index 2c989bb9..d7f518dc 100644 --- a/ccan/tdb2/tdb1_tdb.c +++ b/ccan/tdb2/tdb1_tdb.c @@ -862,7 +862,7 @@ int tdb1_repack(struct tdb_context *tdb) state.error = TDB_SUCCESS; state.dest_db = tmp_db; - if (tdb1_traverse_read(tdb, repack_traverse, &state) == -1) { + if (tdb1_traverse(tdb, repack_traverse, &state) == -1) { tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, __location__ " Failed to traverse copying out"); tdb1_transaction_cancel(tdb); @@ -889,7 +889,7 @@ int tdb1_repack(struct tdb_context *tdb) state.error = TDB_SUCCESS; state.dest_db = tdb; - if (tdb1_traverse_read(tmp_db, repack_traverse, &state) == -1) { + if (tdb1_traverse(tmp_db, repack_traverse, &state) == -1) { tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, __location__ " Failed to traverse copying back"); tdb1_transaction_cancel(tdb); diff --git a/ccan/tdb2/tdb1_traverse.c b/ccan/tdb2/tdb1_traverse.c index 87e233b4..63052854 100644 --- a/ccan/tdb2/tdb1_traverse.c +++ b/ccan/tdb2/tdb1_traverse.c @@ -144,8 +144,10 @@ static tdb1_off_t tdb1_next_lock(struct tdb_context *tdb, struct tdb1_traverse_l a non-zero return value from fn() indicates that the traversal should stop */ static int tdb1_traverse_internal(struct tdb_context *tdb, - tdb1_traverse_func fn, void *private_data, - struct tdb1_traverse_lock *tl) + int (*fn)(struct tdb_context *, + TDB_DATA, TDB_DATA, void *), + void *private_data, + struct tdb1_traverse_lock *tl) { TDB_DATA key, dbuf; struct tdb1_record rec; @@ -213,10 +215,12 @@ out: /* - a write style traverse - temporarily marks the db read only + a read style traverse - only if db read only */ -int tdb1_traverse_read(struct tdb_context *tdb, - tdb1_traverse_func fn, void *private_data) +static int tdb1_traverse_read(struct tdb_context *tdb, + int (*fn)(struct tdb_context *, + TDB_DATA, TDB_DATA, void *), + void *private_data) { struct tdb1_traverse_lock tl = { NULL, 0, 0, F_RDLCK }; int ret; @@ -244,12 +248,14 @@ int tdb1_traverse_read(struct tdb_context *tdb, alignment restrictions malloc gives you. */ int tdb1_traverse(struct tdb_context *tdb, - tdb1_traverse_func fn, void *private_data) + int (*fn)(struct tdb_context *, TDB_DATA, TDB_DATA, void *), + void *private_data) { struct tdb1_traverse_lock tl = { NULL, 0, 0, F_WRLCK }; int ret; - if ((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) { + /* If we're read-only, we don't have to write-lock whole db. */ + if (tdb->flags & TDB_RDONLY) { return tdb1_traverse_read(tdb, fn, private_data); } diff --git a/ccan/tdb2/test/run-tdb1-3G-file.c b/ccan/tdb2/test/run-tdb1-3G-file.c index 116c6554..07490185 100644 --- a/ccan/tdb2/test/run-tdb1-3G-file.c +++ b/ccan/tdb2/test/run-tdb1-3G-file.c @@ -101,12 +101,12 @@ int main(int argc, char *argv[]) tdb1_unlock(tdb, TDB1_BUCKET(rec.full_hash), F_RDLCK); /* Traverse must work. */ - ok1(tdb1_traverse(tdb, test_traverse, &orig_data) == 1); + ok1(tdb_traverse(tdb, test_traverse, &orig_data) == 1); /* Delete should work. */ ok1(tdb_delete(tdb, key) == TDB_SUCCESS); - ok1(tdb1_traverse(tdb, test_traverse, NULL) == 0); + ok1(tdb_traverse(tdb, test_traverse, NULL) == 0); /* Transactions should work. */ ok1(tdb1_transaction_start(tdb) == 0); @@ -118,7 +118,7 @@ int main(int argc, char *argv[]) free(data.dptr); ok1(tdb1_transaction_commit(tdb) == 0); - ok1(tdb1_traverse(tdb, test_traverse, &orig_data) == 1); + ok1(tdb_traverse(tdb, test_traverse, &orig_data) == 1); tdb_close(tdb); return exit_status(); diff --git a/ccan/tdb2/test/run-tdb1-nested-traverse.c b/ccan/tdb2/test/run-tdb1-nested-traverse.c index ef19911d..cf5aa4a2 100644 --- a/ccan/tdb2/test/run-tdb1-nested-traverse.c +++ b/ccan/tdb2/test/run-tdb1-nested-traverse.c @@ -38,7 +38,7 @@ static int traverse1(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, ok1(correct_data(data)); ok1(external_agent_operation1(agent, TRANSACTION_START, tdb->name) == WOULD_HAVE_BLOCKED); - tdb1_traverse(tdb, traverse2, NULL); + tdb_traverse(tdb, traverse2, NULL); /* That should *not* release the transaction lock! */ ok1(external_agent_operation1(agent, TRANSACTION_START, tdb->name) @@ -77,8 +77,10 @@ int main(int argc, char *argv[]) data.dsize = strlen("world"); ok1(tdb_store(tdb, key, data, TDB_INSERT) == TDB_SUCCESS); - tdb1_traverse(tdb, traverse1, NULL); - tdb1_traverse_read(tdb, traverse1, NULL); + tdb_traverse(tdb, traverse1, NULL); + tdb_add_flag(tdb, TDB_RDONLY); + tdb_traverse(tdb, traverse1, NULL); + tdb_remove_flag(tdb, TDB_RDONLY); tdb_close(tdb); return exit_status(); diff --git a/ccan/tdb2/test/run-tdb1-no-lock-during-traverse.c b/ccan/tdb2/test/run-tdb1-no-lock-during-traverse.c index 383b74cb..71404c2d 100644 --- a/ccan/tdb2/test/run-tdb1-no-lock-during-traverse.c +++ b/ccan/tdb2/test/run-tdb1-no-lock-during-traverse.c @@ -74,7 +74,7 @@ int main(int argc, char *argv[]) hsize.base.next = &tap_log_attr; hsize.tdb1_hashsize.hsize = 1024; - plan_tests(41); + plan_tests(43); tdb = tdb_open("run-no-lock-during-traverse.tdb1", TDB_VERSION1, O_CREAT|O_TRUNC|O_RDWR, 0600, &hsize); @@ -84,7 +84,7 @@ int main(int argc, char *argv[]) ok1(locking_errors1 == 0); ok1(tdb1_lockall(tdb) == 0); ok1(locking_errors1 == 0); - tdb1_traverse(tdb, delete_other, &errors); + ok1(tdb_traverse(tdb, delete_other, &errors) >= 0); ok1(errors == 0); ok1(locking_errors1 == 0); ok1(tdb1_unlockall(tdb) == 0); @@ -93,7 +93,7 @@ int main(int argc, char *argv[]) ok1(locking_errors1 == 0); ok1(tdb1_lockall(tdb) == 0); ok1(locking_errors1 == 0); - tdb1_traverse(tdb, delete_self, NULL); + ok1(tdb_traverse(tdb, delete_self, NULL) == NUM_ENTRIES); ok1(locking_errors1 == 0); ok1(tdb1_unlockall(tdb) == 0); diff --git a/ccan/tdb2/test/run-tdb1-traverse-in-transaction.c b/ccan/tdb2/test/run-tdb1-traverse-in-transaction.c index 90783198..c4fd89df 100644 --- a/ccan/tdb2/test/run-tdb1-traverse-in-transaction.c +++ b/ccan/tdb2/test/run-tdb1-traverse-in-transaction.c @@ -64,12 +64,12 @@ int main(int argc, char *argv[]) ok1(tdb1_transaction_start(tdb) == 0); ok1(external_agent_operation1(agent, TRANSACTION_START, tdb->name) == WOULD_HAVE_BLOCKED); - tdb1_traverse(tdb, traverse, NULL); + tdb_traverse(tdb, traverse, NULL); /* That should *not* release the transaction lock! */ ok1(external_agent_operation1(agent, TRANSACTION_START, tdb->name) == WOULD_HAVE_BLOCKED); - tdb1_traverse_read(tdb, traverse, NULL); + tdb_traverse(tdb, traverse, NULL); /* That should *not* release the transaction lock! */ ok1(external_agent_operation1(agent, TRANSACTION_START, tdb->name) diff --git a/ccan/tdb2/traverse.c b/ccan/tdb2/traverse.c index f8a2504d..d93c05ab 100644 --- a/ccan/tdb2/traverse.c +++ b/ccan/tdb2/traverse.c @@ -28,6 +28,13 @@ int64_t tdb_traverse_(struct tdb_context *tdb, struct tdb_data k, d; int64_t count = 0; + if (tdb->flags & TDB_VERSION1) { + count = tdb1_traverse(tdb, fn, p); + if (count == -1) + return tdb->last_error; + return count; + } + k.dptr = NULL; for (ecode = first_in_hash(tdb, &tinfo, &k, &d.dsize); ecode == TDB_SUCCESS; -- 2.39.2