From 0b86108b7f465035a0bc59e81576cae176c3bdfa Mon Sep 17 00:00:00 2001
From: "Bradley C. Kuszmaul" <bradley@tokutek.com>
Date: Fri, 7 Dec 2007 20:16:56 +0000
Subject: [PATCH] db_assoc3 is doing more.  It returns -3 which it shouldn't

git-svn-id: file:///svn/tokudb@1012 c7de825b-a66e-492c-adef-691d508d4ae1
---
 src/tests/test_db_assoc3.c | 149 ++++++++++++++++++++++++++-----------
 src/ydb.c                  |   1 +
 2 files changed, 108 insertions(+), 42 deletions(-)

diff --git a/src/tests/test_db_assoc3.c b/src/tests/test_db_assoc3.c
index 48c49456670..88f59a6cacc 100644
--- a/src/tests/test_db_assoc3.c
+++ b/src/tests/test_db_assoc3.c
@@ -12,7 +12,7 @@
 #include "test.h"
 
 enum mode {
-    MODE_DEFAULT, MODE_DB_CREATE
+    MODE_DEFAULT, MODE_DB_CREATE, MODE_MORE
 } mode;
 
 
@@ -152,6 +152,8 @@ DB *dbp,*namedb,*expiredb;
 
 DB_TXN * const null_txn=0;
 
+DBC *delete_cursor=0;
+
 void create_databases (void) {
     int r;
 
@@ -173,10 +175,13 @@ void create_databases (void) {
 
 void close_databases (void) {
     int r;
-    r = namedb->close(namedb, 0);   CKERR(r);
-    r = dbp->close(dbp, 0);      CKERR(r);
+    if (delete_cursor) {
+	r = delete_cursor->c_close(delete_cursor); CKERR(r);
+    }
+    r = namedb->close(namedb, 0);     CKERR(r);
+    r = dbp->close(dbp, 0);           CKERR(r);
     r = expiredb->close(expiredb, 0); CKERR(r);
-    r = dbenv->close(dbenv, 0);  CKERR(r);
+    r = dbenv->close(dbenv, 0);       CKERR(r);
 }
     
 
@@ -188,41 +193,6 @@ void gettod (struct timestamp *ts) {
     ts->tv_usec = htonl(tv.tv_usec);
 }
 
-void insert_person (void) {
-    int namelen = 5+random()%245;
-    struct primary_key  pk;
-    struct primary_data pd;
-    char keyarray[1000], dataarray[1000]; 
-    unsigned char namearray[1000];
-    pk.rand = random();
-    gettod(&pk.ts);
-    pd.creationtime = pk.ts;
-    pd.expiretime   = pk.ts;
-    pd.expiretime.tv_sec += 24*60*60*366;
-    pd.doesexpire = (random()%1==0);
-    pd.name.len = namelen;
-    int i;
-    pd.name.name = namearray;
-    pd.name.name[0] = 'A'+random()%26;
-    for (i=1; i<namelen; i++) {
-	pd.name.name[i] = 'a'+random()%26;
-    }
-    DBT key,data;
-    memset(&key,0,sizeof(DBT));
-    memset(&data,0,sizeof(DBT));
-    key.data = keyarray;
-    key.ulen = 1000;
-    key.size = 0;
-    data.data = dataarray;
-    data.ulen = 1000;
-    data.size = 0;
-    write_pk_to_dbt(&key, &pk);
-    write_pd_to_dbt(&data, &pd);
-    printf("sizeof(pk)=%d\n", (int)sizeof(struct primary_key));
-    printf("sizeof(pd)=%d\n", (int)sizeof(struct primary_data));
-    int r=dbp->put(dbp, null_txn, &key, &data,0);  assert(r==0);
-}
-
 void setup_for_db_create (void) {
 
     // Remove name.db and then rebuild it with associate(... DB_CREATE)
@@ -272,6 +242,86 @@ void do_create (void) {
     assert(n_named==n_prim);
 }
 
+void insert_person (void) {
+    int namelen = 5+random()%245;
+    struct primary_key  pk;
+    struct primary_data pd;
+    char keyarray[1000], dataarray[1000]; 
+    unsigned char namearray[1000];
+    pk.rand = random();
+    gettod(&pk.ts);
+    pd.creationtime = pk.ts;
+    pd.expiretime   = pk.ts;
+    pd.expiretime.tv_sec += 24*60*60*366;
+    pd.doesexpire = (random()%10==0);
+    pd.name.len = namelen;
+    int i;
+    pd.name.name = namearray;
+    pd.name.name[0] = 'A'+random()%26;
+    for (i=1; i<namelen; i++) {
+	pd.name.name[i] = 'a'+random()%26;
+    }
+    DBT key,data;
+    memset(&key,0,sizeof(DBT));
+    memset(&data,0,sizeof(DBT));
+    key.data = keyarray;
+    key.ulen = 1000;
+    key.size = 0;
+    data.data = dataarray;
+    data.ulen = 1000;
+    data.size = 0;
+    write_pk_to_dbt(&key, &pk);
+    write_pd_to_dbt(&data, &pd);
+    int r=dbp->put(dbp, null_txn, &key, &data,0);  assert(r==0);
+}
+
+void delete_oldest_expired (void) {
+    int r;
+    if (delete_cursor==0) {
+	r = expiredb->cursor(expiredb, null_txn, &delete_cursor, 0); CKERR(r);
+	
+    }
+    DBT key,pkey,data, savepkey;
+    memset(&key, 0, sizeof(key));
+    memset(&pkey, 0, sizeof(pkey));
+    memset(&data, 0, sizeof(data));
+    r = delete_cursor->c_pget(delete_cursor, &key, &pkey, &data, DB_FIRST);
+    if (r==DB_NOTFOUND) return;
+    CKERR(r);
+    savepkey = pkey;
+    savepkey.data = malloc(pkey.size);
+    memcpy(savepkey.data, pkey.data, pkey.size);
+    switch (random()%3) {
+    case 0:
+	r = delete_cursor->c_del(delete_cursor, 0);  CKERR(r);
+	break;
+    case 1:
+	r = expiredb->del(expiredb, null_txn, &key, 0); CKERR(r);
+	break;
+    case 2:
+	r = dbp->del(dbp, null_txn, &pkey, 0);   CKERR(r);
+	break;
+    default:
+	assert(0);
+    }
+    // Make sure it's really gone.
+    r = delete_cursor->c_get(delete_cursor, &key, &data, DB_CURRENT);
+    assert(r==DB_KEYEMPTY);
+    r = dbp->get(dbp, null_txn, &savepkey, &data, 0);
+    assert(r==DB_NOTFOUND);
+    free(savepkey.data);
+}
+
+void activity (void) {
+    if (random()%20==0) {
+	// Delete the oldest expired one.  Keep the cursor open
+	delete_oldest_expired();
+    } else {
+	insert_person();
+    }
+}
+		       
+
 void usage (const char *argv1) {
     fprintf(stderr, "Usage:\n %s [ --DB-CREATE ]\n", argv1);
     exit(1);
@@ -284,6 +334,8 @@ int main (int argc, const char *argv[]) {
     } else if (argc==2) {
 	if (strcmp(argv[1], "--DB_CREATE")==0) {
 	    mode = MODE_DB_CREATE;
+	} else if (strcmp(argv[1], "--more")==0) {
+	    mode = MODE_MORE;
 	} else {
 	    usage(argv[0]);
 	}
@@ -296,9 +348,22 @@ int main (int argc, const char *argv[]) {
 	system("rm -rf " DIR);
 	mkdir(DIR, 0777); 
 	create_databases();
-	int i;
-	for (i=0; i<100; i++)
-	    insert_person();
+	{
+	    int i;
+	    for (i=0; i<100; i++)
+		activity();
+	}
+	break;
+    case MODE_MORE:
+	create_databases();
+	struct timeval tv;
+	gettimeofday(&tv, 0);
+	srandom(tv.tv_sec+tv.tv_usec*997); // magic:  997 is a prime, and a million (microseconds/second) times 997 is still 32 bits.
+	{
+	    int i;
+	    for (i=0; i<100; i++)
+		activity();
+	}
 	break;
     case MODE_DB_CREATE:
 	do_create();
diff --git a/src/ydb.c b/src/ydb.c
index 8e2f2e51ae6..7d248843a57 100644
--- a/src/ydb.c
+++ b/src/ydb.c
@@ -668,6 +668,7 @@ static int toku_c_del_noassociate(DBC * c, u_int32_t flags) {
     return r;
 }
 
+
 static int toku_c_pget(DBC * c, DBT *key, DBT *pkey, DBT *data, u_int32_t flag) {
     int r;
     DB *db = c->i->db;
-- 
2.30.9