From 7d0c797ac875982febfa9687f54aee8136016ba1 Mon Sep 17 00:00:00 2001 From: "Bradley C. Kuszmaul" <bradley@tokutek.com> Date: Fri, 7 Dec 2007 19:02:03 +0000 Subject: [PATCH] DB->associate(..., DB_CREATE, ...) now appears to work. There was a bug in brt.c which checked to see if the number of pinned pages is zero at the beginning of a lookup. With an open cursor, that doesn't have to be true. Fixes #64, #141. git-svn-id: file:///svn/tokudb@1007 c7de825b-a66e-492c-adef-691d508d4ae1 --- newbrt/brt.c | 8 ++-- src/tests/test_db_assoc3.c | 96 ++++++++++++++++++++++++++++++++++---- 2 files changed, 92 insertions(+), 12 deletions(-) diff --git a/newbrt/brt.c b/newbrt/brt.c index 0f678e35ffe..dbb257ed6af 100644 --- a/newbrt/brt.c +++ b/newbrt/brt.c @@ -1722,7 +1722,7 @@ int toku_close_brt (BRT brt) { if (r!=0) return r; } if (brt->cf) { - assert(0==toku_cachefile_count_pinned(brt->cf, 1)); + assert(0==toku_cachefile_count_pinned(brt->cf, 1)); // For the brt, the pinned count should be zero. //printf("%s:%d closing cachetable\n", __FILE__, __LINE__); if ((r = toku_cachefile_close(&brt->cf))!=0) return r; } @@ -1925,12 +1925,12 @@ static int brt_lookup_node (BRT brt, DISKOFF off, DBT *k, DBT *v, BRTNODE parent int toku_brt_lookup (BRT brt, DBT *k, DBT *v) { int r; CACHEKEY *rootp; - assert(0==toku_cachefile_count_pinned(brt->cf, 1)); + //assert(0==toku_cachefile_count_pinned(brt->cf, 1)); // That assertion isn't right. An open cursor could cause things to be pinned. if ((r = toku_read_and_pin_brt_header(brt->cf, &brt->h))) { printf("%s:%d\n", __FILE__, __LINE__); if (0) { died0: toku_unpin_brt_header(brt); } // printf("%s:%d returning %d\n", __FILE__, __LINE__, r); - assert(0==toku_cachefile_count_pinned(brt->cf, 1)); + //assert(0==toku_cachefile_count_pinned(brt->cf, 1)); // That assertion isn't right. An open cursor could cause things to be pinned. return r; } rootp = toku_calculate_root_offset_pointer(brt); @@ -1940,7 +1940,7 @@ int toku_brt_lookup (BRT brt, DBT *k, DBT *v) { } //printf("%s:%d r=%d", __FILE__, __LINE__, r); if (r==0) printf(" vallen=%d", *vallen); printf("\n"); if ((r = toku_unpin_brt_header(brt))!=0) return r; - assert(0==toku_cachefile_count_pinned(brt->cf, 1)); + //assert(0==toku_cachefile_count_pinned(brt->cf, 1)); // That assertion isn't right. An open cursor could cause things to be pinned. return 0; } diff --git a/src/tests/test_db_assoc3.c b/src/tests/test_db_assoc3.c index 03c8b9b381b..48c49456670 100644 --- a/src/tests/test_db_assoc3.c +++ b/src/tests/test_db_assoc3.c @@ -1,15 +1,21 @@ /* Primary with two associated things. */ -#include <string.h> -#include <db.h> +#include <arpa/inet.h> #include <assert.h> +#include <db.h> #include <errno.h> +#include <string.h> #include <sys/stat.h> #include <sys/time.h> -#include <arpa/inet.h> +#include <unistd.h> #include "test.h" +enum mode { + MODE_DEFAULT, MODE_DB_CREATE +} mode; + + /* Primary is a map from a UID which consists of a random number followed by the current time. */ @@ -217,13 +223,87 @@ void insert_person (void) { int r=dbp->put(dbp, null_txn, &key, &data,0); assert(r==0); } -int main () { - system("rm -rf " DIR); - mkdir(DIR, 0777); +void setup_for_db_create (void) { - create_databases(); + // Remove name.db and then rebuild it with associate(... DB_CREATE) - insert_person(); + int r=unlink(DIR "/name.db"); + assert(r==0); + + r = db_env_create(&dbenv, 0); CKERR(r); + r = dbenv->open(dbenv, DIR, DB_PRIVATE|DB_INIT_MPOOL, 0); CKERR(r); + + r = db_create(&dbp, dbenv, 0); CKERR(r); + r = dbp->open(dbp, null_txn, "primary.db", NULL, DB_BTREE, 0, 0600); CKERR(r); + + r = db_create(&namedb, dbenv, 0); CKERR(r); + r = namedb->open(namedb, null_txn, "name.db", NULL, DB_BTREE, DB_CREATE, 0600); CKERR(r); + + r = db_create(&expiredb, dbenv, 0); CKERR(r); + r = expiredb->open(expiredb, null_txn, "expire.db", NULL, DB_BTREE, 0, 0600); CKERR(r); + + r = dbp->associate(dbp, NULL, expiredb, expire_callback, 0); CKERR(r); + r = dbp->associate(dbp, NULL, namedb, name_callback, DB_CREATE); CKERR(r); + +} + +int count_entries (DB *db) { + DBC *dbc; + int r = db->cursor(db, null_txn, &dbc, 0); CKERR(r); + DBT key,data; + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + int n_found=0; + for (r = dbc->c_get(dbc, &key, &data, DB_FIRST); + r==0; + r = dbc->c_get(dbc, &key, &data, DB_NEXT)) { + n_found++; + } + assert(r==DB_NOTFOUND); + r=dbc->c_close(dbc); CKERR(r); + return n_found; +} + +void do_create (void) { + setup_for_db_create(); + // Now check to see if the number of names matches the number of associated things. + int n_named = count_entries(namedb); + int n_prim = count_entries(dbp); + assert(n_named==n_prim); +} + +void usage (const char *argv1) { + fprintf(stderr, "Usage:\n %s [ --DB-CREATE ]\n", argv1); + exit(1); +} + +int main (int argc, const char *argv[]) { + + if (argc==1) { + mode = MODE_DEFAULT; + } else if (argc==2) { + if (strcmp(argv[1], "--DB_CREATE")==0) { + mode = MODE_DB_CREATE; + } else { + usage(argv[0]); + } + } else { + usage(argv[0]); + } + + switch (mode) { + case MODE_DEFAULT: + system("rm -rf " DIR); + mkdir(DIR, 0777); + create_databases(); + int i; + for (i=0; i<100; i++) + insert_person(); + break; + case MODE_DB_CREATE: + do_create(); + break; + } close_databases();