Commit 8f2b0a7e authored by Yoni Fogel's avatar Yoni Fogel

Addresses #1510 Merge of 1510 (so far) back into main

Several fixes are included, particulary db remove after db truncate (with descriptor) does not crash anymore.
svn merge -r 10931:11019 ../tokudb.1510

git-svn-id: file:///svn/toku/tokudb@11020 c7de825b-a66e-492c-adef-691d508d4ae1
parent 0b981a37
/* -*- mode: C; c-basic-offset: 4 -*- */
#ident "$Id: brt.c 10921 2009-04-01 16:54:40Z yfogel $"
#ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved."
#ifndef _TOKU_PTHREAD_H
#define _TOKU_PTHREAD_H
......@@ -13,6 +16,38 @@ typedef pthread_mutexattr_t toku_pthread_mutexattr_t;
typedef pthread_mutex_t toku_pthread_mutex_t;
typedef pthread_condattr_t toku_pthread_condattr_t;
typedef pthread_cond_t toku_pthread_cond_t;
typedef pthread_rwlock_t toku_pthread_rwlock_t;
typedef pthread_rwlockattr_t toku_pthread_rwlockattr_t;
static inline int
toku_pthread_rwlock_init(toku_pthread_rwlock_t *restrict rwlock, const toku_pthread_rwlockattr_t *restrict attr) {
return pthread_rwlock_init(rwlock, attr);
}
static inline int
toku_pthread_rwlock_destroy(toku_pthread_rwlock_t *rwlock) {
return pthread_rwlock_destroy(rwlock);
}
static inline int
toku_pthread_rwlock_rdlock(toku_pthread_rwlock_t *rwlock) {
return pthread_rwlock_rdlock(rwlock);
}
static inline int
toku_pthread_rwlock_rdunlock(toku_pthread_rwlock_t *rwlock) {
return pthread_rwlock_unlock(rwlock);
}
static inline int
toku_pthread_rwlock_wrlock(toku_pthread_rwlock_t *rwlock) {
return pthread_rwlock_wrlock(rwlock);
}
static inline int
toku_pthread_rwlock_wrunlock(toku_pthread_rwlock_t *rwlock) {
return pthread_rwlock_unlock(rwlock);
}
int toku_pthread_yield(void);
......
......@@ -44,6 +44,7 @@ BRT_SOURCES = \
brt \
brt-test-helpers \
cachetable \
checkpoint \
fifo \
fingerprint \
key \
......
......@@ -169,12 +169,10 @@ struct brt_header {
char *panic_string; // A malloced string that can indicate what went wrong.
int layout_version;
unsigned int nodesize;
int n_named_roots; /* -1 if the only one is unnamed */
char **names; // an array of names. NULL if subdatabases are not allowed.
BLOCKNUM *roots; // An array of the roots of the various dictionaries. Element 0 holds the element if no subdatabases allowed.
struct remembered_hash *root_hashes; // an array of hashes of the root offsets.
unsigned int *flags_array; // an array of flags. Element 0 holds the element if no subdatabases allowed.
struct descriptor *descriptors; // an array of descriptors. Element 0 holds the element if no subdatabases allowed.
BLOCKNUM root; // roots of the dictionary
struct remembered_hash root_hash; // hash of the root offset.
unsigned int flags;
struct descriptor descriptor;
FIFO fifo; // all the abort and commit commands. If the header gets flushed to disk, we write the fifo contents beyond the unused_memory.
......@@ -186,7 +184,6 @@ struct brt_header {
struct brt {
CACHEFILE cf;
char *fname; // the filename
char *database_name;
// The header is shared. It is also ephemeral.
struct brt_header *h;
......@@ -238,12 +235,11 @@ struct brtenv {
CACHETABLE ct;
TOKULOGGER logger;
long long checksum_number;
// SPINLOCK checkpointing;
};
extern void toku_brtnode_flush_callback (CACHEFILE cachefile, BLOCKNUM nodename, void *brtnode_v, void *extraargs, long size, BOOL write_me, BOOL keep_me, LSN modified_lsn, BOOL rename_p, BOOL for_checkpoint);
extern void toku_brtnode_flush_callback (CACHEFILE cachefile, BLOCKNUM nodename, void *brtnode_v, void *extraargs, long size, BOOL write_me, BOOL keep_me, BOOL for_checkpoint);
extern int toku_brtnode_fetch_callback (CACHEFILE cachefile, BLOCKNUM nodename, u_int32_t fullhash, void **brtnode_pv, long *sizep, void*extraargs, LSN *written_lsn);
extern int toku_brt_alloc_init_header(BRT t, const char *dbname);
extern int toku_brt_alloc_init_header(BRT t);
extern int toku_read_brt_header_and_store_in_cachefile (CACHEFILE cf, struct brt_header **header);
extern CACHEKEY* toku_calculate_root_offset_pointer (BRT brt, u_int32_t *root_hash);
......@@ -327,7 +323,7 @@ enum brt_layout_version_e {
BRT_LAYOUT_VERSION_7 = 7, // Diff from 6 to 7: Add exact-bit to leafentry_estimate #818, add magic to header #22, add per-subdatase flags #333
BRT_LAYOUT_VERSION_8 = 8, // Diff from 7 to 8: Use murmur instead of crc32. We are going to make a simplification and stop supporting version 7 and before. Current As of Beta 1.0.6
BRT_LAYOUT_VERSION_9 = 9, // Diff from 8 to 9: Variable-sized blocks and compression.
BRT_LAYOUT_VERSION_10 = 10, // Diff from 9 to 10: Variable number of compressed sub-blocks per block, disk byte order == intel byte order, Subtree estimates instead of just leafentry estimates, translation table, dictionary descriptors, checksum in header
BRT_LAYOUT_VERSION_10 = 10, // Diff from 9 to 10: Variable number of compressed sub-blocks per block, disk byte order == intel byte order, Subtree estimates instead of just leafentry estimates, translation table, dictionary descriptors, checksum in header, subdb support removed from brt layer
BRT_ANTEULTIMATE_VERSION, // the version after the most recent version
BRT_LAYOUT_VERSION = BRT_ANTEULTIMATE_VERSION-1 // A hack so I don't have to change this line.
};
......
......@@ -915,7 +915,7 @@ void toku_verify_counts (BRTNODE node) {
}
}
int toku_serialize_brt_header_size (struct brt_header *h) {
int toku_serialize_brt_header_size (struct brt_header *UU(h)) {
unsigned int size = (+8 // "tokudata"
+4 // size
+4 // version
......@@ -925,25 +925,12 @@ int toku_serialize_brt_header_size (struct brt_header *h) {
+4 // tree's nodesize
+8 // translation_size_on_disk
+8 // translation_address_on_disk
+4 // n_named_roots
+4 // checksum
);
if (h->n_named_roots<0) {
size+=(+8 // diskoff
+4 // flags
+8 // blocknum of descriptor
);
} else {
int i;
for (i=0; i<h->n_named_roots; i++) {
size+=(+8 // root diskoff
+4 // flags
+4 // length of null terminated string (including null)
+1 + strlen(h->names[i]) // null-terminated string
+8 // blocknum of descriptor
);
}
}
size+=(+8 // diskoff
+4 // flags
+8 // blocknum of descriptor
);
assert(size <= BLOCK_ALLOCATOR_HEADER_RESERVE);
return size;
}
......@@ -964,26 +951,12 @@ int toku_serialize_brt_header_to_wbuf (struct wbuf *wbuf, struct brt_header *h,
wbuf_LSN (wbuf, h->checkpoint_lsn);
wbuf_int (wbuf, h->nodesize);
wbuf_int (wbuf, h->n_named_roots);
//printf("%s:%d bta=%lu size=%lu\n", __FILE__, __LINE__, h->block_translation_address_on_disk, 4 + 16*h->translated_blocknum_limit);
wbuf_DISKOFF(wbuf, translation_location_on_disk);
wbuf_DISKOFF(wbuf, translation_size_on_disk);
if (h->n_named_roots>=0) {
int i;
for (i=0; i<h->n_named_roots; i++) {
char *s = h->names[i];
unsigned int l = 1+strlen(s);
wbuf_BLOCKNUM(wbuf, h->roots[i]);
wbuf_int (wbuf, h->flags_array[i]);
wbuf_bytes (wbuf, s, l);
assert(l>0 && s[l-1]==0);
serialize_descriptor_to_wbuf(wbuf, &h->descriptors[i]);
}
} else {
wbuf_BLOCKNUM(wbuf, h->roots[0]);
wbuf_int (wbuf, h->flags_array[0]);
serialize_descriptor_to_wbuf(wbuf, &h->descriptors[0]);
}
wbuf_BLOCKNUM(wbuf, h->root);
wbuf_int (wbuf, h->flags);
serialize_descriptor_to_wbuf(wbuf, &h->descriptor);
u_int32_t checksum = x1764_finish(&wbuf->checksum);
wbuf_int(wbuf, checksum);
assert(wbuf->ndone<=wbuf->size);
......@@ -1147,7 +1120,6 @@ deserialize_brtheader (int fd, struct rbuf *rb, struct brt_header **brth) {
h->checkpoint_count = rbuf_ulonglong(&rc);
h->checkpoint_lsn = rbuf_lsn(&rc);
h->nodesize = rbuf_int(&rc);
h->n_named_roots = rbuf_int(&rc);
DISKOFF translation_address_on_disk = rbuf_diskoff(&rc);
DISKOFF translation_size_on_disk = rbuf_diskoff(&rc);
assert(translation_address_on_disk>0);
......@@ -1172,41 +1144,14 @@ deserialize_brtheader (int fd, struct rbuf *rb, struct brt_header **brth) {
toku_free(tbuf);
}
if (h->n_named_roots>=0) {
int i;
int n_to_malloc = (h->n_named_roots == 0) ? 1 : h->n_named_roots;
MALLOC_N(n_to_malloc, h->flags_array); if (h->flags_array==0) { ret=errno; if (0) { died2: toku_free(h->flags_array); } goto died1; }
MALLOC_N(n_to_malloc, h->roots); if (h->roots==0) { ret=errno; if (0) { died3: if (h->roots) toku_free(h->roots); } goto died2; }
MALLOC_N(n_to_malloc, h->root_hashes); if (h->root_hashes==0) { ret=errno; if (0) { died4: if (h->root_hashes) toku_free(h->root_hashes); } goto died3; }
MALLOC_N(n_to_malloc, h->descriptors); if (h->descriptors==0) { ret=errno; if (0) { died5: if (h->descriptors) toku_free(h->descriptors); } goto died4; }
MALLOC_N(n_to_malloc, h->names); if (h->names==0) { ret=errno; if (0) { died6: if (h->names) toku_free(h->names); } goto died5; }
for (i=0; i<h->n_named_roots; i++) {
h->root_hashes[i].valid = FALSE;
h->roots[i] = rbuf_blocknum(&rc);
h->flags_array[i] = rbuf_int(&rc);
bytevec nameptr;
unsigned int len;
rbuf_bytes(&rc, &nameptr, &len);
assert(strlen(nameptr)+1==len);
h->names[i] = toku_memdup(nameptr, len);
assert(len == 0 || h->names[i] != NULL); // make sure the malloc worked. Give up if this malloc failed...
deserialize_descriptor_from(fd, &rc, h, &h->descriptors[i]);
}
} else {
int n_to_malloc = 1;
MALLOC_N(n_to_malloc, h->flags_array); if (h->flags_array==0) { ret=errno; goto died1; }
MALLOC_N(n_to_malloc, h->roots); if (h->roots==0) { ret=errno; goto died2; }
MALLOC_N(n_to_malloc, h->root_hashes); if (h->root_hashes==0) { ret=errno; goto died3; }
MALLOC_N(n_to_malloc, h->descriptors); if (h->descriptors==0) { ret=errno; goto died4; }
h->names = 0;
h->roots[0] = rbuf_blocknum(&rc);
h->root_hashes[0].valid = FALSE;
h->flags_array[0] = rbuf_int(&rc);
deserialize_descriptor_from(fd, &rc, h, &h->descriptors[0]);
}
h->root = rbuf_blocknum(&rc);
h->root_hash.valid = FALSE;
h->flags = rbuf_int(&rc);
deserialize_descriptor_from(fd, &rc, h, &h->descriptor);
(void)rbuf_int(&rc); //Read in checksum and ignore (already verified).
if (rc.ndone!=rc.size) {ret = EINVAL; goto died6;}
if (rc.ndone!=rc.size) {ret = EINVAL; goto died1;}
toku_free(rc.buf);
rc.buf = NULL;
{
int r;
DISKOFF offset;
......@@ -1304,6 +1249,8 @@ int toku_deserialize_brtheader_from (int fd, struct brt_header **brth) {
}
if (r==0) r = deserialize_brtheader(fd, rb, brth);
if (r0==0 && rb_0.buf) toku_free(rb_0.buf);
if (r1==0 && rb_1.buf) toku_free(rb_1.buf);
return r;
}
......
......@@ -43,8 +43,8 @@ int toku_testsetup_nonleaf (BRT brt, int height, BLOCKNUM *blocknum, int n_child
int toku_testsetup_root(BRT brt, BLOCKNUM blocknum) {
int r = toku_read_brt_header_and_store_in_cachefile(brt->cf, &brt->h);
if (r!=0) return r;
brt->h->roots[0] = blocknum;
brt->h->root_hashes[0].valid = FALSE;
brt->h->root = blocknum;
brt->h->root_hash.valid = FALSE;
return 0;
}
......
This diff is collapsed.
......@@ -26,7 +26,7 @@ typedef int(*BRT_GET_CALLBACK_FUNCTION)(ITEMLEN, bytevec, ITEMLEN, bytevec, void
//the element on the other side of the border (as in heaviside function).
typedef int(*BRT_GET_STRADDLE_CALLBACK_FUNCTION)(ITEMLEN, bytevec, ITEMLEN, bytevec, ITEMLEN, bytevec, ITEMLEN, bytevec, void*);
int toku_open_brt (const char *fname, const char *dbname, int is_create, BRT *, int nodesize, CACHETABLE, TOKUTXN, int(*)(DB*,const DBT*,const DBT*), DB*);
int toku_open_brt (const char *fname, int is_create, BRT *, int nodesize, CACHETABLE, TOKUTXN, int(*)(DB*,const DBT*,const DBT*), DB*);
int toku_brt_create(BRT *);
int toku_brt_set_flags(BRT, unsigned int flags);
......@@ -37,7 +37,7 @@ int toku_brt_get_nodesize(BRT, unsigned int *nodesize);
int toku_brt_set_bt_compare(BRT, int (*bt_compare)(DB *, const DBT*, const DBT*));
int toku_brt_set_dup_compare(BRT, int (*dup_compare)(DB *, const DBT*, const DBT*));
int brt_set_cachetable(BRT, CACHETABLE);
int toku_brt_open(BRT, const char *fname, const char *fname_in_env, const char *dbname, int is_create, int only_create, CACHETABLE ct, TOKUTXN txn, DB *db);
int toku_brt_open(BRT, const char *fname, const char *fname_in_env, int is_create, int only_create, CACHETABLE ct, TOKUTXN txn, DB *db);
int toku_brt_remove_subdb(BRT brt, const char *dbname, u_int32_t flags);
......@@ -133,7 +133,7 @@ int toku_brt_stat64 (BRT, TOKUTXN,
u_int64_t *fsize /* the size of the underlying file */
);
void toku_brt_init(void);
void toku_brt_init(void (*ydb_lock_callback)(void), void (*ydb_unlock_callback)(void));
void toku_brt_destroy(void);
void toku_pwrite_lock_init(void);
void toku_pwrite_lock_destroy(void);
......
......@@ -30,19 +30,8 @@ dump_header (int f, struct brt_header **header) {
else printf(" layout_version=%d\n", h->layout_version);
printf(" dirty=%d\n", h->dirty);
printf(" nodesize=%u\n", h->nodesize);
if (h->n_named_roots==-1) {
printf(" unnamed_root=%" PRId64 "\n", h->roots[0].b);
printf(" flags=%u\n", h->flags_array[0]);
} else {
printf(" n_named_roots=%d\n", h->n_named_roots);
if (h->n_named_roots>=0) {
int i;
for (i=0; i<h->n_named_roots; i++) {
printf(" %s -> %" PRId64 "\n", h->names[i], h->roots[i].b);
printf(" flags=%u\n", h->flags_array[i]);
}
}
}
printf(" unnamed_root=%" PRId64 "\n", h->root.b);
printf(" flags=%u\n", h->flags);
*header = h;
printf("Fifo:\n");
printf(" fifo has %d entries\n", toku_fifo_n_entries(h->fifo));
......
......@@ -60,16 +60,7 @@ typedef struct loggedbrtheader {
u_int32_t nodesize;
BLOCKNUM free_blocks;
BLOCKNUM unused_blocks;
int32_t n_named_roots; // -1 for the union below to be "one".
union {
struct {
char **names;
BLOCKNUM *roots;
} many;
struct {
BLOCKNUM root;
} one;
} u;
BLOCKNUM root;
BLOCKNUM btt_size; // block translation table size
DISKOFF btt_diskoff;
struct logged_btt_pair *btt_pairs;
......
This diff is collapsed.
......@@ -35,9 +35,9 @@ int toku_create_cachetable(CACHETABLE */*result*/, long size_limit, LSN initial_
// During a transaction, we cannot reuse a filenum.
int toku_cachefile_of_filenum (CACHETABLE t, FILENUM filenum, CACHEFILE *cf);
// Checkpoint the cachetable.
// Effects: ?
int toku_cachetable_checkpoint (CACHETABLE ct, TOKULOGGER);
// TODO: #1510 Add comments on how these behave
int toku_cachetable_begin_checkpoint (CACHETABLE ct, TOKULOGGER);
int toku_cachetable_end_checkpoint(CACHETABLE ct, TOKULOGGER logger, char **error_string);
// Does an fsync of a cachefile.
// Handles the case where cf points to /dev/null
......@@ -65,7 +65,7 @@ void toku_cachefile_get_workqueue_load (CACHEFILE, int *n_in_queue, int *n_threa
// When keep_me is false, the value should be freed.
// When for_checkpoint is true, this was a 'pending' write
// Returns: 0 if success, otherwise an error number.
typedef void (*CACHETABLE_FLUSH_CALLBACK)(CACHEFILE, CACHEKEY key, void *value, void *extraargs, long size, BOOL write_me, BOOL keep_me, LSN modified_lsn, BOOL rename_p, BOOL for_checkpoint);
typedef void (*CACHETABLE_FLUSH_CALLBACK)(CACHEFILE, CACHEKEY key, void *value, void *extraargs, long size, BOOL write_me, BOOL keep_me, BOOL for_checkpoint);
// The fetch callback is called when a thread is attempting to get and pin a memory
// object and it is not in the cachetable.
......
/* -*- mode: C; c-basic-offset: 4 -*- */
#ident "Copyright (c) 2009 Tokutek Inc. All rights reserved."
#ident "The technology is licensed by the Massachusetts Institute of Technology, Rutgers State University of New Jersey, and the Research Foundation of State University of New York at Stony Brook under United States of America Serial No. 11/760379 and to the patents and/or patent applications resulting from it."
#ident "$Id$"
/***********
* The purpose of this file is to implement the high-level logic for
* taking a checkpoint.
*
* There are three locks used for taking a checkpoint. They are:
*
* NOTE: The reader-writer locks may be held by either multiple clients
* or the checkpoint function. (The checkpoint function has the role
* of the writer, the clients have the reader roles.)
*
* - multi_operation_lock
* This is a new reader-writer lock.
* This lock is held by the checkpoint function only for as long as is required to
* to set all the "pending" bits and to create the checkpoint-in-progress versions
* of the header and translation table (btt).
* The following operations must take the multi_operation_lock:
* - insertion into multiple indexes
* - "replace-into" (matching delete and insert on a single key)
*
* - checkpoint_safe_lock
* This is a new reader-writer lock.
* This lock is held for the entire duration of the checkpoint.
* It is used to prevent more than one checkpoint from happening at a time
* (the checkpoint function is non-re-entrant), and to prevent certain operations
* that should not happen during a checkpoint.
* The following operations must take the checkpoint_safe lock:
* - open a dictionary
* - close a dictionary
* - delete a dictionary
* - truncate a dictionary
* - rename a dictionary
*
* - ydb_big_lock
* This is the existing lock used to serialize all access to tokudb.
* This lock is held by the checkpoint function only for as long as is required to
* to set all the "pending" bits and to create the checkpoint-in-progress versions
* of the header and translation table (btt).
*
* Once the "pending" bits are set and the snapshots are take of the header and btt,
* most normal database operations are permitted to resume.
*
*
*
*****/
#include <stdio.h>
#include "brttypes.h"
#include "toku_portability.h"
#include "cachetable.h"
#include "checkpoint.h"
static toku_pthread_rwlock_t checkpoint_safe_lock;
static toku_pthread_rwlock_t multi_operation_lock;
static void (*ydb_lock)(void) = NULL;
static void (*ydb_unlock)(void) = NULL;
// Note following static functions are called from checkpoint internal logic only,
// and use the "writer" calls for locking and unlocking.
static void
multi_operation_lock_init(void) {
int r = toku_pthread_rwlock_init(&multi_operation_lock, NULL);
assert(r == 0);
}
static void
multi_operation_lock_destroy(void) {
int r = toku_pthread_rwlock_destroy(&multi_operation_lock);
assert(r == 0);
}
static void
multi_operation_checkpoint_lock(void) {
int r = toku_pthread_rwlock_wrlock(&multi_operation_lock);
assert(r == 0);
}
static void
multi_operation_checkpoint_unlock(void) {
int r = toku_pthread_rwlock_wrunlock(&multi_operation_lock);
assert(r == 0);
}
static void
checkpoint_safe_lock_init(void) {
int r = toku_pthread_rwlock_init(&checkpoint_safe_lock, NULL);
assert(r == 0);
}
static void
checkpoint_safe_lock_destroy(void) {
int r = toku_pthread_rwlock_destroy(&checkpoint_safe_lock);
assert(r == 0);
}
static void
checkpoint_safe_checkpoint_lock(void) {
int r = toku_pthread_rwlock_wrlock(&checkpoint_safe_lock);
assert(r == 0);
}
static void
checkpoint_safe_checkpoint_unlock(void) {
int r = toku_pthread_rwlock_wrunlock(&checkpoint_safe_lock);
assert(r == 0);
}
// toku_xxx_client_(un)lock() functions are only called from client code,
// never from checkpoint code, and use the "reader" interface to the lock functions.
void
toku_multi_operation_client_lock(void) {
int r = toku_pthread_rwlock_rdlock(&multi_operation_lock);
assert(r == 0);
}
void
toku_multi_operation_client_unlock(void) {
int r = toku_pthread_rwlock_rdunlock(&multi_operation_lock);
assert(r == 0);
}
void
toku_checkpoint_safe_client_lock(void) {
int r = toku_pthread_rwlock_rdlock(&checkpoint_safe_lock);
assert(r == 0);
}
void
toku_checkpoint_safe_client_unlock(void) {
int r = toku_pthread_rwlock_rdunlock(&checkpoint_safe_lock);
assert(r == 0);
}
static BOOL initialized = FALSE;
// Initialize the checkpoint mechanism, must be called before any client operations.
void
toku_checkpoint_init(void (*ydb_lock_callback)(void), void (*ydb_unlock_callback)(void)) {
ydb_lock = ydb_lock_callback;
ydb_unlock = ydb_unlock_callback;
multi_operation_lock_init();
checkpoint_safe_lock_init();
initialized = TRUE;
}
void toku_checkpoint_destroy(void) {
multi_operation_lock_destroy();
checkpoint_safe_lock_destroy();
initialized = FALSE;
}
// Take a checkpoint of all currently open dictionaries
int
toku_checkpoint(CACHETABLE ct, TOKULOGGER logger, char **error_string) {
int r;
printf("Yipes, checkpoint is being tested\n");
assert(initialized);
multi_operation_checkpoint_lock();
checkpoint_safe_checkpoint_lock();
ydb_lock();
r = toku_cachetable_begin_checkpoint(ct, logger);
multi_operation_checkpoint_unlock();
ydb_unlock();
if (r==0) {
r = toku_cachetable_end_checkpoint(ct, logger, error_string);
}
checkpoint_safe_checkpoint_unlock();
return r;
}
/* -*- mode: C; c-basic-offset: 4 -*- */
#ident "Copyright (c) 2009 Tokutek Inc. All rights reserved."
#ident "The technology is licensed by the Massachusetts Institute of Technology, Rutgers State University of New Jersey, and the Research Foundation of State University of New York at Stony Brook under United States of America Serial No. 11/760379 and to the patents and/or patent applications resulting from it."
#ident "$Id$"
// TODO: $1510 Need callback mechanism so newbrt layer can get/release ydb lock.
/******
*
* NOTE: atomic operation lock is highest level lock
* checkpoint_safe lock is next level lock
* ydb_big_lock is next level lock
*
* Locks must always be taken in this sequence (highest level first).
*
*/
/****** TODO: ydb layer should be taking this lock
* Client code must hold the checkpoint_safe lock during the following operations:
* - delete a dictionary
* - truncate a dictionary
* - rename a dictionary
* - abort a transaction that created a dictionary (abort causes dictionary delete)
* - abort a transaction that had a table lock on an empty table (abort causes dictionary truncate)
*****/
void toku_checkpoint_safe_client_lock(void);
void toku_checkpoint_safe_client_unlock(void);
/****** TODO: rename these functions as something like begin_atomic_operation and end_atomic_operation
* these may need ydb wrappers
* These functions are called from the handlerton level.
* Client code must hold the multi_operation lock during the following operations:
* - insertion into multiple indexes
* - replace into (simultaneous delete/insert on a single key)
*****/
void toku_multi_operation_client_lock(void);
void toku_multi_operation_client_unlock(void);
// Initialize the checkpoint mechanism, must be called before any client operations.
// Must pass in function pointers to take/release ydb lock.
void toku_checkpoint_init(void (*ydb_lock_callback)(void), void (*ydb_unlock_callback)(void));
void toku_checkpoint_destroy(void);
// Take a checkpoint of all currently open dictionaries
int toku_checkpoint(CACHETABLE ct, TOKULOGGER logger, char **error_string);
......@@ -37,7 +37,7 @@
#include "brt.h"
#include "brt-internal.h"
#include "cachetable.h"
#include "cachetable-rwlock.h"
#include "rwlock.h"
#include "fifo.h"
#include "list.h"
#include "key.h"
......
......@@ -139,17 +139,7 @@ static inline int toku_logsizeof_LOGGEDBRTHEADER (LOGGEDBRTHEADER bs) {
in_both += 8; // for the number of block headers
assert(bs.btt_size.b< 30000000); // otherwise we in trouble on the next line
in_both += 12*bs.btt_size.b;
if (bs.n_named_roots==-1)
return in_both+8;
else {
int sum_of_pieces=0;
int i;
for (i=0; i<bs.n_named_roots; i++) {
sum_of_pieces += 4+8+1+strlen(bs.u.many.names[i]);
}
return in_both+sum_of_pieces;
}
return in_both+8;
}
static inline int toku_logsizeof_INTPAIRARRAY (INTPAIRARRAY pa) {
......
......@@ -674,11 +674,9 @@ int toku_fread_LOGGEDBRTHEADER (FILE *f, LOGGEDBRTHEADER *v, struct x1764 *check
r = toku_fread_u_int32_t(f, &v->nodesize, checksum, len); if (r!=0) return r;
r = toku_fread_BLOCKNUM (f, &v->free_blocks, checksum, len); if (r!=0) return r;
r = toku_fread_BLOCKNUM (f, &v->unused_blocks, checksum, len); if (r!=0) return r;
r = toku_fread_int32_t (f, &v->n_named_roots, checksum, len); if (r!=0) return r;
assert(v->n_named_roots==-1);
r = toku_fread_BLOCKNUM (f, &v->u.one.root, checksum, len); if (r!=0) return r;
r = toku_fread_BLOCKNUM (f, &v->btt_size, checksum, len); if (r!=0) return r;
r = toku_fread_DISKOFF (f, &v->btt_diskoff, checksum, len); if (r!=0) return r;
r = toku_fread_BLOCKNUM (f, &v->root, checksum, len); if (r!=0) return r;
r = toku_fread_BLOCKNUM (f, &v->btt_size, checksum, len); if (r!=0) return r;
r = toku_fread_DISKOFF (f, &v->btt_diskoff, checksum, len); if (r!=0) return r;
XMALLOC_N(v->btt_size.b, v->btt_pairs);
int64_t i;
for (i=0; i<v->btt_size.b; i++) {
......@@ -790,7 +788,7 @@ int toku_logprint_LOGGEDBRTHEADER (FILE *outf, FILE *inf, const char *fieldname,
LOGGEDBRTHEADER v;
int r = toku_fread_LOGGEDBRTHEADER(inf, &v, checksum, len);
if (r!=0) return r;
fprintf(outf, " %s={size=%u flags=%u nodesize=%u free_blocks=%" PRId64 " unused_memory=%" PRId64 " n_named_roots=%d", fieldname, v.size, v.flags, v.nodesize, v.free_blocks.b, v.unused_blocks.b, v.n_named_roots);
fprintf(outf, " %s={size=%u flags=%u nodesize=%u free_blocks=%" PRId64 " unused_memory=%" PRId64, fieldname, v.size, v.flags, v.nodesize, v.free_blocks.b, v.unused_blocks.b);
fprintf(outf, " btt_size=%" PRId64 " btt_diskoff=%" PRId64 " btt_pairs={", v.btt_size.b, v.btt_diskoff) ;
int64_t i;
for (i=0; i<v.btt_size.b; i++) {
......
......@@ -135,33 +135,10 @@ static inline void toku_free_BYTESTRING(BYTESTRING val) {
static inline int toku_copy_LOGGEDBRTHEADER(LOGGEDBRTHEADER *target, LOGGEDBRTHEADER val) {
*target = val;
if ((int32_t)val.n_named_roots!=-1) {
int r;
target->u.many.names = toku_memdup(target->u.many.names, val.n_named_roots*sizeof(target->u.many.names[0]));
if (target->u.many.names==0) { r=errno; if (0) { died0: toku_free(target->u.many.names); } return r; }
target->u.many.roots = toku_memdup(target->u.many.roots, val.n_named_roots*sizeof(target->u.many.roots[0]));
if (target->u.many.roots==0) { r=errno; if (0) { died1: toku_free(target->u.many.names); } goto died0; }
int32_t i;
for (i=0; i<val.n_named_roots; i++) {
target->u.many.names[i] = toku_strdup(target->u.many.names[i]);
if (target->u.many.names[i]==0) {
int32_t j;
r=errno;
for (j=0; j<i; j++) toku_free(target->u.many.names[j]);
goto died1;
}
}
}
return 0;
}
static inline void toku_free_LOGGEDBRTHEADER(LOGGEDBRTHEADER val) {
if ((int32_t)val.n_named_roots==-1) return;
int32_t i;
for (i=0; i<val.n_named_roots; i++) {
toku_free(val.u.many.names[i]);
}
toku_free(val.u.many.names);
toku_free(val.u.many.roots);
static inline void toku_free_LOGGEDBRTHEADER(LOGGEDBRTHEADER UU(val)) {
return;
}
int toku_recover_init(void);
......
......@@ -112,7 +112,6 @@ internal_toku_recover_fopen_or_fcreate (int flags, int mode, char *fixedfname, F
int r = toku_brt_create(&brt);
assert(r==0);
brt->fname = fixedfname;
brt->database_name = 0;
brt->h=0;
brt->compare_fun = toku_default_compare_fun; // we'll need to set these to the right comparison function, or do without them.
brt->dup_compare = toku_default_compare_fun;
......@@ -122,7 +121,7 @@ internal_toku_recover_fopen_or_fcreate (int flags, int mode, char *fixedfname, F
brt->cf=cf;
r = toku_read_brt_header_and_store_in_cachefile(brt->cf, &brt->h);
if (r==-1) {
r = toku_brt_alloc_init_header(brt, 0);
r = toku_brt_alloc_init_header(brt);
}
toku_recover_note_cachefile(filenum, cf, brt);
}
......@@ -163,23 +162,15 @@ static void toku_recover_fheader (LSN UU(lsn), TXNID UU(txnid),FILENUM filenum,
h->dirty=0;
h->panic=0;
h->panic_string=0;
XMALLOC(h->flags_array);
h->flags_array[0] = header.flags;
h->flags = header.flags;
h->nodesize = header.nodesize;
//toku_blocktable_create_from_loggedheader(&h->blocktable, header);
assert(0); //create from loggedheader disabled for now. //TODO: #1605
assert(h->blocktable);
h->n_named_roots = header.n_named_roots;
r=toku_fifo_create(&h->fifo);
assert(r==0);
if ((signed)header.n_named_roots==-1) {
MALLOC_N(1, h->roots); assert(h->roots);
MALLOC_N(1, h->root_hashes); assert(h->root_hashes);
h->roots[0] = header.u.one.root;
h->root_hashes[0].valid= FALSE;
} else {
assert(0);
}
h->root = header.root;
h->root_hash.valid= FALSE;
//toku_cachetable_put(pair->cf, header_blocknum, fullhash, h, 0, toku_brtheader_flush_callback, toku_brtheader_fetch_callback, 0);
if (pair->brt) {
toku_free(pair->brt->h);
......@@ -187,7 +178,6 @@ static void toku_recover_fheader (LSN UU(lsn), TXNID UU(txnid),FILENUM filenum,
r = toku_brt_create(&pair->brt);
assert(r==0);
pair->brt->cf = pair->cf;
pair->brt->database_name = 0; // Special case, we don't know or care what the database name is for recovery.
list_init(&pair->brt->cursors);
pair->brt->compare_fun = 0;
pair->brt->dup_compare = 0;
......@@ -270,8 +260,8 @@ toku_recover_changeunnamedroot (LSN UU(lsn), FILENUM filenum, BLOCKNUM UU(oldroo
assert(r==0);
assert(pair->brt);
assert(pair->brt->h);
pair->brt->h->roots[0] = newroot;
pair->brt->h->root_hashes[0].valid = FALSE;
pair->brt->h->root = newroot;
pair->brt->h->root_hash.valid = FALSE;
}
static void
toku_recover_changenamedroot (LSN UU(lsn), FILENUM UU(filenum), BYTESTRING UU(name), BLOCKNUM UU(oldroot), BLOCKNUM UU(newroot)) { assert(0); }
......
/* -*- mode: C; c-basic-offset: 4 -*- */
#ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved."
//Use case:
// A read lock is acquired by threads that get and pin an entry in the
// cachetable. A write lock is acquired by the writer thread when an entry
// is evicted from the cachetable and is being written storage.
// Properties:
//Use case:
// General purpose reader writer lock with properties:
// 1. multiple readers, no writers
// 2. one writer at a time
// 3. pending writers have priority over pending readers
......@@ -12,11 +16,11 @@
// increase parallelism at the expense of single thread performance, we
// are experimenting with a single higher level lock.
typedef struct ctpair_rwlock *CTPAIR_RWLOCK;
struct ctpair_rwlock {
int pinned; // the number of readers
int want_pin; // the number of blocked readers
toku_pthread_cond_t wait_pin;
typedef struct rwlock *RWLOCK;
struct rwlock {
int reader; // the number of readers
int want_read; // the number of blocked readers
toku_pthread_cond_t wait_read;
int writer; // the number of writers
int want_write; // the number of blocked writers
toku_pthread_cond_t wait_write;
......@@ -26,10 +30,10 @@ struct ctpair_rwlock {
static __attribute__((__unused__))
void
ctpair_rwlock_init(CTPAIR_RWLOCK rwlock) {
rwlock_init(RWLOCK rwlock) {
int r;
rwlock->pinned = rwlock->want_pin = 0;
r = toku_pthread_cond_init(&rwlock->wait_pin, 0); assert(r == 0);
rwlock->reader = rwlock->want_read = 0;
r = toku_pthread_cond_init(&rwlock->wait_read, 0); assert(r == 0);
rwlock->writer = rwlock->want_write = 0;
r = toku_pthread_cond_init(&rwlock->wait_write, 0); assert(r == 0);
}
......@@ -38,34 +42,34 @@ ctpair_rwlock_init(CTPAIR_RWLOCK rwlock) {
static __attribute__((__unused__))
void
ctpair_rwlock_destroy(CTPAIR_RWLOCK rwlock) {
rwlock_destroy(RWLOCK rwlock) {
int r;
assert(rwlock->pinned == 0 && rwlock->want_pin == 0);
assert(rwlock->reader == 0 && rwlock->want_read == 0);
assert(rwlock->writer == 0 && rwlock->want_write == 0);
r = toku_pthread_cond_destroy(&rwlock->wait_pin); assert(r == 0);
r = toku_pthread_cond_destroy(&rwlock->wait_read); assert(r == 0);
r = toku_pthread_cond_destroy(&rwlock->wait_write); assert(r == 0);
}
// obtain a read lock
// expects: mutex is locked
static inline void ctpair_read_lock(CTPAIR_RWLOCK rwlock, toku_pthread_mutex_t *mutex) {
static inline void rwlock_read_lock(RWLOCK rwlock, toku_pthread_mutex_t *mutex) {
if (rwlock->writer || rwlock->want_write) {
rwlock->want_pin++;
rwlock->want_read++;
while (rwlock->writer || rwlock->want_write) {
int r = toku_pthread_cond_wait(&rwlock->wait_pin, mutex); assert(r == 0);
int r = toku_pthread_cond_wait(&rwlock->wait_read, mutex); assert(r == 0);
}
rwlock->want_pin--;
rwlock->want_read--;
}
rwlock->pinned++;
rwlock->reader++;
}
// release a read lock
// expects: mutex is locked
static inline void ctpair_read_unlock(CTPAIR_RWLOCK rwlock) {
rwlock->pinned--;
if (rwlock->pinned == 0 && rwlock->want_write) {
static inline void rwlock_read_unlock(RWLOCK rwlock) {
rwlock->reader--;
if (rwlock->reader == 0 && rwlock->want_write) {
int r = toku_pthread_cond_signal(&rwlock->wait_write); assert(r == 0);
}
}
......@@ -73,10 +77,10 @@ static inline void ctpair_read_unlock(CTPAIR_RWLOCK rwlock) {
// obtain a write lock
// expects: mutex is locked
static inline void ctpair_write_lock(CTPAIR_RWLOCK rwlock, toku_pthread_mutex_t *mutex) {
if (rwlock->pinned || rwlock->writer) {
static inline void rwlock_write_lock(RWLOCK rwlock, toku_pthread_mutex_t *mutex) {
if (rwlock->reader || rwlock->writer) {
rwlock->want_write++;
while (rwlock->pinned || rwlock->writer) {
while (rwlock->reader || rwlock->writer) {
int r = toku_pthread_cond_wait(&rwlock->wait_write, mutex); assert(r == 0);
}
rwlock->want_write--;
......@@ -87,32 +91,32 @@ static inline void ctpair_write_lock(CTPAIR_RWLOCK rwlock, toku_pthread_mutex_t
// release a write lock
// expects: mutex is locked
static inline void ctpair_write_unlock(CTPAIR_RWLOCK rwlock) {
static inline void rwlock_write_unlock(RWLOCK rwlock) {
rwlock->writer--;
if (rwlock->writer == 0) {
if (rwlock->want_write) {
int r = toku_pthread_cond_signal(&rwlock->wait_write); assert(r == 0);
} else if (rwlock->want_pin) {
int r = toku_pthread_cond_broadcast(&rwlock->wait_pin); assert(r == 0);
} else if (rwlock->want_read) {
int r = toku_pthread_cond_broadcast(&rwlock->wait_read); assert(r == 0);
}
}
}
// returns: the number of readers
static inline int ctpair_pinned(CTPAIR_RWLOCK rwlock) {
return rwlock->pinned;
static inline int rwlock_readers(RWLOCK rwlock) {
return rwlock->reader;
}
// returns: the number of writers
static inline int ctpair_writers(CTPAIR_RWLOCK rwlock) {
static inline int rwlock_writers(RWLOCK rwlock) {
return rwlock->writer;
}
// returns: the sum of the number of readers, pending readers, writers, and
// pending writers
static inline int ctpair_users(CTPAIR_RWLOCK rwlock) {
return rwlock->pinned + rwlock->want_pin + rwlock->writer + rwlock->want_write;
static inline int rwlock_users(RWLOCK rwlock) {
return rwlock->reader + rwlock->want_read + rwlock->writer + rwlock->want_write;
}
......@@ -11,9 +11,11 @@
static int recovery_main(int argc, const char *argv[]);
static void dummy(void) {}
int
main(int argc, const char *argv[]) {
toku_brt_init();
toku_brt_init(dummy, dummy);
int r = recovery_main(argc, argv);
toku_brt_destroy();
return r;
......
......@@ -41,7 +41,6 @@ REGRESSION_TESTS_RAW = \
brt-test \
brt-test-cursor \
brt-test-cursor-2 \
brt-test-named-db \
brt-test0 \
brt-test1 \
brt-test2 \
......@@ -89,7 +88,6 @@ REGRESSION_TESTS_RAW = \
omt-test \
shortcut \
test1308a \
test1626 \
test-assert \
test-brt-delete-both \
test-brt-overflow \
......
......@@ -30,7 +30,7 @@ static void setup (void) {
int r;
unlink(fname);
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0);
r = toku_open_brt(fname, 0, 1, &t, nodesize, ct, NULL_TXN, toku_default_compare_fun, (DB*)0); assert(r==0);
r = toku_open_brt(fname, 1, &t, nodesize, ct, NULL_TXN, toku_default_compare_fun, (DB*)0); assert(r==0);
}
static void toku_shutdown (void) {
......
......@@ -16,7 +16,6 @@ static void test_sub_block(int n) {
TOKUTXN const null_txn = 0;
DB * const null_db = 0;
char * const null_dbname = 0;
int error;
CACHETABLE ct;
......@@ -28,7 +27,7 @@ static void test_sub_block(int n) {
error = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
assert(error == 0);
error = toku_open_brt(fname, null_dbname, TRUE, &brt, nodesize, ct, null_txn, toku_default_compare_fun, null_db);
error = toku_open_brt(fname, TRUE, &brt, nodesize, ct, null_txn, toku_default_compare_fun, null_db);
assert(error == 0);
// insert keys 0, 1, 2, .. (n-1)
......@@ -47,7 +46,7 @@ static void test_sub_block(int n) {
assert(error == 0);
// verify the brt by walking a cursor through the rows
error = toku_open_brt(fname, null_dbname, FALSE, &brt, nodesize, ct, null_txn, toku_default_compare_fun, null_db);
error = toku_open_brt(fname, FALSE, &brt, nodesize, ct, null_txn, toku_default_compare_fun, null_db);
assert(error == 0);
BRT_CURSOR cursor;
......
......@@ -34,7 +34,7 @@ static void test_multiple_brt_cursor_dbts(int n, DB *db) {
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
assert(r==0);
r = toku_open_brt(fname, 0, 1, &brt, 1<<12, ct, null_txn, toku_default_compare_fun, db);
r = toku_open_brt(fname, 1, &brt, 1<<12, ct, null_txn, toku_default_compare_fun, db);
assert(r==0);
int i;
......
......@@ -89,7 +89,7 @@ static void test_brt_cursor_first(int n, DB *db) {
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
assert(r==0);
r = toku_open_brt(fname, 0, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
r = toku_open_brt(fname, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
assert(r==0);
/* insert a bunch of kv pairs */
......@@ -130,7 +130,7 @@ static void test_brt_cursor_last(int n, DB *db) {
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
assert(r==0);
r = toku_open_brt(fname, 0, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
r = toku_open_brt(fname, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
assert(r==0);
/* insert keys 0, 1, .. (n-1) */
......@@ -171,7 +171,7 @@ static void test_brt_cursor_first_last(int n, DB *db) {
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
assert(r==0);
r = toku_open_brt(fname, 0, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
r = toku_open_brt(fname, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
assert(r==0);
/* insert a bunch of kv pairs */
......@@ -216,7 +216,7 @@ static void test_brt_cursor_rfirst(int n, DB *db) {
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
assert(r==0);
r = toku_open_brt(fname, 0, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
r = toku_open_brt(fname, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
assert(r==0);
/* insert keys n-1, n-2, ... , 0 */
......@@ -284,7 +284,7 @@ static void test_brt_cursor_walk(int n, DB *db) {
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
assert(r==0);
r = toku_open_brt(fname, 0, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
r = toku_open_brt(fname, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
assert(r==0);
/* insert a bunch of kv pairs */
......@@ -350,7 +350,7 @@ static void test_brt_cursor_rwalk(int n, DB *db) {
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
assert(r==0);
r = toku_open_brt(fname, 0, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
r = toku_open_brt(fname, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
assert(r==0);
/* insert a bunch of kv pairs */
......@@ -434,7 +434,7 @@ static void test_brt_cursor_rand(int n, DB *db) {
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
assert(r==0);
r = toku_open_brt(fname, 0, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
r = toku_open_brt(fname, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
assert(r==0);
/* insert a bunch of kv pairs */
......@@ -488,7 +488,7 @@ static void test_brt_cursor_split(int n, DB *db) {
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
assert(r==0);
r = toku_open_brt(fname, 0, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
r = toku_open_brt(fname, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
assert(r==0);
/* insert a bunch of kv pairs */
......@@ -564,7 +564,7 @@ static void test_multiple_brt_cursors(int n, DB *db) {
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
assert(r==0);
r = toku_open_brt(fname, 0, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
r = toku_open_brt(fname, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
assert(r==0);
int i;
......@@ -613,7 +613,7 @@ static void test_multiple_brt_cursor_walk(int n, DB *db) {
r = toku_brt_create_cachetable(&ct, cachesize, ZERO_LSN, NULL_LOGGER);
assert(r==0);
r = toku_open_brt(fname, 0, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
r = toku_open_brt(fname, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
assert(r==0);
int c;
......@@ -690,7 +690,7 @@ static void test_brt_cursor_set(int n, int cursor_op, DB *db) {
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
assert(r==0);
r = toku_open_brt(fname, 0, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
r = toku_open_brt(fname, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
assert(r==0);
int i;
......@@ -762,7 +762,7 @@ static void test_brt_cursor_set_range(int n, DB *db) {
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
assert(r==0);
r = toku_open_brt(fname, 0, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
r = toku_open_brt(fname, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
assert(r==0);
int i;
......@@ -826,7 +826,7 @@ static void test_brt_cursor_delete(int n, DB *db) {
error = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
assert(error == 0);
error = toku_open_brt(fname, 0, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
error = toku_open_brt(fname, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
assert(error == 0);
error = toku_brt_cursor(brt, &cursor);
......@@ -887,7 +887,7 @@ static void test_brt_cursor_get_both(int n, DB *db) {
error = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
assert(error == 0);
error = toku_open_brt(fname, 0, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
error = toku_open_brt(fname, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db);
assert(error == 0);
error = toku_brt_cursor(brt, &cursor);
......
/* -*- mode: C; c-basic-offset: 4 -*- */
#ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved."
#include "includes.h"
#include "test.h"
static TOKUTXN const null_txn = 0;
static DB * const null_db = 0;
static void test_named_db (void) {
const char *n0 = __FILE__ "0.brt";
CACHETABLE ct;
BRT t0;
int r;
DBT k,v;
if (verbose) printf("test_named_db\n");
unlink(n0);
toku_memory_check_all_free();
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0);
r = toku_open_brt(n0, "db1", 1, &t0, 1<<12, ct, null_txn, toku_default_compare_fun, null_db); assert(r==0);
toku_brt_insert(t0, toku_fill_dbt(&k, "good", 5), toku_fill_dbt(&v, "day", 4), null_txn); assert(r==0);
r = toku_close_brt(t0, 0, 0); assert(r==0);
r = toku_cachetable_close(&ct); assert(r==0);
toku_memory_check_all_free();
toku_memory_check_all_free();
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0);
r = toku_open_brt(n0, "db1", 0, &t0, 1<<12, ct, null_txn, toku_default_compare_fun, null_db); assert(r==0);
{
brt_lookup_and_check_nodup(t0, "good", "day");
}
r = toku_close_brt(t0, 0, 0); assert(r==0);
r = toku_cachetable_close(&ct); assert(r==0);
toku_memory_check_all_free();
}
int
test_main (int argc , const char *argv[]) {
default_parse_args(argc, argv);
test_named_db();
toku_malloc_cleanup();
if (verbose) printf("test_named_db ok\n");
return 0;
}
This diff is collapsed.
......@@ -19,7 +19,7 @@ static void test0 (void) {
assert(r==0);
if (verbose) printf("%s:%d test0\n", __FILE__, __LINE__);
unlink(fname);
r = toku_open_brt(fname, 0, 1, &t, 1024, ct, null_txn, toku_default_compare_fun, null_db);
r = toku_open_brt(fname, 1, &t, 1024, ct, null_txn, toku_default_compare_fun, null_db);
assert(r==0);
//printf("%s:%d test0\n", __FILE__, __LINE__);
//printf("%s:%d n_items_malloced=%lld\n", __FILE__, __LINE__, n_items_malloced);
......
......@@ -18,7 +18,7 @@ static void test1 (void) {
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
assert(r==0);
unlink(fname);
r = toku_open_brt(fname, 0, 1, &t, 1024, ct, null_txn, toku_default_compare_fun, null_db);
r = toku_open_brt(fname, 1, &t, 1024, ct, null_txn, toku_default_compare_fun, null_db);
assert(r==0);
toku_brt_insert(t, toku_fill_dbt(&k, "hello", 6), toku_fill_dbt(&v, "there", 6), null_txn);
{
......
......@@ -18,7 +18,7 @@ static void test2 (int memcheck, int limit) {
toku_memory_check_all_free();
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0);
unlink(fname);
r = toku_open_brt(fname, 0, 1, &t, 1024, ct, null_txn, toku_default_compare_fun, null_db);
r = toku_open_brt(fname, 1, &t, 1024, ct, null_txn, toku_default_compare_fun, null_db);
if (verbose) printf("%s:%d did setup\n", __FILE__, __LINE__);
assert(r==0);
for (i=0; i<limit; i++) { // 4096
......
......@@ -20,7 +20,7 @@ static void test3 (int nodesize, int count, int memcheck) {
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0);
gettimeofday(&t0, 0);
unlink(fname);
r = toku_open_brt(fname, 0, 1, &t, nodesize, ct, null_txn, toku_default_compare_fun, null_db);
r = toku_open_brt(fname, 1, &t, nodesize, ct, null_txn, toku_default_compare_fun, null_db);
assert(r==0);
for (i=0; i<count; i++) {
char key[100],val[100];
......
......@@ -20,7 +20,7 @@ static void test4 (int nodesize, int count, int memcheck) {
toku_memory_check=memcheck;
toku_memory_check_all_free();
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0);
r = toku_open_brt(fname, 0, 1, &t, nodesize, ct, null_txn, toku_default_compare_fun, null_db); assert(r==0);
r = toku_open_brt(fname, 1, &t, nodesize, ct, null_txn, toku_default_compare_fun, null_db); assert(r==0);
for (i=0; i<count; i++) {
char key[100],val[100];
int rv = random();
......
......@@ -20,7 +20,7 @@ static void test5 (void) {
for (i=0; i<limit; i++) values[i]=-1;
unlink(fname);
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0);
r = toku_open_brt(fname, 0, 1, &t, 1<<12, ct, null_txn, toku_default_compare_fun, null_db); assert(r==0);
r = toku_open_brt(fname, 1, &t, 1<<12, ct, null_txn, toku_default_compare_fun, null_db); assert(r==0);
for (i=0; i<limit/2; i++) {
char key[100],val[100];
int rk = random()%limit;
......
......@@ -5,7 +5,7 @@
#include <assert.h>
#include "test.h"
#include "cachetable.h"
#include "checkpoint.h"
static int N; // how many items in the table
static CACHEFILE cf;
......@@ -27,7 +27,7 @@ sleep_random (void)
int expect_value = 42; // initially 42, later 43
static void
flush (CACHEFILE UU(thiscf), CACHEKEY UU(key), void *value, void *UU(extraargs), long size, BOOL write_me, BOOL keep_me, LSN UU(modified_lsn), BOOL UU(rename_p), BOOL UU(for_checkpoint))
flush (CACHEFILE UU(thiscf), CACHEKEY UU(key), void *value, void *UU(extraargs), long size, BOOL write_me, BOOL keep_me, BOOL UU(for_checkpoint))
{
// printf("f");
assert(size == item_size);
......@@ -74,7 +74,8 @@ do_update (void *UU(ignore))
static void*
do_checkpoint (void *UU(v))
{
int r = toku_cachetable_checkpoint(ct, NULL);
// TODO: #1510 Replace with real checkpoint function
int r = toku_checkpoint(ct, NULL, NULL);
assert(r == 0);
return 0;
}
......@@ -85,7 +86,7 @@ do_checkpoint (void *UU(v))
// make sure that the stuff that was checkpointed includes only the old versions
// then do a flush and make sure the new items are written
static void cachetable_checkpoint_pending(void) {
static void checkpoint_pending(void) {
if (verbose) printf("%s:%d n=%d\n", __FUNCTION__, __LINE__, N);
const int test_limit = N;
int r;
......@@ -122,13 +123,17 @@ static void cachetable_checkpoint_pending(void) {
// after the checkpoint, all of the items should be 43
//printf("E43\n");
n_flush = n_write_me = n_keep_me = n_fetch = 0; expect_value = 43;
r = toku_cachetable_checkpoint(ct, NULL);
//TODO: #1510 Replace with real checkpoint call
r = toku_checkpoint(ct, NULL, NULL);
assert(r == 0);
assert(n_flush == N && n_write_me == N && n_keep_me == N);
// a subsequent checkpoint should cause no flushes, or writes since all of the items are clean
n_flush = n_write_me = n_keep_me = n_fetch = 0;
r = toku_cachetable_checkpoint(ct, NULL);
//TODO: #1510 Replace with real checkpoint call
r = toku_checkpoint(ct, NULL, NULL);
assert(r == 0);
assert(n_flush == 0 && n_write_me == 0 && n_keep_me == 0);
......@@ -155,7 +160,7 @@ test_main(int argc, const char *argv[]) {
for (N=1; N<=128; N*=2) {
int myvalues[N];
values = myvalues;
cachetable_checkpoint_pending();
checkpoint_pending();
//printf("\n");
}
return 0;
......
......@@ -3,14 +3,14 @@
#include <assert.h>
#include "test.h"
#include "cachetable.h"
#include "checkpoint.h"
static const int item_size = 1;
static int n_flush, n_write_me, n_keep_me, n_fetch;
static void flush(CACHEFILE cf, CACHEKEY key, void *value, void *extraargs, long size, BOOL write_me, BOOL keep_me, LSN modified_lsn, BOOL rename_p, BOOL UU(for_checkpoint)) {
cf = cf; key = key; value = value; extraargs = extraargs; modified_lsn = modified_lsn; rename_p = rename_p;
static void flush(CACHEFILE cf, CACHEKEY key, void *value, void *extraargs, long size, BOOL write_me, BOOL keep_me, BOOL UU(for_checkpoint)) {
cf = cf; key = key; value = value; extraargs = extraargs;
// assert(key == make_blocknum((long)value));
assert(size == item_size);
n_flush++;
......@@ -67,7 +67,8 @@ static void cachetable_checkpoint_test(int n, enum cachetable_dirty dirty) {
// the checkpoint should cause n writes, but since n <= the cachetable size,
// all items should be kept in the cachetable
n_flush = n_write_me = n_keep_me = n_fetch = 0;
r = toku_cachetable_checkpoint(ct, NULL);
r = toku_checkpoint(ct, NULL, NULL);
assert(r == 0);
assert(n_flush == n && n_write_me == n && n_keep_me == n);
......@@ -95,7 +96,9 @@ static void cachetable_checkpoint_test(int n, enum cachetable_dirty dirty) {
// a subsequent checkpoint should cause no flushes, or writes since all of the items are clean
n_flush = n_write_me = n_keep_me = n_fetch = 0;
r = toku_cachetable_checkpoint(ct, NULL);
r = toku_checkpoint(ct, NULL, NULL);
assert(r == 0);
assert(n_flush == 0 && n_write_me == 0 && n_keep_me == 0);
......
......@@ -9,8 +9,6 @@ flush (CACHEFILE f __attribute__((__unused__)),
long s __attribute__((__unused__)),
BOOL w __attribute__((__unused__)),
BOOL keep __attribute__((__unused__)),
LSN m __attribute__((__unused__)),
BOOL r __attribute__((__unused__)),
BOOL c __attribute__((__unused__))
) {
/* Do nothing */
......
......@@ -9,8 +9,6 @@ flush (CACHEFILE f __attribute__((__unused__)),
long s __attribute__((__unused__)),
BOOL w __attribute__((__unused__)),
BOOL keep __attribute__((__unused__)),
LSN m __attribute__((__unused__)),
BOOL r __attribute__((__unused__)),
BOOL c __attribute__((__unused__))
) {
/* Do nothing */
......
......@@ -9,8 +9,6 @@ flush (CACHEFILE f __attribute__((__unused__)),
long s __attribute__((__unused__)),
BOOL w __attribute__((__unused__)),
BOOL keep __attribute__((__unused__)),
LSN m __attribute__((__unused__)),
BOOL r __attribute__((__unused__)),
BOOL c __attribute__((__unused__))
) {
/* Do nothing */
......
......@@ -9,8 +9,6 @@ flush (CACHEFILE cf __attribute__((__unused__)),
long size __attribute__((__unused__)),
BOOL write_me __attribute__((__unused__)),
BOOL keep_me __attribute__((__unused__)),
LSN lsn __attribute__((__unused__)),
BOOL rename_p __attribute__((__unused__)),
BOOL for_checkpoint __attribute__((__unused__))
) {
assert((long) key.b == size);
......
......@@ -7,14 +7,14 @@
#include <assert.h>
#include "test.h"
#include "cachetable.h"
#include "checkpoint.h"
const int item_size = 1;
int n_flush, n_write_me, n_keep_me, n_fetch;
static void flush(CACHEFILE cf, CACHEKEY key, void *value, void *extraargs, long size, BOOL write_me, BOOL keep_me, LSN modified_lsn, BOOL rename_p, BOOL UU(for_checkpoint)) {
cf = cf; key = key; value = value; extraargs = extraargs; modified_lsn = modified_lsn; rename_p = rename_p;
static void flush(CACHEFILE cf, CACHEKEY key, void *value, void *extraargs, long size, BOOL write_me, BOOL keep_me, BOOL UU(for_checkpoint)) {
cf = cf; key = key; value = value; extraargs = extraargs;
// assert(key == make_blocknum((long)value));
assert(size == item_size);
n_flush++;
......@@ -78,7 +78,8 @@ static void cachetable_prefetch_checkpoint_test(int n, enum cachetable_dirty dir
// the checkpoint should cause n writes, but since n <= the cachetable size,
// all items should be kept in the cachetable
n_flush = n_write_me = n_keep_me = n_fetch = 0;
r = toku_cachetable_checkpoint(ct, NULL);
r = toku_checkpoint(ct, NULL, NULL);
assert(r == 0);
assert(n_flush == n && n_write_me == n && n_keep_me == n);
......@@ -106,7 +107,8 @@ static void cachetable_prefetch_checkpoint_test(int n, enum cachetable_dirty dir
// a subsequent checkpoint should cause no flushes, or writes since all of the items are clean
n_flush = n_write_me = n_keep_me = n_fetch = 0;
r = toku_cachetable_checkpoint(ct, NULL);
r = toku_checkpoint(ct, NULL, NULL);
assert(r == 0);
assert(n_flush == 0 && n_write_me == 0 && n_keep_me == 0);
......
......@@ -12,8 +12,6 @@ flush (CACHEFILE f __attribute__((__unused__)),
long s __attribute__((__unused__)),
BOOL w __attribute__((__unused__)),
BOOL keep __attribute__((__unused__)),
LSN m __attribute__((__unused__)),
BOOL r __attribute__((__unused__)),
BOOL c __attribute__((__unused__))
) {
assert(w == FALSE);
......
......@@ -12,8 +12,6 @@ flush (CACHEFILE f __attribute__((__unused__)),
long s __attribute__((__unused__)),
BOOL w __attribute__((__unused__)),
BOOL keep __attribute__((__unused__)),
LSN m __attribute__((__unused__)),
BOOL r __attribute__((__unused__)),
BOOL c __attribute__((__unused__))
) {
assert(w == FALSE && v != NULL);
......
......@@ -12,8 +12,6 @@ flush (CACHEFILE f __attribute__((__unused__)),
long s __attribute__((__unused__)),
BOOL w __attribute__((__unused__)),
BOOL keep __attribute__((__unused__)),
LSN m __attribute__((__unused__)),
BOOL r __attribute__((__unused__)),
BOOL c __attribute__((__unused__))
) {
assert(w == FALSE);
......
......@@ -12,8 +12,6 @@ flush (CACHEFILE f __attribute__((__unused__)),
long s __attribute__((__unused__)),
BOOL w __attribute__((__unused__)),
BOOL keep __attribute__((__unused__)),
LSN m __attribute__((__unused__)),
BOOL r __attribute__((__unused__)),
BOOL c __attribute__((__unused__))
) {
assert(w == FALSE);
......
......@@ -12,8 +12,6 @@ flush (CACHEFILE f __attribute__((__unused__)),
long s __attribute__((__unused__)),
BOOL w __attribute__((__unused__)),
BOOL keep __attribute__((__unused__)),
LSN m __attribute__((__unused__)),
BOOL r __attribute__((__unused__)),
BOOL c __attribute__((__unused__))
) {
assert(w == FALSE);
......
......@@ -12,8 +12,6 @@ flush (CACHEFILE f __attribute__((__unused__)),
long s __attribute__((__unused__)),
BOOL w __attribute__((__unused__)),
BOOL keep __attribute__((__unused__)),
LSN m __attribute__((__unused__)),
BOOL r __attribute__((__unused__)),
BOOL c __attribute__((__unused__))
) {
assert(w == FALSE);
......
......@@ -13,8 +13,6 @@ flush (CACHEFILE f __attribute__((__unused__)),
long s __attribute__((__unused__)),
BOOL w __attribute__((__unused__)),
BOOL keep __attribute__((__unused__)),
LSN m __attribute__((__unused__)),
BOOL r __attribute__((__unused__)),
BOOL c __attribute__((__unused__))
) {
assert(w == FALSE);
......
......@@ -9,8 +9,6 @@ flush (CACHEFILE f __attribute__((__unused__)),
long s __attribute__((__unused__)),
BOOL w __attribute__((__unused__)),
BOOL keep __attribute__((__unused__)),
LSN m __attribute__((__unused__)),
BOOL r __attribute__((__unused__)),
BOOL c __attribute__((__unused__))
) {
/* Do nothing */
......
......@@ -44,8 +44,6 @@ static void r_flush (CACHEFILE f __attribute__((__unused__)),
long size __attribute__((__unused__)),
BOOL write_me __attribute__((__unused__)),
BOOL keep_me,
LSN modified_lsn __attribute__((__unused__)),
BOOL rename_p __attribute__((__unused__)),
BOOL for_checkpoint __attribute__((__unused__))) {
int i;
//printf("Flush\n");
......
......@@ -7,66 +7,66 @@
static void
test_create_destroy (void) {
struct ctpair_rwlock the_rwlock, *rwlock = &the_rwlock;
struct rwlock the_rwlock, *rwlock = &the_rwlock;
ctpair_rwlock_init(rwlock);
ctpair_rwlock_destroy(rwlock);
rwlock_init(rwlock);
rwlock_destroy(rwlock);
}
// test read lock and unlock with no writers
static void
test_simple_read_lock (int n) {
struct ctpair_rwlock the_rwlock, *rwlock = &the_rwlock;
struct rwlock the_rwlock, *rwlock = &the_rwlock;
ctpair_rwlock_init(rwlock);
assert(ctpair_pinned(rwlock) == 0);
rwlock_init(rwlock);
assert(rwlock_readers(rwlock) == 0);
int i;
for (i=1; i<=n; i++) {
ctpair_read_lock(rwlock, 0);
assert(ctpair_pinned(rwlock) == i);
assert(ctpair_users(rwlock) == i);
rwlock_read_lock(rwlock, 0);
assert(rwlock_readers(rwlock) == i);
assert(rwlock_users(rwlock) == i);
}
for (i=n-1; i>=0; i--) {
ctpair_read_unlock(rwlock);
assert(ctpair_pinned(rwlock) == i);
assert(ctpair_users(rwlock) == i);
rwlock_read_unlock(rwlock);
assert(rwlock_readers(rwlock) == i);
assert(rwlock_users(rwlock) == i);
}
ctpair_rwlock_destroy(rwlock);
rwlock_destroy(rwlock);
}
// test write lock and unlock with no readers
static void
test_simple_write_lock (void) {
struct ctpair_rwlock the_rwlock, *rwlock = &the_rwlock;
ctpair_rwlock_init(rwlock);
assert(ctpair_users(rwlock) == 0);
ctpair_write_lock(rwlock, 0);
assert(ctpair_writers(rwlock) == 1);
assert(ctpair_users(rwlock) == 1);
ctpair_write_unlock(rwlock);
assert(ctpair_users(rwlock) == 0);
ctpair_rwlock_destroy(rwlock);
struct rwlock the_rwlock, *rwlock = &the_rwlock;
rwlock_init(rwlock);
assert(rwlock_users(rwlock) == 0);
rwlock_write_lock(rwlock, 0);
assert(rwlock_writers(rwlock) == 1);
assert(rwlock_users(rwlock) == 1);
rwlock_write_unlock(rwlock);
assert(rwlock_users(rwlock) == 0);
rwlock_destroy(rwlock);
}
struct rw_event {
int e;
struct ctpair_rwlock the_rwlock;
struct rwlock the_rwlock;
toku_pthread_mutex_t mutex;
};
static void
rw_event_init (struct rw_event *rwe) {
rwe->e = 0;
ctpair_rwlock_init(&rwe->the_rwlock);
rwlock_init(&rwe->the_rwlock);
int r = toku_pthread_mutex_init(&rwe->mutex, 0); assert(r == 0);
}
static void
rw_event_destroy (struct rw_event *rwe) {
ctpair_rwlock_destroy(&rwe->the_rwlock);
rwlock_destroy(&rwe->the_rwlock);
int r = toku_pthread_mutex_destroy(&rwe->mutex); assert(r == 0);
}
......@@ -76,13 +76,13 @@ test_writer_priority_thread (void *arg) {
int r;
r = toku_pthread_mutex_lock(&rwe->mutex); assert(r == 0);
ctpair_write_lock(&rwe->the_rwlock, &rwe->mutex);
rwlock_write_lock(&rwe->the_rwlock, &rwe->mutex);
rwe->e++; assert(rwe->e == 3);
r = toku_pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
sleep(1);
r = toku_pthread_mutex_lock(&rwe->mutex); assert(r == 0);
rwe->e++; assert(rwe->e == 4);
ctpair_write_unlock(&rwe->the_rwlock);
rwlock_write_unlock(&rwe->the_rwlock);
r = toku_pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
return arg;
......@@ -97,7 +97,7 @@ test_writer_priority (void) {
rw_event_init(rwe);
r = toku_pthread_mutex_lock(&rwe->mutex); assert(r == 0);
ctpair_read_lock(&rwe->the_rwlock, &rwe->mutex);
rwlock_read_lock(&rwe->the_rwlock, &rwe->mutex);
sleep(1);
rwe->e++; assert(rwe->e == 1);
r = toku_pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
......@@ -111,16 +111,16 @@ test_writer_priority (void) {
sleep(1);
r = toku_pthread_mutex_lock(&rwe->mutex); assert(r == 0);
ctpair_read_unlock(&rwe->the_rwlock);
rwlock_read_unlock(&rwe->the_rwlock);
r = toku_pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
sleep(1);
r = toku_pthread_mutex_lock(&rwe->mutex); assert(r == 0);
ctpair_read_lock(&rwe->the_rwlock, &rwe->mutex);
rwlock_read_lock(&rwe->the_rwlock, &rwe->mutex);
rwe->e++; assert(rwe->e == 5);
r = toku_pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
sleep(1);
r = toku_pthread_mutex_lock(&rwe->mutex); assert(r == 0);
ctpair_read_unlock(&rwe->the_rwlock);
rwlock_read_unlock(&rwe->the_rwlock);
r = toku_pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
void *ret;
......@@ -137,10 +137,10 @@ test_single_writer_thread (void *arg) {
int r;
r = toku_pthread_mutex_lock(&rwe->mutex); assert(r == 0);
ctpair_write_lock(&rwe->the_rwlock, &rwe->mutex);
rwlock_write_lock(&rwe->the_rwlock, &rwe->mutex);
rwe->e++; assert(rwe->e == 3);
assert(ctpair_writers(&rwe->the_rwlock) == 1);
ctpair_write_unlock(&rwe->the_rwlock);
assert(rwlock_writers(&rwe->the_rwlock) == 1);
rwlock_write_unlock(&rwe->the_rwlock);
r = toku_pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
return arg;
......@@ -152,10 +152,10 @@ test_single_writer (void) {
int r;
rw_event_init(rwe);
assert(ctpair_writers(&rwe->the_rwlock) == 0);
assert(rwlock_writers(&rwe->the_rwlock) == 0);
r = toku_pthread_mutex_lock(&rwe->mutex); assert(r == 0);
ctpair_write_lock(&rwe->the_rwlock, &rwe->mutex);
assert(ctpair_writers(&rwe->the_rwlock) == 1);
rwlock_write_lock(&rwe->the_rwlock, &rwe->mutex);
assert(rwlock_writers(&rwe->the_rwlock) == 1);
sleep(1);
rwe->e++; assert(rwe->e == 1);
r = toku_pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
......@@ -165,15 +165,15 @@ test_single_writer (void) {
sleep(1);
r = toku_pthread_mutex_lock(&rwe->mutex); assert(r == 0);
rwe->e++; assert(rwe->e == 2);
assert(ctpair_writers(&rwe->the_rwlock) == 1);
assert(ctpair_users(&rwe->the_rwlock) == 2);
ctpair_write_unlock(&rwe->the_rwlock);
assert(rwlock_writers(&rwe->the_rwlock) == 1);
assert(rwlock_users(&rwe->the_rwlock) == 2);
rwlock_write_unlock(&rwe->the_rwlock);
r = toku_pthread_mutex_unlock(&rwe->mutex); assert(r == 0);
void *ret;
r = toku_pthread_join(tid, &ret); assert(r == 0);
assert(ctpair_writers(&rwe->the_rwlock) == 0);
assert(rwlock_writers(&rwe->the_rwlock) == 0);
rw_event_destroy(rwe);
}
......
......@@ -18,8 +18,6 @@ static void f_flush (CACHEFILE f,
long size,
BOOL write_me,
BOOL keep_me,
LSN modified_lsn __attribute__((__unused__)),
BOOL rename_p __attribute__((__unused__)),
BOOL for_checkpoint __attribute__((__unused__))) {
assert(size==BLOCKSIZE);
if (write_me) {
......
......@@ -107,8 +107,6 @@ static void flush (CACHEFILE f,
long size __attribute__((__unused__)),
BOOL write_me __attribute__((__unused__)),
BOOL keep_me __attribute__((__unused__)),
LSN modified_lsn __attribute__((__unused__)),
BOOL rename_p __attribute__((__unused__)),
BOOL for_checkpoint __attribute__((__unused__))) {
struct item *it = value;
int i;
......@@ -304,7 +302,6 @@ static void flush_n (CACHEFILE f __attribute__((__unused__)), CACHEKEY key __att
void *extra __attribute__((__unused__)),
long size __attribute__((__unused__)),
BOOL write_me __attribute__((__unused__)), BOOL keep_me __attribute__((__unused__)),
LSN modified_lsn __attribute__((__unused__)), BOOL rename_p __attribute__ ((__unused__)),
BOOL for_checkpoint __attribute__ ((__unused__))) {
int *v = value;
assert(*v==0);
......@@ -369,8 +366,6 @@ static void null_flush (CACHEFILE cf __attribute__((__unused__)),
long size __attribute__((__unused__)),
BOOL write_me __attribute__((__unused__)),
BOOL keep_me __attribute__((__unused__)),
LSN modified_lsn __attribute__((__unused__)),
BOOL rename_p __attribute__((__unused__)),
BOOL for_checkpoint __attribute__((__unused__))) {
}
......@@ -445,8 +440,6 @@ static void test_dirty_flush(CACHEFILE f,
long size,
BOOL do_write,
BOOL keep,
LSN modified_lsn __attribute__((__unused__)),
BOOL rename_p __attribute__((__unused__)),
BOOL for_checkpoint __attribute__((__unused__))) {
if (verbose) printf("test_dirty_flush %p %" PRId64 " %p %ld %u %u\n", f, key.b, value, size, (unsigned)do_write, (unsigned)keep);
}
......@@ -571,8 +564,6 @@ static void test_size_flush_callback(CACHEFILE f,
long size,
BOOL do_write,
BOOL keep,
LSN modified_lsn __attribute__((__unused__)),
BOOL rename_p __attribute__((__unused__)),
BOOL for_checkpoint __attribute__((__unused__))) {
if (test_size_debug && verbose) printf("test_size_flush %p %" PRId64 " %p %ld %u %u\n", f, key.b, value, size, (unsigned)do_write, (unsigned)keep);
if (keep) {
......
......@@ -101,8 +101,6 @@ static void flush_forchain (CACHEFILE f __attribute__((__unused__)),
long size __attribute__((__unused__)),
BOOL write_me __attribute__((__unused__)),
BOOL keep_me __attribute__((__unused__)),
LSN modified_lsn __attribute__((__unused__)),
BOOL rename_p __attribute__((__unused__)),
BOOL for_checkpoint __attribute__((__unused__))) {
if (keep_me) return;
int *v = value;
......
......@@ -9,8 +9,6 @@ flush (CACHEFILE f __attribute__((__unused__)),
long s __attribute__((__unused__)),
BOOL w __attribute__((__unused__)),
BOOL keep __attribute__((__unused__)),
LSN m __attribute__((__unused__)),
BOOL r __attribute__((__unused__)),
BOOL c __attribute__((__unused__))
) {
/* Do nothing */
......
......@@ -21,7 +21,7 @@ static void test_flat (void) {
r = toku_brt_create(&t); assert(r==0);
r = toku_brt_set_flags(t, TOKU_DB_DUP + TOKU_DB_DUPSORT); assert(r == 0);
r = toku_brt_set_nodesize(t, 4096); assert(r == 0);
r = toku_brt_open(t, fname, fname, 0, 1, 1, ct, null_txn, (DB*)0);
r = toku_brt_open(t, fname, fname, 1, 1, ct, null_txn, (DB*)0);
u_int64_t i;
for (i=0; i<limit; i++) {
u_int64_t j;
......
......@@ -20,7 +20,7 @@ static void test_flat (void) {
r = toku_brt_create(&t); assert(r==0);
r = toku_brt_set_flags(t, TOKU_DB_DUP + TOKU_DB_DUPSORT); assert(r == 0);
r = toku_brt_set_nodesize(t, 4096); assert(r == 0);
r = toku_brt_open(t, fname, fname, 0, 1, 1, ct, null_txn, (DB*)0);
r = toku_brt_open(t, fname, fname, 1, 1, ct, null_txn, (DB*)0);
u_int64_t i;
for (i=0; i<limit; i++) {
u_int64_t j;
......
......@@ -18,7 +18,7 @@ static void test_flat (void) {
// set the cachetable to size 1 so that things won't fit.
int r = toku_brt_create_cachetable(&ct, 1, ZERO_LSN, NULL_LOGGER); assert(r==0);
BRT t;
r = toku_open_brt(fname, 0, 1, &t, 1<<12, ct, null_txn, toku_default_compare_fun, null_db); assert(r==0);
r = toku_open_brt(fname, 1, &t, 1<<12, ct, null_txn, toku_default_compare_fun, null_db); assert(r==0);
u_int64_t i;
// permute the numbers from 0 (inclusive) to limit (exclusive)
permute[0]=0;
......
......@@ -16,7 +16,7 @@ static void test_flat (void) {
CACHETABLE ct;
int r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0);
BRT t;
r = toku_open_brt(fname, 0, 1, &t, 1<<12, ct, null_txn, toku_default_compare_fun, null_db); assert(r==0);
r = toku_open_brt(fname, 1, &t, 1<<12, ct, null_txn, toku_default_compare_fun, null_db); assert(r==0);
u_int64_t i;
for (i=0; i<limit; i++) {
char key[100],val[100];
......
......@@ -21,7 +21,7 @@ test_main (int argc __attribute__((__unused__)), const char *argv[] __attribute
unlink(fname);
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0);
r = toku_open_brt(fname, 0, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db); assert(r==0);
r = toku_open_brt(fname, 1, &brt, 1<<12, ct, null_txn, test_brt_cursor_keycompare, db); assert(r==0);
r = toku_brt_cursor(brt, &cursor); assert(r==0);
int i;
......
......@@ -21,7 +21,7 @@ doit (void) {
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0);
unlink(fname);
r = toku_brt_create(&t); assert(r==0);
r = toku_brt_open(t, fname, fname, 0, 1, 1, ct, null_txn, (DB*)0); assert(r==0);
r = toku_brt_open(t, fname, fname, 1, 1, ct, null_txn, (DB*)0); assert(r==0);
r = toku_brt_insert(t, toku_fill_dbt(&k, "a", 2), toku_fill_dbt(&v, "x", 2), null_txn);
assert(r==0);
......
......@@ -19,7 +19,7 @@ test_overflow (void) {
int r;
unlink(fname);
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0);
r = toku_open_brt(fname, 0, 1, &t, nodesize, ct, null_txn, toku_default_compare_fun, null_db); assert(r==0);
r = toku_open_brt(fname, 1, &t, nodesize, ct, null_txn, toku_default_compare_fun, null_db); assert(r==0);
DBT k,v;
u_int32_t vsize = nodesize/8;
......
......@@ -28,7 +28,7 @@ doit (void) {
snprintf(fname, fnamelen, "%s.brt", __FILE__);
r = toku_brt_create_cachetable(&ct, 16*1024, ZERO_LSN, NULL_LOGGER); assert(r==0);
unlink(fname);
r = toku_open_brt(fname, 0, 1, &t, NODESIZE, ct, null_txn, toku_default_compare_fun, null_db);
r = toku_open_brt(fname, 1, &t, NODESIZE, ct, null_txn, toku_default_compare_fun, null_db);
assert(r==0);
toku_free(fname);
......
......@@ -57,7 +57,7 @@ doit (int ksize __attribute__((__unused__))) {
snprintf(fname, fnamelen, "%s.brt", __FILE__);
r = toku_brt_create_cachetable(&ct, 16*1024, ZERO_LSN, NULL_LOGGER); assert(r==0);
unlink(fname);
r = toku_open_brt(fname, 0, 1, &t, NODESIZE, ct, null_txn, toku_default_compare_fun, null_db);
r = toku_open_brt(fname, 1, &t, NODESIZE, ct, null_txn, toku_default_compare_fun, null_db);
assert(r==0);
toku_free(fname);
......
......@@ -86,9 +86,11 @@ default_parse_args (int argc, const char *argv[]) {
int test_main(int argc, const char *argv[]);
static void dummy(void) {}
int
main(int argc, const char *argv[]) {
toku_brt_init();
toku_brt_init(dummy, dummy);
int r = test_main(argc, argv);
toku_brt_destroy();
return r;
......
/* -*- mode: C; c-basic-offset: 4 -*- */
#ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved."
#include "includes.h"
#include "test.h"
static TOKUTXN const null_txn = 0;
static DB * const null_db = 0;
CACHETABLE ct;
#define FNAME __FILE__ ".brt"
static BRT
open_db(u_int32_t flags, char *subdb) {
BRT t;
int r;
r = toku_brt_create(&t); assert(r == 0);
r = toku_brt_set_flags(t, flags); assert(r == 0);
r = toku_brt_set_nodesize(t, 4096); assert(r == 0);
r = toku_brt_open(t, FNAME, FNAME, subdb, 1, 0, ct, null_txn, (DB*)0);
assert(r==0);
return t;
}
int
test_main (int argc , const char *argv[]) {
default_parse_args(argc, argv);
int r;
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0);
unlink(FNAME);
BRT one;
BRT two;
BRT three;
char *name1 = "dupsort";
char *name2 = "dup and dupsort";
char *name3 = "temp";
one = open_db(TOKU_DB_DUPSORT, name1);
two = open_db(TOKU_DB_DUP | TOKU_DB_DUPSORT, name2);
three = open_db(TOKU_DB_DUPSORT, name3);
r = toku_close_brt(one, 0, 0); assert(r==0);
r = toku_close_brt(two, 0, 0); assert(r==0);
r = toku_brt_remove_subdb(three, name1, 0);
assert(r==0);
two = open_db(TOKU_DB_DUP | TOKU_DB_DUPSORT, name2);
r = toku_close_brt(two, 0, 0); assert(r==0);
r = toku_close_brt(three, 0, 0); assert(r==0);
r = toku_cachetable_close(&ct); assert(r==0);
return 0;
}
......@@ -133,16 +133,7 @@ static inline void wbuf_LOGGEDBRTHEADER (struct wbuf *w, LOGGEDBRTHEADER h) {
wbuf_uint(w, h.nodesize);
wbuf_BLOCKNUM(w, h.free_blocks);
wbuf_BLOCKNUM(w, h.unused_blocks);
wbuf_int(w, h.n_named_roots);
if ((signed)h.n_named_roots==-1) {
wbuf_BLOCKNUM(w, h.u.one.root);
} else {
int i;
for (i=0; i<h.n_named_roots; i++) {
wbuf_BLOCKNUM(w, h.u.many.roots[i]);
wbuf_bytes (w, h.u.many.names[i], (u_int32_t)(1+strlen(h.u.many.names[i])));
}
}
wbuf_BLOCKNUM(w, h.root);
wbuf_BLOCKNUM(w, h.btt_size);
wbuf_DISKOFF(w, h.btt_diskoff);
{
......
......@@ -18,8 +18,7 @@ BOOL toku_db_id_equals(const toku_db_id* a, const toku_db_id* b) {
return (BOOL)
(a == b ||
(a->saved_hash == b->saved_hash &&
memcmp(&a->id, &b->id, sizeof(b->id))==0 &&
!strcmp(a->sub_database_name, b->sub_database_name)));
memcmp(&a->id, &b->id, sizeof(b->id))==0));
}
void toku_db_id_add_ref(toku_db_id* db_id) {
......@@ -30,7 +29,6 @@ void toku_db_id_add_ref(toku_db_id* db_id) {
static void toku_db_id_close(toku_db_id** pdb_id) {
toku_db_id* db_id = *pdb_id;
toku_free(db_id->sub_database_name);
toku_free(db_id);
*pdb_id = NULL;
}
......@@ -44,10 +42,8 @@ void toku_db_id_remove_ref(toku_db_id** pdb_id) {
toku_db_id_close(pdb_id);
}
int toku_db_id_create(toku_db_id** pdbid, int fd,
const char* sub_database_name) {
int toku_db_id_create(toku_db_id** pdbid, int fd) {
int r = ENOSYS;
assert(sub_database_name);
toku_db_id* db_id = NULL;
db_id = (toku_db_id *)toku_malloc(sizeof(*db_id));
......@@ -57,11 +53,7 @@ int toku_db_id_create(toku_db_id** pdbid, int fd,
r = toku_os_get_unique_file_id(fd, &db_id->id);
if (r!=0) goto cleanup;
db_id->sub_database_name = toku_strdup(sub_database_name);
if (!db_id->sub_database_name) { r = ENOMEM; goto cleanup; }
db_id->saved_hash = hash_key((unsigned char*)db_id->sub_database_name,
strlen(db_id->sub_database_name));
db_id->saved_hash = hash_key((unsigned char*)&db_id->id, sizeof(db_id->id));
db_id->ref_count = 1;
*pdbid = db_id;
......@@ -69,7 +61,6 @@ int toku_db_id_create(toku_db_id** pdbid, int fd,
cleanup:
if (r != 0) {
if (db_id != NULL) {
if (db_id->sub_database_name) { toku_free(db_id->sub_database_name); }
toku_free(db_id);
}
}
......
......@@ -11,14 +11,12 @@
typedef struct __toku_db_id {
struct fileid id;
char* sub_database_name;
u_int32_t saved_hash;
u_int32_t ref_count;
} toku_db_id;
/* db_id methods */
int toku_db_id_create(toku_db_id** pdbid, int fd,
const char* sub_database_name);
int toku_db_id_create(toku_db_id** pdbid, int fd);
BOOL toku_db_id_equals(const toku_db_id* a, const toku_db_id* b);
......
......@@ -41,21 +41,23 @@ static void close_ltm(void) {
}
static void run_test(BOOL dups) {
int fd = open(TESTDIR "/file.db", O_CREAT|O_RDWR, S_IRWXU);
int fd = open(TESTDIR "/file.db", O_CREAT|O_RDWR, S_IRWXU);
assert(fd>=0);
int fd2 = open(TESTDIR "/file2.db", O_CREAT|O_RDWR, S_IRWXU);
assert(fd>=0);
toku_db_id* db_id = NULL;
r = toku_db_id_create(&db_id, fd, "subdb");
r = toku_db_id_create(&db_id, fd);
CKERR(r);
assert(db_id);
toku_db_id* db_id2 = NULL;
r = toku_db_id_create(&db_id2, fd, "subdb2");
r = toku_db_id_create(&db_id2, fd2);
CKERR(r);
assert(db_id);
toku_db_id* db_id3 = NULL;
r = toku_db_id_create(&db_id3, fd, "subdb");
r = toku_db_id_create(&db_id3, fd);
CKERR(r);
assert(db_id);
......
......@@ -13,10 +13,9 @@ static u_int32_t lt_refs[100];
static toku_lock_tree* lts [100];
static toku_ltm* ltm = NULL;
static toku_db_id* db_ids[100];
static char subdb [100][5];
static u_int32_t max_locks = 10;
int nums[10000];
int fd;
int fd[100];
static void setup_ltm(void) {
assert(!ltm);
......@@ -115,15 +114,15 @@ static void run_test(BOOL dups) {
static void initial_setup(void) {
u_int32_t i;
fd = open(TESTDIR "/file.db", O_CREAT|O_RDWR, S_IRWXU);
ltm = NULL;
assert(sizeof(db_ids) / sizeof(db_ids[0]) == sizeof(lts) / sizeof(lts[0]));
assert(sizeof(subdb) / sizeof(subdb[0]) == sizeof(lts) / sizeof(lts[0]));
for (i = 0; i < sizeof(lts) / sizeof(lts[0]); i++) {
lts[i] = NULL;
sprintf(subdb[i], "%05x", i);
if (!db_ids[i]) toku_db_id_create(&db_ids[i], fd, subdb[i]);
char name[sizeof(TESTDIR) + 256];
sprintf(name, TESTDIR "/file%05x.db", i);
fd[i] = open(name, O_CREAT|O_RDWR, S_IRWXU);
if (!db_ids[i]) toku_db_id_create(&db_ids[i], fd[i]);
assert(db_ids[i]);
lt_refs[i] = 0;
}
......@@ -136,6 +135,7 @@ static void close_test(void) {
assert(db_ids[i]);
toku_db_id_remove_ref(&db_ids[i]);
assert(!db_ids[i]);
close(fd[i]);
}
}
......@@ -153,7 +153,6 @@ int main(int argc, const char *argv[]) {
run_test(TRUE);
close(fd);
close_test();
return 0;
}
......@@ -81,6 +81,8 @@ BDB_DONTRUN_TESTS = \
test_txn_close_open_commit \
test_txn_commit8 \
test_db_descriptor \
test_db_descriptor_named_db \
test_heaviside_straddle_1622 \
#\ ends prev line
ifeq ($(OS_CHOICE),windows)
......@@ -93,7 +95,6 @@ TDB_TESTS_THAT_SHOULD_FAIL= \
test_groupcommit_count \
test944 \
test_truncate_txn_abort \
test_truncate_subdb \
test_txn_nested_abort3 \
test_txn_nested_abort4 \
test_abort4 \
......
......@@ -29,8 +29,6 @@ test_cursor_current (void) {
const char * const fname = ENVDIR "/" "test.cursor.current.brt";
int r;
unlink(fname);
r = db_create(&db, null_env, 0); CKERR(r);
db->set_errfile(db,0); // Turn off those annoying errors
r = db->open(db, null_txn, fname, "main", DB_BTREE, DB_CREATE, 0666); CKERR(r);
......
......@@ -56,7 +56,9 @@ test_cursor_delete (int dup_mode) {
const char * const fname = ENVDIR "/" "test.cursor.delete.brt";
int r;
unlink(fname);
r = system("rm -rf " ENVDIR); assert(r == 0);
r = toku_os_mkdir(ENVDIR, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
/* create the dup database file */
r = db_create(&db, null_env, 0); assert(r == 0);
......@@ -106,7 +108,8 @@ test_cursor_delete_dupsort (void) {
const char * const fname = ENVDIR "/" "test.cursor.delete.brt";
int r;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
/* create the dup database file */
r = db_create(&db, null_env, 0); assert(r == 0);
......@@ -152,13 +155,8 @@ test_cursor_delete_dupsort (void) {
int
test_main(int argc, const char *argv[]) {
int r;
parse_args(argc, argv);
r = system("rm -rf " ENVDIR); assert(r == 0);
r = toku_os_mkdir(ENVDIR, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
test_cursor_delete(0);
#ifdef USE_BDB
test_cursor_delete(DB_DUP);
......
......@@ -22,8 +22,9 @@ test_cursor_flags (int cursor_flags, int expectr) {
const char * const fname = ENVDIR "/" "test.cursor.delete.brt";
int r;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO);
r = db_create(&db, null_env, 0); assert(r == 0);
db->set_errfile(db,0); // Turn off those annoying errors
r = db->open(db, null_txn, fname, "main", DB_BTREE, DB_CREATE, 0666); assert(r == 0);
......@@ -44,9 +45,6 @@ test_main(int argc, const char *argv[]) {
parse_args(argc, argv);
system("rm -rf " ENVDIR);
toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO);
test_cursor_flags(0, 0);
test_cursor_flags(~0, EINVAL);
......
......@@ -55,7 +55,8 @@ test_cursor_nonleaf_expand (int n, int reverse) {
const char * const fname = ENVDIR "/" "test.insert.brt";
int r;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r=toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); assert(r==0);
/* create the dup database file */
r = db_create(&db, null_env, 0); assert(r == 0);
......@@ -91,9 +92,6 @@ int
test_main(int argc, const char *argv[]) {
parse_args(argc, argv);
system("rm -rf " ENVDIR);
int r=toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); assert(r==0);
int i;
for (i=1; i<=65536; i *= 2) {
test_cursor_nonleaf_expand(i, 0);
......
......@@ -43,7 +43,8 @@ test_cursor_sticky (int n, int dup_mode) {
const char * const fname = ENVDIR "/" "test_cursor_sticky.brt";
int r;
unlink(fname);
r = system("rm -rf " ENVDIR); assert(r == 0);
r = toku_os_mkdir(ENVDIR, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
/* create the dup database file */
r = db_create(&db, null_env, 0); assert(r == 0);
......@@ -77,15 +78,11 @@ test_cursor_sticky (int n, int dup_mode) {
int
test_main(int argc, const char *argv[]) {
int r;
int i;
// setvbuf(stdout, NULL, _IONBF, 0);
parse_args(argc, argv);
r = system("rm -rf " ENVDIR); assert(r == 0);
r = toku_os_mkdir(ENVDIR, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
for (i=1; i<65537; i *= 2) {
test_cursor_sticky(i, 0);
}
......
......@@ -12,7 +12,7 @@
#include "test.h"
// ENVDIR is defined in the Makefile
#define FNAME "nonames.db"
#define FNAME "foo.tokudb"
char *name = NULL;
#define NUM 8
......@@ -25,9 +25,14 @@ DBT descriptors[NUM];
DB_ENV *env;
DB *db;
DB_TXN *null_txn = NULL;
DB_TXN *txn = NULL;
DB_TXN *null_txn;
int last_open_descriptor = -1;
int abort_type;
int get_table_lock;
u_int64_t num_called = 0;
int manual_truncate = 0;
static void
......@@ -47,6 +52,7 @@ verify_db_matches(void) {
static int
verify_int_cmp (DB *dbp, const DBT *a, const DBT *b) {
num_called++;
verify_db_matches();
int r = int_dbt_cmp(dbp, a, b);
return r;
......@@ -55,24 +61,66 @@ verify_int_cmp (DB *dbp, const DBT *a, const DBT *b) {
static void
open_db(int descriptor) {
/* create the dup database file */
assert(txn==NULL);
int r = db_create(&db, env, 0);
CKERR(r);
r = db->set_bt_compare(db, verify_int_cmp);
CKERR(r);
assert(abort_type >=0 && abort_type <= 2);
if (abort_type==2) {
r = env->txn_begin(env, null_txn, &txn, 0);
CKERR(r);
last_open_descriptor = -1; //DB was destroyed at end of last close, did not hang around.
}
if (descriptor >= 0) {
assert(descriptor < NUM);
r = db->set_descriptor(db, &descriptors[descriptor]);
CKERR(r);
last_open_descriptor = descriptor;
}
r = db->open(db, null_txn, FNAME, name, DB_BTREE, DB_CREATE, 0666);
r = db->open(db, txn, FNAME, name, DB_BTREE, DB_CREATE, 0666);
CKERR(r);
verify_db_matches();
if (abort_type!=2) {
r = env->txn_begin(env, null_txn, &txn, 0);
CKERR(r);
}
assert(txn);
if (get_table_lock) {
r = db->pre_acquire_table_lock(db, txn);
CKERR(r);
}
}
static void
delete_db(void) {
int r = db_create(&db, env, 0);
CKERR(r);
r = db->remove(db, FNAME, name, 0);
if (abort_type==2) {
CKERR2(r, ENOENT); //Abort deleted it
}
else CKERR(r);
}
static void
close_db(void) {
int r = db->close(db, 0);
int r;
if (manual_truncate) {
u_int32_t ignore_row_count;
r = db->truncate(db, txn, &ignore_row_count, 0);
CKERR(r);
}
if (abort_type>0) {
r = txn->abort(txn);
CKERR(r);
}
else {
r = txn->commit(txn, 0);
CKERR(r);
}
txn = NULL;
r = db->close(db, 0);
CKERR(r);
}
......@@ -93,6 +141,7 @@ setup_data(void) {
descriptors[i].data = &data[i][0];
}
last_open_descriptor = -1;
txn = NULL;
}
static void
......@@ -116,7 +165,9 @@ test_insert (int n) {
for (i=0; i<n; i++) {
int k = last++;
DBT key, val;
int r = db->put(db, null_txn, dbt_init(&key, &k, sizeof k), dbt_init(&val, &i, sizeof i), DB_YESOVERWRITE);
u_int64_t called = num_called;
int r = db->put(db, txn, dbt_init(&key, &k, sizeof k), dbt_init(&val, &i, sizeof i), DB_YESOVERWRITE);
if (i>0) assert(num_called > called);
CKERR(r);
}
}
......@@ -124,6 +175,11 @@ test_insert (int n) {
static void
runtest(void) {
system("rm -rf " ENVDIR);
int r=toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); assert(r==0);
setup_data();
permute_order();
int i;
for (i=0; i < NUM; i++) {
open_db(-1);
......@@ -134,27 +190,26 @@ runtest(void) {
test_insert(i);
close_db();
}
delete_db();
env->close(env, 0);
}
int
test_main(int argc, const char *argv[]) {
parse_args(argc, argv);
system("rm -rf " ENVDIR);
int r=toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); assert(r==0);
setup_data();
permute_order();
name = NULL;
runtest();
env->close(env, 0);
for (abort_type = 0; abort_type < 3; abort_type++) {
for (get_table_lock = 0; get_table_lock < 2; get_table_lock++) {
for (manual_truncate = 0; manual_truncate < 2; manual_truncate++) {
name = NULL;
runtest();
system("rm -rf " ENVDIR);
r=toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); assert(r==0);
setup_data();
permute_order();
name = "main.db";
runtest();
env->close(env, 0);
name = "bar";
runtest();
}
}
}
return 0;
}
......
/* -*- mode: C; c-basic-offset: 4 -*- */
#include <toku_portability.h>
#ident "Copyright (c) 2007 Tokutek Inc. All rights reserved."
#include <memory.h>
#include <toku_portability.h>
#include <db.h>
#include <assert.h>
#include <errno.h>
#include <sys/stat.h>
#include "test.h"
// ENVDIR is defined in the Makefile
#define FNAME "foo.tokudb"
char *name = NULL;
#define NUM 8
#define MAX_LENGTH (1<<16)
DB_ENV *env;
DB *db;
DB_TXN *null_txn;
static void
open_db(void) {
int r = db_create(&db, env, 0);
CKERR(r);
r = db->open(db, null_txn, FNAME, name, DB_BTREE, DB_CREATE, 0666);
CKERR(r);
}
static void
delete_db(void) {
int r = db_create(&db, env, 0);
CKERR(r);
r = db->remove(db, FNAME, name, 0);
}
static void
close_db(void) {
int r;
r = db->close(db, 0);
CKERR(r);
}
static void
setup_data(void) {
int r = db_env_create(&env, 0); CKERR(r);
const int envflags = DB_CREATE|DB_INIT_MPOOL|DB_INIT_TXN|DB_INIT_LOCK |DB_THREAD |DB_PRIVATE;
r = env->open(env, ENVDIR, envflags, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
}
static void
runtest(void) {
system("rm -rf " ENVDIR);
int r=toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); assert(r==0);
setup_data();
name = "foo";
open_db();
close_db();
delete_db();
name = "foo1";
open_db();
close_db();
name = "foo2";
open_db();
close_db();
name = "foo1";
delete_db();
name = "foo2";
delete_db();
name = "foo1";
open_db();
close_db();
name = "foo2";
open_db();
close_db();
name = "foo2";
delete_db();
name = "foo1";
delete_db();
env->close(env, 0);
}
int
test_main(int argc, const char *argv[]) {
parse_args(argc, argv);
runtest();
return 0;
}
......@@ -22,7 +22,8 @@ test_db_set_flags (int flags, int expectr, int flags2, int expectr2) {
const char * const fname = ENVDIR "/" "test.db.set.flags.brt";
int r;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO);
r = db_create(&db, null_env, 0); assert(r == 0);
db->set_errfile(db,0); // Turn off those annoying errors
......@@ -37,9 +38,6 @@ test_main(int argc, const char *argv[]) {
parse_args(argc, argv);
system("rm -rf " ENVDIR);
toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO);
test_db_set_flags(0, 0, 0, 0);
test_db_set_flags(0, 0, DB_DUP, EINVAL);
test_db_set_flags(DB_DUP+DB_DUPSORT, 0, DB_DUP+DB_DUPSORT, EINVAL);
......
......@@ -49,7 +49,8 @@ test_dup_delete (int n, int dup_mode) {
const char * const fname = ENVDIR "/" "test_dup_delete.brt";
int r;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0);
......@@ -144,8 +145,6 @@ test_dup_delete_delete (int n) {
const char * const fname = ENVDIR "/" "test_dup_delete_delete.brt";
int r;
unlink(fname);
/* create the dup database file */
r = db_create(&db, null_env, 0);
assert(r == 0);
......@@ -225,8 +224,6 @@ test_dup_delete_insert (int n, int dup_mode) {
const char * const fname = ENVDIR "/" "test_dup_delete_insert.brt";
int r;
unlink(fname);
/* create the dup database file */
r = db_create(&db, null_env, 0);
assert(r == 0);
......@@ -332,8 +329,6 @@ test_all_dup_delete_insert (int n) {
const char * const fname = ENVDIR "/" "test_all_dup_delete_insert.brt";
int r;
unlink(fname);
/* create the dup database file */
r = db_create(&db, null_env, 0);
assert(r == 0);
......@@ -408,8 +403,6 @@ test_walk_empty (int n, int dup_mode) {
const char * const fname = ENVDIR "/" "test_walk_empty.brt";
int r;
unlink(fname);
/* create the dup database file */
r = db_create(&db, null_env, 0);
assert(r == 0);
......@@ -482,8 +475,6 @@ test_icdi_search (int n, int dup_mode) {
const char * const fname = ENVDIR "/" "test_icdi_search.brt";
int r;
unlink(fname);
/* create the dup database file */
r = db_create(&db, null_env, 0);
assert(r == 0);
......@@ -573,8 +564,6 @@ test_ici_search (int n, int dup_mode) {
const char * const fname = ENVDIR "/" "test_ici_search.brt";
int r;
unlink(fname);
/* create the dup database file */
r = db_create(&db, null_env, 0);
assert(r == 0);
......@@ -670,8 +659,6 @@ test_i0i1ci0_search (int n, int dup_mode) {
const char * const fname = ENVDIR "/" "test_i0i1ci0.brt";
int r;
unlink(fname);
/* create the dup database file */
r = db_create(&db, null_env, 0);
assert(r == 0);
......@@ -719,15 +706,15 @@ test_i0i1ci0_search (int n, int dup_mode) {
int
test_main(int argc, const char *argv[]) {
int i;
int r;
parse_args(argc, argv);
system("rm -rf " ENVDIR);
toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO);
#ifdef USE_BDB
/* dup tests */
for (i = 1; i <= (1<<16); i *= 2) {
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
test_dup_delete(i, DB_DUP);
test_dup_delete_insert(i, DB_DUP);
test_all_dup_delete_insert(i);
......@@ -737,6 +724,8 @@ test_main(int argc, const char *argv[]) {
/* dupsort tests */
for (i = 1; i <= (1<<16); i *= 2) {
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
test_dup_delete(i, DB_DUP + DB_DUPSORT);
test_dup_delete_insert(i, DB_DUP + DB_DUPSORT);
test_walk_empty(i, DB_DUP + DB_DUPSORT);
......
......@@ -65,7 +65,8 @@ test_dup_key (int dup_mode, u_int32_t put_flags, int rexpect, int rexpectdupdup)
const char * const fname = ENVDIR "/" "test_insert.brt";
int r;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0); assert(r == 0);
......@@ -117,7 +118,8 @@ test_dup_dup (int dup_mode, u_int32_t put_flags, int rexpect, int rexpectdupdup)
const char * const fname = ENVDIR "/" "test_insert.brt";
int r;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0); assert(r == 0);
......@@ -169,7 +171,8 @@ test_put_00_01_01 (int dup_mode, u_int32_t put_flags) {
const char * const fname = ENVDIR "/" "test_insert.brt";
int r, expectr;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0); assert(r == 0);
......
......@@ -22,7 +22,8 @@ test_dup_flags (u_int32_t dup_flags) {
const char * const fname = ENVDIR "/" "test_dup_flags.brt";
int r;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0); assert(r == 0);
......
......@@ -54,7 +54,8 @@ test_insert (int n, int dup_mode) {
int r;
int i;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0);
......@@ -151,7 +152,8 @@ test_nonleaf_insert (int n, int dup_mode) {
int r;
int i;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0);
......
......@@ -69,7 +69,8 @@ test_dup_next (int n, int dup_mode) {
const char * const fname = ENVDIR "/" "test_dup_next.brt";
int r;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0); assert(r == 0);
......
......@@ -72,7 +72,8 @@ test_icdi_search (int n, int dup_mode) {
const char * const fname = ENVDIR "/" "test_icdi_search.brt";
int r;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0);
......@@ -143,7 +144,8 @@ test_ici_search (int n, int dup_mode) {
const char * const fname = ENVDIR "/" "test_ici_search.brt";
int r;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0);
......@@ -212,8 +214,6 @@ test_i0i1ci0_search (int n, int dup_mode) {
const char * const fname = ENVDIR "/" "test_i0i1ci0.brt";
int r;
unlink(fname);
/* create the dup database file */
r = db_create(&db, null_env, 0);
assert(r == 0);
......@@ -269,7 +269,8 @@ test_reverse_search (int n, int dup_mode) {
const char * const fname = ENVDIR "/" "test_reverse_search.brt";
int r;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0);
......@@ -332,11 +333,14 @@ test_main(int argc, const char *argv[]) {
if (verbose > 1)
limit = 1<<16;
int r;
/* dup search */
if (IS_TDB) {
if (verbose) printf("%s:%d:WARNING:tokudb does not support DB_DUP\n", __FILE__, __LINE__);
} else {
for (i = 1; i <= limit; i *= 2) {
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
test_ici_search(i, DB_DUP);
test_icdi_search(i, DB_DUP);
test_i0i1ci0_search(i, DB_DUP);
......@@ -345,6 +349,8 @@ test_main(int argc, const char *argv[]) {
/* dupsort search */
for (i = 1; i <= limit; i *= 2) {
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
test_ici_search(i, DB_DUP + DB_DUPSORT);
test_icdi_search(i, DB_DUP + DB_DUPSORT);
test_i0i1ci0_search(i, DB_DUP + DB_DUPSORT);
......
......@@ -49,7 +49,8 @@ test_dupsort_delete (int n) {
int r;
int i;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0); assert(r == 0);
......
......@@ -72,7 +72,8 @@ test_dupsort_get (int n, int dup_mode) {
const char * const fname = ENVDIR "/" "test.dupsort.get.brt";
int r;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0); assert(r == 0);
......
......@@ -89,7 +89,8 @@ test_icdi_search (int n, int dup_mode) {
const char * const fname = ENVDIR "/" "test_icdi_search.brt";
int r;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0); assert(r == 0);
......
......@@ -89,7 +89,8 @@ test_icdi_search (int n, int dup_mode) {
const char * const fname = ENVDIR "/" "test_icdi_search.brt";
int r;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0); assert(r == 0);
......
......@@ -90,7 +90,8 @@ test_icdi_search (int n, int dup_mode) {
const char * const fname = ENVDIR "/" "test_icdi_search.brt";
int r;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0); assert(r == 0);
......
......@@ -89,15 +89,17 @@ expect_cursor_get_current (DBC *cursor, int k, int v) {
/* insert, close, delete, insert, search */
static void
test_icdi_search (int n, int dup_mode) {
int r;
if (verbose) printf("test_icdi_search:%d %d\n", n, dup_mode);
DB_ENV * const null_env = 0;
DB *db;
DB_TXN * const null_txn = 0;
const char * const fname = ENVDIR "/" "test_icdi_search.brt";
int r;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0); assert(r == 0);
......@@ -156,9 +158,6 @@ test_main(int argc, const char *argv[]) {
parse_args(argc, argv);
system("rm -rf " ENVDIR);
toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO);
int limit = 1<<13;
if (verbose > 1)
limit = 1<<16;
......
......@@ -40,6 +40,13 @@ static void test_get_both(int n, int dup_mode, int op) {
snprintf(fname, sizeof(fname), "%s/test_icdi_search_brt", annotated_envdir);
int r;
{
char rmcmd[sizeof(annotated_envdir)+10];
snprintf(rmcmd, sizeof(rmcmd), "rm -rf %s", annotated_envdir);
system(rmcmd);
}
toku_os_mkdir(annotated_envdir, S_IRWXU+S_IRWXG+S_IRWXO);
unlink(fname);
/* create the dup database file */
......
......@@ -13,15 +13,17 @@
static void
test_insert_delete_insert (int dup_mode) {
int r;
r = system("rm -rf " ENVDIR);
CKERR(r);
toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO);
if (verbose) printf("test_insert_delete_insert:%d\n", dup_mode);
DB_ENV * const null_env = 0;
DB *db;
DB_TXN * const null_txn = 0;
const char * const fname = ENVDIR "/" "test.cursor.insert.delete.insert.brt";
int r;
unlink(fname);
/* create the dup database file */
r = db_create(&db, null_env, 0); assert(r == 0);
......@@ -67,9 +69,6 @@ test_main(int argc, const char *argv[]) {
parse_args(argc, argv);
system("rm -rf " ENVDIR);
toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO);
test_insert_delete_insert(0);
test_insert_delete_insert(DB_DUP + DB_DUPSORT);
......
......@@ -92,7 +92,8 @@ test_icdi_search (int n, int dup_mode) {
const char * const fname = ENVDIR "/" "test_icdi_search.brt";
int r;
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0); assert(r == 0);
......
......@@ -47,7 +47,8 @@ test_cursor_nonleaf_expand (int n, int reverse) {
const char * const fname = ENVDIR "/" "test.insert.brt";
int r;
// unlink(fname);
// r = system("rm -rf " ENVDIR); CKERR(r);
// r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0); assert(r == 0);
......
......@@ -51,7 +51,8 @@ test_insert_zero_length (int n, int dup_mode, const char *dbname) {
char fname[strlen(ENVDIR) + strlen("/") + strlen(dbname) + 1];
sprintf(fname, "%s/%s", ENVDIR, dbname);
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0); assert(r == 0);
......@@ -108,7 +109,8 @@ test_insert_zero_length_keys (int n, int dup_mode, const char *dbname) {
char fname[strlen(ENVDIR) + strlen("/") + strlen(dbname) + 1];
sprintf(fname, "%s/%s", ENVDIR, dbname);
unlink(fname);
r = system("rm -rf " ENVDIR); CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
/* create the dup database file */
r = db_create(&db, null_env, 0); assert(r == 0);
......@@ -143,9 +145,6 @@ test_main(int argc, const char *argv[]) {
unlink(TFILE);
SET_TRACE_FILE(TFILE);
system("rm -rf " ENVDIR);
toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO);
test_insert_zero_length(32, 0, "test0");
test_insert_zero_length_keys(32, 0, "test0keys");
test_insert_zero_length_keys(32, DB_DUP+DB_DUPSORT, "test0keys_dupsort");
......
......@@ -27,7 +27,6 @@ struct __toku_db_internal {
int database_number; // -1 if it is the single unnamed database. Nonnengative number otherwise.
char *fname;
char *full_fname;
char *database_name;
//int fd;
u_int32_t open_flags;
int open_mode;
......
This diff is collapsed.
......@@ -25,6 +25,7 @@ enum typ_tag { TYP_BRTNODE = 0xdead0001,
/* Everything should call toku_malloc() instead of malloc(), and toku_calloc() instead of calloc() */
void *toku_calloc(size_t nmemb, size_t size) __attribute__((__visibility__("default")));
void *toku_xcalloc(size_t nmemb, size_t size) __attribute__((__visibility__("default")));
void *toku_malloc(size_t size) __attribute__((__visibility__("default")));
// xmalloc aborts instead of return NULL if we run out of memory
......@@ -54,17 +55,25 @@ void *toku_realloc(void *, size_t size) __attribute__((__visibility__("default"
* and you cannot go wrong.
*/
#define MALLOC(v) v = toku_malloc(sizeof(*v))
/* MALLOC_N is like calloc: It makes an array. Write
/* MALLOC_N is like calloc(Except no 0ing of data): It makes an array. Write
* int *MALLOC_N(5,x);
* to make an array of 5 integers.
*/
#define MALLOC_N(n,v) v = toku_malloc((n)*sizeof(*v))
//CALLOC_N is like calloc with auto-figuring out size of members
#define CALLOC_N(n,v) v = toku_calloc((n), sizeof(*v))
#define CALLOC(v) CALLOC_N(1,v)
#define REALLOC_N(n,v) v = toku_realloc(v, (n)*sizeof(*v))
// XMALLOC macros are like MALLOC except they abort if the operation fails
#define XMALLOC(v) v = toku_xmalloc(sizeof(*v))
#define XMALLOC_N(n,v) v = toku_xmalloc((n)*sizeof(*v))
#define XCALLOC_N(n,v) v = toku_xcalloc((n), (sizeof(*v)))
#define XCALLOC(v) XCALLOC_N(1,(v))
#define XREALLOC_N(n,v) v = toku_xrealloc(v, (n)*sizeof(*v))
/* If you have a type such as
......
......@@ -63,6 +63,13 @@ int toku_os_initialize_settings(int verbosity) __attribute__((__visibility__("d
//
int toku_os_is_absolute_name(const char* path) __attribute__((__visibility__("default")));
#if defined(TOKU_WINDOWS) && TOKU_WINDOWS
#include <sys/types.h>
#include <sys/stat.h>
//Test if st_mode (from stat) is a directory
#define S_ISDIR(bitvector) (((bitvector)&_S_IFDIR)!=0)
#endif
// Portable linux 'stat'
int toku_stat(const char *name, toku_struct_stat *statbuf) __attribute__((__visibility__("default")));
// Portable linux 'fstat'
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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