Commit 2e2160ab authored by Yoni Fogel's avatar Yoni Fogel

DB_DBT_(MALLOC|REALOC|USERMEM) now behave the same as BDB.

We never touch ulen.  If DB_DBT_USERMEM and ulen is too small, we set size, (do not write anything)
and return DB_BUFFER_SMALL.

This includes test_db_dbt_mem_behavior.c
Closes #146

git-svn-id: file:///svn/tokudb@1034 c7de825b-a66e-492c-adef-691d508d4ae1
parent 25f0468a
......@@ -67,6 +67,7 @@ typedef enum {
#define DB_NOTFOUND -30989
#define DB_SECONDARY_BAD -30973
#define DB_DONOTINDEX -30998
#define DB_BUFFER_SMALL -30999
#define DB_BADFORMAT -30500
#define DB_DELETE_ANY 65536
#define DB_FIRST 9
......
......@@ -73,6 +73,7 @@ void print_defines (void) {
dodefine(DB_NOTFOUND);
dodefine(DB_SECONDARY_BAD);
dodefine(DB_DONOTINDEX);
dodefine(DB_BUFFER_SMALL);
printf("#define DB_BADFORMAT -30500\n"); // private tokudb
printf("#define DB_DELETE_ANY %d\n", 1<<16); // private tokudb
......
......@@ -67,6 +67,7 @@ typedef enum {
#define DB_NOTFOUND -30989
#define DB_SECONDARY_BAD -30973
#define DB_DONOTINDEX -30998
#define DB_BUFFER_SMALL -30999
#define DB_BADFORMAT -30500
#define DB_DELETE_ANY 65536
#define DB_FIRST 9
......
......@@ -21,15 +21,13 @@ int toku_dbt_set_value (DBT *ybt, bytevec val, ITEMLEN vallen, void **staticptrp
domalloc:
ybt->data = toku_malloc(vallen);
if (errno!=0) return errno;
ybt->ulen = vallen;
} else if (ybt->flags==DB_DBT_REALLOC) {
if (ybt->data==0) goto domalloc;
ybt->data = toku_realloc(ybt->data, vallen);
if (errno!=0) return errno;
ybt->ulen = vallen;
} else if (ybt->flags==DB_DBT_USERMEM) {
/*nothing*/
ybt->size = vallen;
if (ybt->ulen < vallen) return DB_BUFFER_SMALL;
} else {
if (staticptrp==0) return -1;
void *staticptr=*staticptrp;
......@@ -42,11 +40,9 @@ int toku_dbt_set_value (DBT *ybt, bytevec val, ITEMLEN vallen, void **staticptrp
//if (old!=staticptr) printf("%s:%d MALLOC --> %p\n", __FILE__, __LINE__, staticptr);
*staticptrp = staticptr;
ybt->data = staticptr;
ybt->ulen = vallen;
}
ybt->size = vallen;
if (ybt->ulen>0) {
if (ybt->ulen<vallen) vallen=ybt->ulen;
if (ybt->size>0) {
memcpy(ybt->data, val, vallen);
}
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
typedef struct {
int32_t pkey;
char waste[1024];
} DATA;
DB* db;
DB_TXN *const null_txn = 0;
DB_ENV *dbenv;
u_int32_t set_ulen;
int32_t key_1 = 1;
void setup(void) {
int r;
system("rm -rf " DIR);
mkdir(DIR, 0777);
dbenv = 0;
/* Open/create primary */
r = db_create(&db, dbenv, 0); CKERR(r);
r = db->open(db, null_txn, DIR "/primary.db", NULL, DB_BTREE, DB_CREATE, 0600); CKERR(r);
}
void insert_test(void) {
int r;
DATA entry;
DBT data;
DBT key;
memset(&entry, 0xFF, sizeof(entry));
entry.pkey = key_1;
dbt_init(&key, &entry.pkey, sizeof(entry.pkey));
dbt_init(&data, &entry, sizeof(entry));
r = db->put(db, null_txn, &key, &data, 0); CKERR(r);
}
void close_dbs() {
int r;
r = db->close(db, 0); CKERR(r);
}
int main(int argc, const char *argv[]) {
int i;
int r;
parse_args(argc, argv);
//Simple flags that require minimal setup.
u_int32_t flags[] = {
0,
DB_DBT_USERMEM,
DB_DBT_MALLOC,
DB_DBT_REALLOC,
};
int num_flags = sizeof(flags) / sizeof(flags[0]);
int j;
setup();
insert_test();
DBT key;
DBT data;
void* oldmem;
for (j = 0; j < num_flags; j++) {
for (i = 0; i < 2; i++) {
if (i) set_ulen = sizeof(DATA) / 2;
else set_ulen = sizeof(DATA);
int old_ulen;
int was_truncated = 0;
int ulen_changed;
int size_full;
int clone = 0;
DATA fake;
int small_buffer = 0;
memset(&fake, 0xFF, sizeof(DATA));
fake.pkey = key_1;
dbt_init(&key, &key_1, sizeof(key_1));
dbt_init(&data, 0, 0);
data.flags = flags[j];
oldmem = malloc(set_ulen);
data.data = oldmem;
memset(oldmem, 0, set_ulen);
if (flags[j] == DB_DBT_USERMEM) {
data.ulen = set_ulen;
}
old_ulen = data.ulen;
r = db->get(db, null_txn, &key, &data, 0);
if (flags[j] == DB_DBT_USERMEM && set_ulen < sizeof(DATA)) CKERR2(r, DB_BUFFER_SMALL);
else CKERR(r);
if (r == DB_BUFFER_SMALL) {
//The entire 'waste' is full of 0xFFs
DATA* entry = data.data;
was_truncated = entry->waste[0] != 0;
small_buffer = 1;
}
ulen_changed = data.ulen != old_ulen;
size_full = data.size == sizeof(DATA);
int min = data.ulen < data.size ? data.ulen : data.size;
min = min < sizeof(DATA) ? min : sizeof(DATA);
//assert(min == sizeof(DATA));
r = memcmp((DATA*)data.data, &fake, min);
clone = r == 0;
if (flags[j] != 0) {
free(data.data);
}
if (flags[j] == 0 || flags[j] == DB_DBT_MALLOC) {
free(oldmem);
}
assert(!was_truncated);
assert(!ulen_changed);
assert(size_full);
assert(clone == !small_buffer);
}
}
oldmem = 0;
dbt_init(&key, 0, 0);
dbt_init(&data, 0, 0);
close_dbs();
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