Commit ca7d898e authored by Rich Prohaska's avatar Rich Prohaska

test multithread db->pget. addresses #167

git-svn-id: file:///svn/tokudb@1672 c7de825b-a66e-492c-adef-691d508d4ae1
parent 1de897e0
......@@ -3,11 +3,12 @@
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <db.h>
#include "test.h"
const char *dbfile = "test.db";
const char *dbfile = DIR "/" "test.db";
const char *dbname = 0;
int db_put(DB *db, int k, int v) {
......@@ -66,6 +67,8 @@ void test_db_thread() {
int main(int argc, const char *argv[]) {
parse_args(argc, argv);
system("rm -rf " DIR);
mkdir(DIR, 0777);
test_db_create();
test_db_thread();
return 0;
......
/* -*- mode: C; c-basic-offset: 4 -*- */
#ident "Copyright (c) 2007 Tokutek Inc. All rights reserved."
#include <string.h>
#include <db.h>
#include <assert.h>
#include <errno.h>
#include <sys/stat.h>
#include "test.h"
// DIR is defined in the Makefile
int dbtcmp(DBT *dbt1, DBT *dbt2) {
int r;
r = dbt1->size - dbt2->size; if (r) return r;
return memcmp(dbt1->data, dbt2->data, dbt1->size);
}
struct student_record {
char student_id[4];
char last_name[15];
char first_name[15];
};
#define SPACES " "
DB *dbp;
DB *sdbp;
DB_TXN *const null_txn = 0;
DB_ENV *dbenv;
/*
* getname -- extracts a secondary key (the last name) from a primary
* key/data pair
*/
int getname(DB *secondary, const DBT *pkey, const DBT *pdata, DBT *skey)
{
/*
* Since the secondary key is a simple structure member of the
* record, we don't have to do anything fancy to return it. If
* we have composite keys that need to be constructed from the
* record, rather than simply pointing into it, then the user's
* function might need to allocate space and copy data. In
* this case, the DB_DBT_APPMALLOC flag should be set in the
* secondary key DBT.
*/
memset(skey, 0, sizeof(DBT));
skey->data = ((struct student_record *)pdata->data)->last_name;
skey->size = sizeof ((struct student_record *)pdata->data)->last_name;
return (0);
}
void second_setup() {
int r;
/* Open/create primary */
r = db_create(&dbp, dbenv, 0); CKERR(r);
r = dbp->open(dbp, NULL, DIR "/students.db", NULL, DB_BTREE, DB_CREATE+DB_THREAD, 0600); CKERR(r);
/*
* Open/create secondary. Note that it supports duplicate data
* items, since last names might not be unique.
*/
r = db_create(&sdbp, dbenv, 0); CKERR(r);
r = sdbp->set_flags(sdbp, DB_DUP | DB_DUPSORT); CKERR(r);
r = sdbp->open(sdbp, NULL, DIR "/lastname.db", NULL, DB_BTREE, DB_CREATE+DB_THREAD, 0600); CKERR(r);
/* Associate the secondary with the primary. */
r = dbp->associate(dbp, NULL, sdbp, getname, 0); CKERR(r);
}
void setup_student(struct student_record *s) {
memset(s, 0, sizeof(struct student_record));
memcpy(&s->student_id, "WC42" SPACES, sizeof(s->student_id));
//Padded with enough spaces to fill out last/first name.
memcpy(&s->last_name, "Churchill" SPACES, sizeof(s->last_name));
memcpy(&s->first_name, "Winston" SPACES, sizeof(s->first_name));
}
void insert_test() {
struct student_record s;
DBT data;
DBT key;
DBT skey;
DBT testdata;
DBT testkey;
int r;
setup_student(&s);
memset(&testdata, 0, sizeof(DBT));
memset(&testkey, 0, sizeof(DBT));
memset(&skey, 0, sizeof(DBT));
memset(&key, 0, sizeof(DBT));
memset(&data, 0, sizeof(DBT));
key.data = "WC42";
key.size = strlen("WC42");
data.data = &s;
data.size = sizeof(s);
//Set up secondary key
r = getname(sdbp, &key, &data, &skey); CKERR(r);
//Insert into primary.
r = dbp->put(dbp, null_txn, &key, &data, 0); CKERR(r);
//Make certain we fail to insert into secondary.
r = sdbp->put(sdbp, null_txn, &key, &data, 0); assert(r == EINVAL);
/* Try to get it from primary. */
memset(&testdata, 0, sizeof testdata); testdata.flags = DB_DBT_MALLOC;
r = dbp->get(dbp, null_txn, &key, &testdata, 0); CKERR(r);
r = dbtcmp(&data, &testdata); CKERR(r);
if (testdata.data) free(testdata.data);
/* Try to get it from secondary. */
memset(&testdata, 0, sizeof testdata); testdata.flags = DB_DBT_MALLOC;
r = sdbp->get(sdbp, null_txn, &skey, &testdata, 0); CKERR(r);
r = dbtcmp(&data, &testdata); CKERR(r);
if (testdata.data) free(testdata.data);
/* Try to pget from secondary */
memset(&testkey, 0, sizeof testkey); testkey.flags = DB_DBT_MALLOC;
memset(&testdata, 0, sizeof testdata); testdata.flags = DB_DBT_MALLOC;
r = sdbp->pget(sdbp, null_txn, &skey, &testkey, &testdata, 0); CKERR(r);
r = dbtcmp(&data, &testdata); CKERR(r);
if (testdata.data) free(testdata.data);
r = dbtcmp(&testkey, &key); CKERR(r);
if (testkey.data) free(testkey.data);
/* Make sure we fail 'pget' from primary */
r = dbp->pget(dbp, null_txn, &key, &testkey, &data, 0); assert(r == EINVAL);
}
void delete_from_primary() {
int r;
DBT key;
memset(&key, 0, sizeof(DBT));
key.data = "WC42";
key.size = 4;
r = dbp->del(dbp, null_txn, &key, 0); CKERR(r);
}
void delete_from_secondary() {
int r;
DBT skey;
DBT data;
struct student_record s;
setup_student(&s);
memset(&skey, 0, sizeof(DBT));
memset(&data, 0, sizeof(DBT));
data.data = &s;
data.size = sizeof(s);
r = getname(sdbp, NULL, &data, &skey); CKERR(r);
r = sdbp->del(sdbp, null_txn, &skey, 0); CKERR(r);
}
void verify_gone() {
int r;
DBT key;
DBT skey;
DBT data;
struct student_record s;
memset(&key, 0, sizeof(DBT));
memset(&skey, 0, sizeof(DBT));
memset(&data, 0, sizeof(DBT));
key.data = "WC42";
key.size = 4;
/* Try (fail) to get it from primary. */
data.flags = DB_DBT_MALLOC;
r = dbp->get(dbp, null_txn, &key, &data, 0); assert(r == DB_NOTFOUND);
if (data.data) free(data.data);
/* Try (fail) to get it from secondary. */
setup_student(&s); memset(&data, 0, sizeof data); data.data = &s; data.size = sizeof s;
r = getname(sdbp, NULL, &data, &skey); CKERR(r);
memset(&data, 0, sizeof data); data.flags = DB_DBT_MALLOC;
r = sdbp->get(sdbp, null_txn, &skey, &data, 0); assert(r == DB_NOTFOUND);
if (data.data) free(data.data);
/* Try (fail) to pget from secondary */
setup_student(&s); memset(&data, 0, sizeof data); data.data = &s; data.size = sizeof s;
r = getname(sdbp, NULL, &data, &skey); CKERR(r);
memset(&data, 0, sizeof data); data.flags = DB_DBT_MALLOC;
memset(&key, 0, sizeof key); key.flags = DB_DBT_MALLOC;
r = sdbp->pget(sdbp, null_txn, &skey, &key, &data, 0);assert(r == DB_NOTFOUND);
if (data.data) free(data.data);
if (key.data) free(key.data);
}
int main() {
int r;
system("rm -rf " DIR);
mkdir(DIR, 0777);
second_setup();
insert_test();
delete_from_primary();
verify_gone();
insert_test();
delete_from_secondary();
verify_gone();
r = dbp->close(dbp, 0); CKERR(r);
r = sdbp->close(sdbp, 0); CKERR(r);
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment