Commit fc02addc authored by Yoni Fogel's avatar Yoni Fogel

[t:2249] Merge #2249 to main.

'load' entry and rollback/recovery,
single filename for brtloader and rest of brt
test-fsync

git-svn-id: file:///svn/toku/tokudb@18617 c7de825b-a66e-492c-adef-691d508d4ae1
parent a382d783
......@@ -9,7 +9,7 @@ ifneq ($(GCOV),)
CFLAGS += -fprofile-arcs -ftest-coverage -DGCOV
endif
LDFLAGS = ../libtokuportability.a -lpthread
SRCS = $(wildcard *.c)
SRCS=$(sort $(filter-out dir.%.c,$(wildcard *.c)))
TARGETS = $(patsubst %.c,%,$(SRCS))
RUNTARGETS = $(patsubst %,%.tdbrun,$(TARGETS))
VGRIND = valgrind
......
../../windows/tests/test-fsync.c
\ No newline at end of file
......@@ -349,7 +349,7 @@ int toku_brtheader_end_checkpoint (CACHEFILE cachefile, int fd, void *header_v);
int toku_maybe_upgrade_brt(BRT t);
int toku_db_badformat(void);
int toku_brt_remove_on_commit(TOKUTXN child, DBT* iname_dbt_p, DBT* iname_within_cwd_dbt_p);
int toku_brt_remove_now(CACHETABLE ct, DBT* iname_dbt_p, DBT* iname_within_cwd_dbt_p);
int toku_brt_remove_on_commit(TOKUTXN child, DBT* iname_dbt_p);
int toku_brt_remove_now(CACHETABLE ct, DBT* iname_dbt_p);
#endif
This diff is collapsed.
......@@ -30,7 +30,7 @@ typedef int(*BRT_GET_STRADDLE_CALLBACK_FUNCTION)(ITEMLEN, bytevec, ITEMLEN, byte
int toku_open_brt (const char *fname, int is_create, BRT *, int nodesize, CACHETABLE, TOKUTXN, int(*)(DB*,const DBT*,const DBT*), DB*);
int toku_dictionary_redirect (const char *dst_fname_in_env, const char *dst_fname_in_cwd, BRT old_brt, TOKUTXN txn);
int toku_dictionary_redirect (const char *dst_fname_in_env, BRT old_brt, TOKUTXN txn);
// See the brt.c file for what this toku_redirect_brt does
int toku_dictionary_redirect_abort(struct brt_header *old_h, struct brt_header *new_h, TOKUTXN txn);
......@@ -49,9 +49,9 @@ int toku_brt_set_dup_compare(BRT, brt_compare_func);
brt_compare_func toku_brt_get_bt_compare (BRT brt);
int brt_set_cachetable(BRT, CACHETABLE);
int toku_brt_open(BRT, const char *fname_in_env, const char *fname_in_cwd,
int toku_brt_open(BRT, const char *fname_in_env,
int is_create, int only_create, CACHETABLE ct, TOKUTXN txn, DB *db);
int toku_brt_open_recovery(BRT, const char *fname_in_env, const char *fname_in_cwd,
int toku_brt_open_recovery(BRT, const char *fname_in_env,
int is_create, int only_create, CACHETABLE ct, TOKUTXN txn, DB *db, int recovery_force_fcreate, FILENUM use_filenum);
int toku_brt_remove_subdb(BRT brt, const char *dbname, u_int32_t flags);
......@@ -66,6 +66,8 @@ int toku_brt_insert (BRT brt, DBT *k, DBT *v, TOKUTXN txn);
// Effect: Insert a key and data pair into a brt if the oplsn is newer than the brt lsn. This function is called during recovery.
// Returns 0 if successful
int toku_brt_maybe_insert (BRT brt, DBT *k, DBT *v, TOKUTXN txn, BOOL oplsn_valid, LSN oplsn, int do_logging, enum brt_msg_type type);
int toku_brt_load_recovery(TOKUTXN txn, char const * old_iname, char const * new_iname, int do_fsync, int do_log);
int toku_brt_load(BRT brt, TOKUTXN txn, char const * new_iname, int do_fsync);
int toku_brt_log_put_multiple (TOKUTXN txn, BRT src_brt, BRT *brts, int num_brts, const DBT *key, const DBT *val);
int toku_brt_log_del_multiple (TOKUTXN txn, BRT src_brt, BRT *brts, int num_brts, const DBT *key, const DBT *val);
......
......@@ -306,7 +306,7 @@ main (int argc, const char *const argv[]) {
assert(r == 0);
CACHEFILE cf;
FILENUM fn={0};
r = toku_cachetable_openfd_with_filenum (&cf, ct, f, n, n, FALSE, fn, FALSE);
r = toku_cachetable_openfd_with_filenum (&cf, ct, f, n, FALSE, fn, FALSE);
assert(r==0);
dump_header(f, &h, cf);
if (interactive) {
......
......@@ -18,13 +18,12 @@ struct brtloader_s {
DB **dbs;
const struct descriptor **descriptors; // N of these
const char **new_fnames_in_env; // the file names that the final data will be written to (relative to env).
const char **new_fnames_in_cwd; // the file names that the final data will be written to (relative to cwd).
const char *temp_file_template;
FILE *fprimary_rows; char *fprimary_rows_name;
FILE *fprimary_idx; char *fprimary_idx_name;
u_int64_t fprimary_offset;
CACHETABLE cachetable;
};
/* These data structures are used for manipulating a collection of rows in main memory. */
......
......@@ -32,12 +32,12 @@ int brtloader_open_temp_file (BRTLOADER bl, FILE **filep, char **fnamep)
}
int toku_brt_loader_open (/* out */ BRTLOADER *blp,
CACHETABLE cachetable,
generate_row_for_put_func g,
DB *src_db,
int N, DB*dbs[/*N*/],
const struct descriptor *descriptors[/*N*/],
const char *new_fnames_in_env[/*N*/],
const char *new_fnames_in_cwd[/*N*/],
brt_compare_func bt_compare_functions[/*N*/],
const char *temp_file_template)
/* Effect: called by DB_ENV->create_loader to create a brt loader.
......@@ -57,6 +57,7 @@ int toku_brt_loader_open (/* out */ BRTLOADER *blp,
bl->panic_errno = 0;
bl->generate_row_for_put = g;
bl->cachetable = cachetable;
bl->src_db = src_db;
bl->N = N;
......@@ -66,8 +67,6 @@ int toku_brt_loader_open (/* out */ BRTLOADER *blp,
for (int i=0; i<N; i++) bl->descriptors[i]=descriptors[i];
MALLOC_N(N, bl->new_fnames_in_env);
for (int i=0; i<N; i++) bl->new_fnames_in_env[i] = toku_strdup(new_fnames_in_env[i]);
MALLOC_N(N, bl->new_fnames_in_cwd);
for (int i=0; i<N; i++) bl->new_fnames_in_cwd[i] = toku_strdup(new_fnames_in_cwd[i]);
MALLOC_N(N, bl->bt_compare_funs);
for (int i=0; i<N; i++) bl->bt_compare_funs[i] = bt_compare_functions[i];
......@@ -595,17 +594,17 @@ int toku_brt_loader_close (BRTLOADER bl)
* Return all the file descriptors in the array fds. */
{
for (int i=0; i<bl->N; i++) {
int r = loader_do_i(bl, bl->dbs[i], bl->bt_compare_funs[i], bl->descriptors[i], bl->new_fnames_in_cwd[i]);
char * fname_in_cwd = toku_cachetable_get_fname_in_cwd(bl->cachetable, bl->new_fnames_in_env[i]);
int r = loader_do_i(bl, bl->dbs[i], bl->bt_compare_funs[i], bl->descriptors[i], fname_in_cwd);
toku_free(fname_in_cwd);
if (r!=0) return r;
toku_free((void*)bl->new_fnames_in_env[i]);
toku_free((void*)bl->new_fnames_in_cwd[i]);
bl->new_fnames_in_env[i] = NULL;
bl->new_fnames_in_cwd[i] = NULL;
}
toku_free(bl->dbs);
toku_free(bl->descriptors);
toku_free(bl->new_fnames_in_env);
toku_free(bl->new_fnames_in_cwd);
toku_free(bl->bt_compare_funs);
toku_free((void*)bl->temp_file_template);
{ int r = fclose(bl->fprimary_rows); assert (r==0); }
......
......@@ -6,13 +6,13 @@
typedef struct brtloader_s *BRTLOADER;
int toku_brt_loader_open (BRTLOADER *bl,
CACHETABLE cachetable,
generate_row_for_put_func g,
DB *src_db,
int N,
DB *dbs[/*N*/],
const struct descriptor *descriptors[/*N*/],
const char * new_fnames_in_env[/*N*/],
const char * new_fnames_in_cwd[/*N*/],
brt_compare_func bt_compare_functions[/*N*/],
const char *temp_file_template);
int toku_brt_loader_put (BRTLOADER bl, DBT *key, DBT *val);
......
......@@ -4,11 +4,12 @@
#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."
#include <toku_portability.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdarg.h>
#include <toku_portability.h>
#include "memory.h"
#include "workqueue.h"
#include "threadpool.h"
......@@ -160,6 +161,8 @@ struct cachetable {
toku_pthread_mutex_t openfd_mutex; // make toku_cachetable_openfd() single-threaded
LEAFLOCK_POOL leaflock_pool;
OMT reserved_filenums;
char *env_dir;
BOOL set_env_dir; //Can only set env_dir once
};
......@@ -218,7 +221,6 @@ struct cachefile {
struct fileid fileid;
FILENUM filenum;
char *fname_in_env; /* Used for logging */
char *fname_in_cwd; /* Used for logging, redirect */
void *userdata;
int (*log_fassociate_during_checkpoint)(CACHEFILE cf, void *userdata); // When starting a checkpoint we must log all open files.
......@@ -273,10 +275,19 @@ int toku_create_cachetable(CACHETABLE *result, long size_limit, LSN UU(initial_l
toku_minicron_setup(&ct->checkpointer, 0, checkpoint_thread, ct); // default is no checkpointing
r = toku_leaflock_create(&ct->leaflock_pool); assert(r==0);
r = toku_omt_create(&ct->reserved_filenums); assert(r==0);
ct->env_dir = toku_xstrdup(".");
*result = ct;
return 0;
}
void
toku_cachetable_set_env_dir(CACHETABLE ct, char *env_dir) {
assert(!ct->set_env_dir);
toku_free(ct->env_dir);
ct->env_dir = toku_xstrdup(env_dir);
ct->set_env_dir = TRUE;
}
//
// Increment the reference count
// MUST HOLD cachetable lock
......@@ -343,16 +354,15 @@ int toku_cachefile_of_filenum (CACHETABLE ct, FILENUM filenum, CACHEFILE *cf) {
static FILENUM next_filenum_to_use={0};
static void cachefile_init_filenum(CACHEFILE cf, int fd, const char *fname_in_env, const char *fname_in_cwd, struct fileid fileid) {
static void cachefile_init_filenum(CACHEFILE cf, int fd, const char *fname_in_env, struct fileid fileid) {
cf->fd = fd;
cf->fileid = fileid;
cf->fname_in_env = toku_xstrdup(fname_in_env);
cf->fname_in_cwd = toku_xstrdup(fname_in_cwd);
}
// If something goes wrong, close the fd. After this, the caller shouldn't close the fd, but instead should close the cachefile.
int toku_cachetable_openfd (CACHEFILE *cfptr, CACHETABLE ct, int fd, const char *fname_in_env, const char *fname_in_cwd) {
return toku_cachetable_openfd_with_filenum(cfptr, ct, fd, fname_in_env, fname_in_cwd, FALSE, next_filenum_to_use, FALSE);
int toku_cachetable_openfd (CACHEFILE *cfptr, CACHETABLE ct, int fd, const char *fname_in_env) {
return toku_cachetable_openfd_with_filenum(cfptr, ct, fd, fname_in_env, FALSE, next_filenum_to_use, FALSE);
}
static int
......@@ -474,7 +484,7 @@ toku_cachetable_unreserve_filenum (CACHETABLE ct, FILENUM reserved_filenum) {
}
int toku_cachetable_openfd_with_filenum (CACHEFILE *cfptr, CACHETABLE ct, int fd,
const char *fname_in_env, const char *fname_in_cwd,
const char *fname_in_env,
BOOL with_filenum, FILENUM filenum, BOOL reserved) {
int r;
CACHEFILE extant;
......@@ -551,7 +561,7 @@ int toku_cachetable_openfd_with_filenum (CACHEFILE *cfptr, CACHETABLE ct, int fd
CACHEFILE XCALLOC(newcf);
newcf->cachetable = ct;
newcf->filenum.fileid = with_filenum ? filenum.fileid : next_filenum_to_use.fileid++;
cachefile_init_filenum(newcf, fd, fname_in_env, fname_in_cwd, fileid);
cachefile_init_filenum(newcf, fd, fname_in_env, fileid);
newcf->refcount = 1;
newcf->next = ct->cachefiles;
ct->cachefiles = newcf;
......@@ -576,7 +586,7 @@ static int cachetable_flush_cachefile (CACHETABLE, CACHEFILE cf);
static void assert_cachefile_is_flushed_and_removed (CACHETABLE ct, CACHEFILE cf);
// Do not use this function to redirect to /dev/null.
int toku_cachefile_redirect (CACHEFILE cf, int newfd, const char *fname_in_env, const char *fname_in_cwd) {
int toku_cachefile_redirect (CACHEFILE cf, int newfd, const char *fname_in_env) {
int r;
struct fileid newfileid;
assert(newfd >= 0);
......@@ -607,9 +617,7 @@ int toku_cachefile_redirect (CACHEFILE cf, int newfd, const char *fname_in_env,
toku_free(cf->fname_in_env); // free old iname string
cf->fname_in_env = NULL; // hygiene
toku_free(cf->fname_in_cwd); // free old iname string
cf->fname_in_cwd = NULL; // hygiene
cachefile_init_filenum(cf, newfd, fname_in_env, fname_in_cwd, newfileid);
cachefile_init_filenum(cf, newfd, fname_in_env, newfileid);
rwlock_write_unlock(&cf->fdlock);
cachetable_unlock(ct);
......@@ -617,10 +625,14 @@ int toku_cachefile_redirect (CACHEFILE cf, int newfd, const char *fname_in_env,
}
//TEST_ONLY_FUNCTION
int toku_cachetable_openf (CACHEFILE *cfptr, CACHETABLE ct, const char *fname_in_env, const char *fname_in_cwd, int flags, mode_t mode) {
int toku_cachetable_openf (CACHEFILE *cfptr, CACHETABLE ct, const char *fname_in_env, int flags, mode_t mode) {
char *fname_in_cwd = toku_construct_full_name(2, ct->env_dir, fname_in_env);
int fd = open(fname_in_cwd, flags+O_BINARY, mode);
if (fd<0) return errno;
return toku_cachetable_openfd (cfptr, ct, fd, fname_in_env, fname_in_cwd);
int r;
if (fd<0) r = errno;
else r = toku_cachetable_openfd (cfptr, ct, fd, fname_in_env);
toku_free(fname_in_cwd);
return r;
}
WORKQUEUE toku_cachetable_get_workqueue(CACHETABLE ct) {
......@@ -657,13 +669,9 @@ int toku_cachefile_set_fd (CACHEFILE cf, int fd, const char *fname_in_env) {
toku_free(cf->fname_in_env);
cf->fname_in_env = NULL;
}
if (cf->fname_in_cwd) {
toku_free(cf->fname_in_cwd);
cf->fname_in_cwd = NULL;
}
//It is safe to have the name repeated since this is a newbrt-only test function.
//There isn't an environment directory so its both env/cwd.
cachefile_init_filenum(cf, fd, fname_in_env, fname_in_env, fileid);
cachefile_init_filenum(cf, fd, fname_in_env, fileid);
r = 0;
cleanup:
toku_cachefile_unpin_fd(cf);
......@@ -680,11 +688,6 @@ toku_cachefile_fname_in_env (CACHEFILE cf) {
return cf->fname_in_env;
}
char *
toku_cachefile_fname_in_cwd (CACHEFILE cf) {
return cf->fname_in_cwd;
}
int toku_cachefile_get_and_pin_fd (CACHEFILE cf) {
CACHETABLE ct = cf->cachetable;
cachetable_lock(ct);
......@@ -780,7 +783,6 @@ int toku_cachefile_close (CACHEFILE *cfp, char **error_string, BOOL oplsn_valid,
assert(rd == 0);
}
if (cf->fname_in_env) toku_free(cf->fname_in_env);
if (cf->fname_in_cwd) toku_free(cf->fname_in_cwd);
rwlock_write_lock(&cf->fdlock, ct->mutex);
if ( !toku_cachefile_is_dev_null_unlocked(cf) ) {
......@@ -847,7 +849,6 @@ int toku_cachefile_close (CACHEFILE *cfp, char **error_string, BOOL oplsn_valid,
cf->fd = -1;
if (cf->fname_in_env) toku_free(cf->fname_in_env);
if (cf->fname_in_cwd) toku_free(cf->fname_in_cwd);
toku_free(cf);
*cfp=NULL;
return r;
......@@ -1854,6 +1855,7 @@ toku_cachetable_close (CACHETABLE *ctp) {
toku_omt_destroy(&ct->reserved_filenums);
r = toku_pthread_mutex_destroy(&ct->cachefiles_mutex); assert(r == 0);
toku_free(ct->table);
toku_free(ct->env_dir);
toku_free(ct);
*ctp = 0;
return 0;
......@@ -2311,12 +2313,9 @@ int toku_cachefile_redirect_nullfd (CACHEFILE cf) {
close(cf->fd); // no change for t:2444
cf->fd = null_fd;
char *saved_fname_in_env = cf->fname_in_env;
char *saved_fname_in_cwd = cf->fname_in_cwd;
cf->fname_in_env = NULL;
cf->fname_in_cwd = NULL;
cachefile_init_filenum(cf, null_fd, saved_fname_in_env, saved_fname_in_cwd, fileid);
cachefile_init_filenum(cf, null_fd, saved_fname_in_env, fileid);
if (saved_fname_in_env) toku_free(saved_fname_in_env);
if (saved_fname_in_cwd) toku_free(saved_fname_in_cwd);
cf->is_dev_null = TRUE;
rwlock_write_unlock(&cf->fdlock);
cachetable_unlock(ct);
......@@ -2358,3 +2357,34 @@ void toku_cachetable_get_status(CACHETABLE ct, CACHETABLE_STATUS s) {
s->size_writing = ct->size_writing;
s->get_and_pin_footprint = get_and_pin_footprint;
}
char *
toku_construct_full_name(int count, ...) {
va_list ap;
char *name = NULL;
size_t n = 0;
int i;
va_start(ap, count);
for (i=0; i<count; i++) {
char *arg = va_arg(ap, char *);
if (arg) {
n += 1 + strlen(arg) + 1;
char *newname = toku_xmalloc(n);
if (name && !toku_os_is_absolute_name(arg))
snprintf(newname, n, "%s/%s", name, arg);
else
snprintf(newname, n, "%s", arg);
toku_free(name);
name = newname;
}
}
va_end(ap);
return name;
}
char *
toku_cachetable_get_fname_in_cwd(CACHETABLE ct, const char * fname_in_env) {
return toku_construct_full_name(2, ct->env_dir, fname_in_env);
}
......@@ -73,18 +73,17 @@ int toku_cachetable_close (CACHETABLE*); /* Flushes everything to disk, and dest
void toku_cachetable_get_miss_times(CACHETABLE ct, uint64_t *misscount, uint64_t *misstime);
// Open a file and bind the file to a new cachefile object. (For use by test programs only.)
int toku_cachetable_openf (CACHEFILE *,CACHETABLE, const char */*fname_in_env*/, const char */*fname_in_cwd*/,int flags, mode_t mode);
int toku_cachetable_openf (CACHEFILE *,CACHETABLE, const char */*fname_in_env*/, int flags, mode_t mode);
// Bind a file to a new cachefile object.
int toku_cachetable_openfd (CACHEFILE *,CACHETABLE, int /*fd*/,
const char *fname_relative_to_env /*(used for logging)*/,
const char *fname_in_cwd);
const char *fname_relative_to_env); /*(used for logging)*/
int toku_cachetable_openfd_with_filenum (CACHEFILE *,CACHETABLE, int /*fd*/,
const char *fname_in_env, const char *fname_in_cwd,
const char *fname_in_env,
BOOL with_filenum, FILENUM filenum, BOOL reserved);
// Change the binding of which file is attached to a cachefile. Close the old fd. Use the new fd.
int toku_cachefile_redirect (CACHEFILE cf, int fd, const char *fname_in_env, const char *fname_in_cwd);
int toku_cachefile_redirect (CACHEFILE cf, int fd, const char *fname_in_env);
int toku_cachetable_reserve_filenum (CACHETABLE ct, FILENUM *reserved_filenum, BOOL with_filenum, FILENUM filenum);
......@@ -313,4 +312,8 @@ void toku_cachetable_get_status(CACHETABLE ct, CACHETABLE_STATUS s);
LEAFLOCK_POOL toku_cachefile_leaflock_pool(CACHEFILE cf);
void toku_cachetable_set_env_dir(CACHETABLE ct, char *env_dir);
char * toku_construct_full_name(int count, ...);
char * toku_cachetable_get_fname_in_cwd(CACHETABLE ct, const char * fname_in_env);
#endif
......@@ -176,7 +176,7 @@ const struct logtype logtypes[] = {
{"comment", 'T', FA{{"u_int64_t", "timestamp", 0},
{"BYTESTRING", "comment", 0},
NULLFIELD}},
{"load", 'l', FA{{"u_int64_t", "timestamp", 0},
{"load", 'l', FA{{"TXNID", "xid", 0},
{"BYTESTRING", "old_iname", 0},
{"BYTESTRING", "new_iname", 0},
NULLFIELD}},
......
......@@ -261,7 +261,7 @@ static int internal_toku_recover_fopen_or_fcreate (RECOVER_ENV renv, BOOL must_c
r = toku_brt_set_descriptor(brt, descriptor_version, &descriptor_dbt, abort_on_upgrade);
if (r!=0) goto close_brt;
}
r = toku_brt_open_recovery(brt, iname, iname, must_create, must_create, renv->ct, txn, fake_db, recovery_force_fcreate, filenum);
r = toku_brt_open_recovery(brt, iname, must_create, must_create, renv->ct, txn, fake_db, recovery_force_fcreate, filenum);
if (r != 0) {
close_brt:
;
......@@ -413,7 +413,7 @@ static int toku_recover_fdelete (struct logtype_fdelete *l, RECOVER_ENV renv) {
// txn exists and file exists, so create fdelete rollback entry
DBT iname_dbt;
toku_fill_dbt(&iname_dbt, fixediname, strlen(fixediname)+1);
r = toku_brt_remove_on_commit(txn, &iname_dbt, &iname_dbt);
r = toku_brt_remove_on_commit(txn, &iname_dbt);
assert(r==0);
cleanup:
toku_free(fixediname);
......@@ -987,8 +987,23 @@ static int toku_recover_backward_comment (struct logtype_comment *UU(l), RECOVER
}
static int toku_recover_load(struct logtype_load *UU(l), RECOVER_ENV UU(renv)) {
// need to implement
assert(1);
int r;
TOKUTXN txn = NULL;
r = toku_txnid2txn(renv->logger, l->xid, &txn);
assert(r == 0);
if (txn == NULL) {
//This is a straddle txn.
assert(renv->ss.ss == FORWARD_OLDER_CHECKPOINT_BEGIN); //cannot happen after checkpoint begin
return 0;
}
char *old_iname = fixup_fname(&l->old_iname);
char *new_iname = fixup_fname(&l->new_iname);
r = toku_brt_load_recovery(txn, old_iname, new_iname, 0, 0);
assert(r==0);
toku_free(old_iname);
toku_free(new_iname);
return 0;
}
......
......@@ -20,8 +20,6 @@ toku_commit_fdelete (u_int8_t file_was_open,
LSN UU(oplsn)) //oplsn is the lsn of the commit
{
//TODO: #2037 verify the file is (user) closed
char *fname = fixup_fname(&bs_fname);
//Remove reference to the fd in the cachetable
CACHEFILE cf;
int r;
......@@ -39,9 +37,13 @@ toku_commit_fdelete (u_int8_t file_was_open,
r = toku_cachefile_redirect_nullfd(cf);
assert(r==0);
}
r = unlink(fname); // pathname relative to cwd
assert(r==0);
toku_free(fname);
char *fname_in_env = fixup_fname(&bs_fname);
char *fname_in_cwd = toku_cachetable_get_fname_in_cwd(txn->logger->ct, fname_in_env);
r = unlink(fname_in_cwd);
assert(r==0 || errno==ENOENT);
toku_free(fname_in_env);
toku_free(fname_in_cwd);
return 0;
}
......@@ -78,7 +80,6 @@ toku_rollback_fcreate (FILENUM filenum,
LSN UU(oplsn))
{
//TODO: #2037 verify the file is (user) closed
char *fname = fixup_fname(&bs_fname);
//Remove reference to the fd in the cachetable
CACHEFILE cf = NULL;
......@@ -94,9 +95,14 @@ toku_rollback_fcreate (FILENUM filenum,
}
r = toku_cachefile_redirect_nullfd(cf);
assert(r==0);
r = unlink(fname); // fname is relative to cwd
assert(r==0);
toku_free(fname);
char *fname_in_env = fixup_fname(&bs_fname);
char *fname_in_cwd = toku_cachetable_get_fname_in_cwd(txn->logger->ct, fname_in_env);
r = unlink(fname_in_cwd);
assert(r==0 || errno==ENOENT);
toku_free(fname_in_env);
toku_free(fname_in_cwd);
return 0;
}
......@@ -316,15 +322,18 @@ toku_commit_rollinclude (BYTESTRING bs,
void * yieldv,
LSN oplsn) {
int r;
char *fname = fixup_fname(&bs);
int fd = open(fname, O_RDONLY+O_BINARY);
char *fname_in_logger = fixup_fname(&bs);
char *fname_in_cwd = toku_construct_full_name(2, txn->logger->directory, fname_in_logger);
int fd = open(fname_in_cwd, O_RDONLY+O_BINARY);
assert(fd>=0);
r = toku_commit_fileentries(fd, txn, yield, yieldv, oplsn);
assert(r==0);
r = close(fd);
assert(r==0);
unlink(fname);
toku_free(fname);
r = unlink(fname_in_cwd);
assert(r==0);
toku_free(fname_in_logger);
toku_free(fname_in_cwd);
return 0;
}
......@@ -336,15 +345,18 @@ toku_rollback_rollinclude (BYTESTRING bs,
LSN oplsn)
{
int r;
char *fname = fixup_fname(&bs);
int fd = open(fname, O_RDONLY+O_BINARY);
char *fname_in_logger = fixup_fname(&bs);
char *fname_in_cwd = toku_construct_full_name(2, txn->logger->directory, fname_in_logger);
int fd = open(fname_in_cwd, O_RDONLY+O_BINARY);
assert(fd>=0);
r = toku_rollback_fileentries(fd, txn, yield, yieldv, oplsn);
assert(r==0);
r = close(fd);
assert(r==0);
unlink(fname);
toku_free(fname);
r = unlink(fname_in_cwd);
assert(r==0);
toku_free(fname_in_logger);
toku_free(fname_in_cwd);
return 0;
}
......@@ -387,28 +399,56 @@ toku_commit_tablelock_on_empty_table (FILENUM filenum, TOKUTXN txn, YIELDF UU(yi
}
int
toku_commit_load (BYTESTRING UU(old_iname),
toku_commit_load (BYTESTRING old_iname,
BYTESTRING UU(new_iname),
TOKUTXN UU(txn),
TOKUTXN txn,
YIELDF UU(yield),
void *UU(yield_v),
LSN UU(oplsn))
{
// TODO 2216: need to implement
assert(1);
CACHEFILE cf;
int r;
char *fname_in_env = fixup_fname(&old_iname); //Delete old file
r = toku_cachefile_of_iname_in_env(txn->logger->ct, fname_in_env, &cf);
if (r==0) {
r = toku_cachefile_redirect_nullfd(cf);
assert(r==0);
}
else {
assert(r==ENOENT);
}
char *fname_in_cwd = toku_cachetable_get_fname_in_cwd(txn->logger->ct, fname_in_env);
r = unlink(fname_in_cwd);
assert(r==0 || errno==ENOENT);
toku_free(fname_in_env);
toku_free(fname_in_cwd);
return 0;
}
int
toku_rollback_load (BYTESTRING UU(old_iname),
BYTESTRING UU(new_iname),
TOKUTXN UU(txn),
BYTESTRING new_iname,
TOKUTXN txn,
YIELDF UU(yield),
void *UU(yield_v),
LSN UU(oplsn))
{
// TODO 2216: need to implement
assert(1);
CACHEFILE cf;
int r;
char *fname_in_env = fixup_fname(&new_iname); //Delete new file
r = toku_cachefile_of_iname_in_env(txn->logger->ct, fname_in_env, &cf);
if (r==0) {
r = toku_cachefile_redirect_nullfd(cf);
assert(r==0);
}
else {
assert(r==ENOENT);
}
char *fname_in_cwd = toku_cachetable_get_fname_in_cwd(txn->logger->ct, fname_in_env);
r = unlink(fname_in_cwd);
assert(r==0 || errno==ENOENT);
toku_free(fname_in_env);
toku_free(fname_in_cwd);
return 0;
}
......
......@@ -42,9 +42,11 @@ void toku_rollback_txn_close (TOKUTXN txn) {
if (txn->rollentry_filename!=0) {
int r = close(txn->rollentry_fd);
assert(r==0);
r = unlink(txn->rollentry_filename);
char *fname_in_cwd = toku_construct_full_name(2, txn->logger->directory, txn->rollentry_filename);
r = unlink(fname_in_cwd);
assert(r==0);
toku_free(txn->rollentry_filename);
toku_free(fname_in_cwd);
}
{
......@@ -126,11 +128,20 @@ int toku_rollback_commit(TOKUTXN txn, YIELDF yield, void*yieldv, LSN lsn) {
if (r!=0) return r;
r = close(txn->rollentry_fd);
if (r!=0) {
//TODO: #2249.. this is a panic/crash situation
// If the rolltmp file is necessary for a checkpoint
// we CANNOT delete it!
// For now.. delete it, but figure out how to deal with this later.
// Maybe we should just assert that the close succeeds?
// We have to do the unlink ourselves, and then
// set txn->rollentry_filename=0 so that the cleanup
// won't try to close the fd again.
char *fname_in_cwd = toku_construct_full_name(2, txn->logger->directory, txn->rollentry_filename);
r = unlink(fname_in_cwd);
assert(r==0); //Can we assert this at this point?
unlink(txn->rollentry_filename);
toku_free(txn->rollentry_filename);
toku_free(fname_in_cwd);
txn->rollentry_filename = 0;
return r;
}
......@@ -251,13 +262,11 @@ int toku_maybe_spill_rollbacks (TOKUTXN txn) {
assert((ssize_t)w.ndone==bufsize);
txn->oldest_logentry = txn->newest_logentry = 0;
if (txn->rollentry_fd<0) {
const char filenamepart[] = "/__tokudb_rolltmp.";
int fnamelen = strlen(txn->logger->directory)+sizeof(filenamepart)+16;
assert(txn->rollentry_filename==0);
txn->rollentry_filename = toku_malloc(fnamelen);
if (txn->rollentry_filename==0) return errno;
snprintf(txn->rollentry_filename, fnamelen, "%s%s%.16"PRIx64, txn->logger->directory, filenamepart, txn->txnid64);
txn->rollentry_fd = open(txn->rollentry_filename, O_CREAT+O_RDWR+O_EXCL+O_BINARY, 0600);
char filenamepart[sizeof("__tokudb_rolltmp.") + 16];
snprintf(filenamepart, sizeof(filenamepart), "__tokudb_rolltmp.%.16"PRIx64, txn->txnid64);
txn->rollentry_filename = toku_xstrdup(filenamepart);
char *rollentry_filename_in_cwd = toku_construct_full_name(2, txn->logger->directory, filenamepart);
txn->rollentry_fd = open(rollentry_filename_in_cwd, O_CREAT+O_RDWR+O_EXCL+O_BINARY, 0600);
if (txn->rollentry_fd==-1) return errno;
}
uLongf compressed_len = compressBound(w.ndone);
......
......@@ -785,7 +785,7 @@ static void test_brt_delete_both(int n) {
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, 1, 1, ct, null_txn, (DB*)0);
r = toku_brt_open(t, fname, 1, 1, ct, null_txn, (DB*)0);
assert(r==0);
DBT key, val;
......@@ -889,7 +889,7 @@ static void test_new_brt_cursor_first(int n, int dup_mode) {
r = toku_brt_create(&t); assert(r == 0);
r = toku_brt_set_flags(t, dup_mode); assert(r == 0);
r = toku_brt_set_nodesize(t, 4096); assert(r == 0);
r = toku_brt_open(t, fname, fname, 1, 1, ct, null_txn, 0); assert(r==0);
r = toku_brt_open(t, fname, 1, 1, ct, null_txn, 0); assert(r==0);
DBT key, val;
int k, v;
......@@ -942,7 +942,7 @@ static void test_new_brt_cursor_last(int n, int dup_mode) {
r = toku_brt_create(&t); assert(r == 0);
r = toku_brt_set_flags(t, dup_mode); assert(r == 0);
r = toku_brt_set_nodesize(t, 4096); assert(r == 0);
r = toku_brt_open(t, fname, fname, 1, 1, ct, null_txn, 0); assert(r==0);
r = toku_brt_open(t, fname, 1, 1, ct, null_txn, 0); assert(r==0);
DBT key, val;
int k, v;
......@@ -996,7 +996,7 @@ static void test_new_brt_cursor_next(int n, int dup_mode) {
r = toku_brt_create(&t); assert(r == 0);
r = toku_brt_set_flags(t, dup_mode); assert(r == 0);
r = toku_brt_set_nodesize(t, 4096); assert(r == 0);
r = toku_brt_open(t, fname, fname, 1, 1, ct, null_txn, 0); assert(r==0);
r = toku_brt_open(t, fname, 1, 1, ct, null_txn, 0); assert(r==0);
for (i=0; i<n; i++) {
DBT key, val;
......@@ -1040,7 +1040,7 @@ static void test_new_brt_cursor_prev(int n, int dup_mode) {
r = toku_brt_create(&t); assert(r == 0);
r = toku_brt_set_flags(t, dup_mode); assert(r == 0);
r = toku_brt_set_nodesize(t, 4096); assert(r == 0);
r = toku_brt_open(t, fname, fname, 1, 1, ct, null_txn, 0); assert(r==0);
r = toku_brt_open(t, fname, 1, 1, ct, null_txn, 0); assert(r==0);
for (i=0; i<n; i++) {
DBT key, val;
......@@ -1084,7 +1084,7 @@ static void test_new_brt_cursor_current(int n, int dup_mode) {
r = toku_brt_create(&t); assert(r == 0);
r = toku_brt_set_flags(t, dup_mode); assert(r == 0);
r = toku_brt_set_nodesize(t, 4096); assert(r == 0);
r = toku_brt_open(t, fname, fname, 1, 1, ct, null_txn, 0); assert(r==0);
r = toku_brt_open(t, fname, 1, 1, ct, null_txn, 0); assert(r==0);
for (i=0; i<n; i++) {
int k = toku_htonl(i);
......@@ -1167,7 +1167,7 @@ static void test_new_brt_cursor_set_range(int n, int dup_mode) {
r = toku_brt_create(&brt); assert(r == 0);
r = toku_brt_set_flags(brt, dup_mode); assert(r == 0);
r = toku_brt_set_nodesize(brt, 4096); assert(r == 0);
r = toku_brt_open(brt, fname, fname, 1, 1, ct, null_txn, 0); assert(r==0);
r = toku_brt_open(brt, fname, 1, 1, ct, null_txn, 0); assert(r==0);
int i;
......
......@@ -101,7 +101,7 @@ static void checkpoint_pending(void) {
r = toku_create_cachetable(&ct, test_limit*sizeof(int), ZERO_LSN, NULL_LOGGER); assert(r == 0);
char fname1[] = __FILE__ "test1.dat";
r = unlink(fname1); if (r!=0) CKERR2(errno, ENOENT);
r = toku_cachetable_openf(&cf, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&cf, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
toku_cachefile_set_userdata(cf, NULL, NULL, NULL, NULL, NULL, NULL,
dummy_pin_unpin, dummy_pin_unpin);
......
......@@ -59,7 +59,7 @@ static void cachetable_checkpoint_test(int n, enum cachetable_dirty dirty) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
toku_cachefile_set_userdata(f1, NULL, NULL, NULL, NULL, NULL, NULL,
dummy_pin_unpin, dummy_pin_unpin);
......
......@@ -36,7 +36,7 @@ cachetable_count_pinned_test (int n) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
int i;
for (i=1; i<=n; i++) {
......
......@@ -36,7 +36,7 @@ cachetable_debug_test (int n) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
int num_entries, hash_size; long size_current, size_limit;
toku_cachetable_get_state(ct, &num_entries, &hash_size, &size_current, &size_limit);
......
......@@ -11,7 +11,7 @@ cachetable_fd_test (void) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE cf;
r = toku_cachetable_openf(&cf, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&cf, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
int fd1 = toku_cachefile_get_and_pin_fd(cf); assert(fd1 >= 0);
toku_cachefile_unpin_fd(cf);
......
......@@ -36,12 +36,12 @@ test_cachetable_flush (int n) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
char fname2[] = __FILE__ "test2.dat";
unlink(fname2);
CACHEFILE f2;
r = toku_cachetable_openf(&f2, ct, fname2, fname2, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f2, ct, fname2, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
// insert keys 0..n-1
int i;
......
......@@ -45,7 +45,7 @@ cachetable_getandpin_test (int n) {
char fname1[] = __FILE__ "test_getandpin.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
int i;
......
......@@ -45,7 +45,7 @@ static void cachetable_prefetch_checkpoint_test(int n, enum cachetable_dirty dir
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
toku_cachefile_set_userdata(f1, NULL, NULL, NULL, NULL, NULL, NULL,
dummy_pin_unpin, dummy_pin_unpin);
......
......@@ -47,7 +47,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
// prefetch block 0. this will take 10 seconds.
CACHEKEY key = make_blocknum(0);
......
......@@ -48,7 +48,7 @@ static void cachetable_prefetch_close_leak_test (void) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
// prefetch block 0. this will take 10 seconds.
CACHEKEY key = make_blocknum(0);
......
......@@ -47,7 +47,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
// prefetch block 0. this will take 10 seconds.
CACHEKEY key = make_blocknum(0);
......
......@@ -59,7 +59,7 @@ static void cachetable_prefetch_flowcontrol_test (int cachetable_size_limit) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
int i;
......
......@@ -50,7 +50,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
struct timeval tstart;
gettimeofday(&tstart, NULL);
......
......@@ -50,7 +50,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
struct timeval tstart;
gettimeofday(&tstart, NULL);
......
......@@ -44,7 +44,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
// prefetch block 0. this will take 10 seconds.
CACHEKEY key = make_blocknum(0);
......
......@@ -48,7 +48,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
// prefetch block 0. this will take 10 seconds.
CACHEKEY key = make_blocknum(0);
......
......@@ -36,7 +36,7 @@ cachetable_put_test (int n) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
int i;
for (i=1; i<=n; i++) {
......
......@@ -89,7 +89,7 @@ static void test_rename (void) {
const char fname[] = __FILE__ "rename.dat";
r=toku_create_cachetable(&t, KEYLIMIT, ZERO_LSN, NULL_LOGGER); assert(r==0);
unlink(fname);
r = toku_cachetable_openf(&f, t, fname, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
assert(r==0);
for (i=0; i<TRIALLIMIT; i++) {
int ra = random()%3;
......
......@@ -18,7 +18,7 @@ cachetable_reserve_filenum_test (void) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE cf;
r = toku_cachetable_openf(&cf, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&cf, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
int fd1 = toku_cachefile_get_and_pin_fd(cf); assert(fd1 >= 0);
toku_cachefile_unpin_fd(cf);
......
......@@ -51,7 +51,7 @@ CACHEFILE f;
static void open_file (void ) {
int r;
r = toku_create_cachetable(&t, KEYLIMIT, ZERO_LSN, NULL_LOGGER); assert(r==0);
r = toku_cachetable_openf(&f, t, fname, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
}
static void writeit (void) {
......
......@@ -173,7 +173,7 @@ static void test0 (void) {
r=toku_create_cachetable(&t, 5, ZERO_LSN, NULL_LOGGER);
assert(r==0);
unlink(fname);
r = toku_cachetable_openf(&f, t, fname, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
assert(r==0);
TOKULOGGER logger = toku_cachefile_logger(f);
......@@ -326,7 +326,7 @@ static void test_nested_pin (void) {
r = toku_create_cachetable(&t, 1, ZERO_LSN, NULL_LOGGER);
assert(r==0);
unlink(fname);
r = toku_cachetable_openf(&f, t, fname, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
assert(r==0);
expect_f = f;
......@@ -397,10 +397,10 @@ static void test_multi_filehandles (void) {
unlink(fname2);
r = toku_create_cachetable(&t, 4, ZERO_LSN, NULL_LOGGER); assert(r==0);
r = toku_cachetable_openf(&f1, t, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
r = toku_cachetable_openf(&f1, t, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
r = link(fname1, fname2); assert(r==0);
r = toku_cachetable_openf(&f2, t, fname2, fname2, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
r = toku_cachetable_openf(&f3, t, fname3, fname3, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
r = toku_cachetable_openf(&f2, t, fname2, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
r = toku_cachetable_openf(&f3, t, fname3, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
assert(f1==f2);
assert(f1!=f3);
......@@ -464,7 +464,7 @@ static void test_dirty(void) {
char *fname = __FILE__ "test.dat";
unlink(fname);
r = toku_cachetable_openf(&f, t, fname, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
assert(r == 0);
key = make_blocknum(1); value = (void*)1;
......@@ -591,7 +591,7 @@ static void test_size_resize(void) {
char *fname = __FILE__ "test.dat";
unlink(fname);
r = toku_cachetable_openf(&f, t, fname, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
assert(r == 0);
CACHEKEY key = make_blocknum(42);
......@@ -646,7 +646,7 @@ static void test_size_flush(void) {
char *fname = __FILE__ "test.dat";
unlink(fname);
r = toku_cachetable_openf(&f, t, fname, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
assert(r == 0);
/* put 2*n keys into the table, ensure flushes occur in key order */
......
......@@ -156,7 +156,7 @@ static void test_chaining (void) {
r = snprintf(fname[i], FILENAME_LEN, __FILE__ ".%ld.dat", i);
assert(r>0 && r<FILENAME_LEN);
unlink(fname[i]);
r = toku_cachetable_openf(&f[i], ct, fname[i], fname[i], O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
r = toku_cachetable_openf(&f[i], ct, fname[i], O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
}
for (i=0; i<N_PRESENT_LIMIT; i++) {
int fnum = i%N_FILES;
......@@ -229,7 +229,7 @@ static void test_chaining (void) {
CACHEFILE oldcf=f[i];
r = toku_cachefile_close(&f[i], 0, FALSE, ZERO_LSN); assert(r==0);
file_is_not_present(oldcf);
r = toku_cachetable_openf(&f[i], ct, fname[i], fname[i], O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
r = toku_cachetable_openf(&f[i], ct, fname[i], O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
}
}
for (i=0; i<N_FILES; i++) {
......
......@@ -40,7 +40,7 @@ cachetable_unpin_and_remove_test (int n) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, 0777); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, 0777); assert(r == 0);
// generate some random keys
CACHEKEY keys[n]; int nkeys = n;
......@@ -104,7 +104,7 @@ cachetable_put_evict_remove_test (int n) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, 0777); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, 0777); assert(r == 0);
u_int32_t hi[n];
for (i=0; i<n; i++)
......
......@@ -36,7 +36,7 @@ cachetable_unpin_test (int n) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
int i;
for (i=1; i<=n; i++) {
......
......@@ -25,7 +25,7 @@ static void test_delete_all (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, 1, 1, ct, null_txn, (DB*)0); assert(r==0);
r = toku_brt_open(t, fname, 1, 1, ct, null_txn, (DB*)0); assert(r==0);
u_int32_t i;
for (i=0; i<limit; i++) {
char key[100];
......@@ -45,7 +45,7 @@ static void test_delete_all (void) {
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0);
r = toku_brt_create(&t); assert(r==0);
r = toku_brt_open(t, fname, fname, 0, 0, ct, null_txn, (DB*)0); assert(r==0);
r = toku_brt_open(t, fname, 0, 0, ct, null_txn, (DB*)0); assert(r==0);
// Don't do a dump here, because that will warm the cachetable. We want subsequent inserts to be buffered at the root.
......
......@@ -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, 1, 1, ct, null_txn, (DB*)0);
r = toku_brt_open(t, 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, 1, 1, ct, null_txn, (DB*)0);
r = toku_brt_open(t, fname, 1, 1, ct, null_txn, (DB*)0);
u_int64_t i;
for (i=0; i<limit; i++) {
u_int64_t j;
......
......@@ -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, 1, 1, ct, null_txn, (DB*)0); assert(r==0);
r = toku_brt_open(t, 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);
......
......@@ -51,7 +51,6 @@ struct __toku_loader_internal {
int err_errno;
char **inames_in_env; /* [N] inames of new files to be created */
char **inames_in_cwd; /* [N] */
};
static int verify_empty(DB *db, DB_TXN *txn)
......@@ -142,27 +141,25 @@ int toku_loader_create_loader(DB_ENV *env,
}
else {
char **XMALLOC_N(N, new_inames_in_env);
char **XMALLOC_N(N, new_inames_in_cwd);
const struct descriptor **XMALLOC_N(N, descriptors);
for (int i=0; i<N; i++) {
descriptors[i] = &dbs[i]->i->brt->h->descriptor;
}
loader->i->ekeys = NULL;
loader->i->evals = NULL;
r = ydb_load_inames (env, txn, N, dbs, new_inames_in_env, new_inames_in_cwd);
r = ydb_load_inames (env, txn, N, dbs, new_inames_in_env);
assert(r==0);
toku_brt_loader_open(&loader->i->brt_loader,
loader->i->env->i->cachetable,
loader->i->env->i->generate_row_for_put,
src_db,
N,
dbs,
descriptors,
(const char **)new_inames_in_env,
(const char **)new_inames_in_cwd,
compare_functions,
loader->i->temp_file_template);
loader->i->inames_in_env = new_inames_in_env;
loader->i->inames_in_cwd = new_inames_in_cwd;
toku_free(descriptors);
}
*blp = loader;
......@@ -247,16 +244,13 @@ int toku_loader_close(DB_LOADER *loader)
for (int i=0; i<loader->i->N; i++) {
toku_ydb_lock(); //Must hold ydb lock for dictionary_redirect.
int r = toku_dictionary_redirect(loader->i->inames_in_env[i],
loader->i->inames_in_cwd[i],
loader->i->dbs[i]->i->brt,
db_txn_struct_i(loader->i->txn)->tokutxn);
assert(r==0);
toku_ydb_unlock();
toku_free(loader->i->inames_in_env[i]);
toku_free(loader->i->inames_in_cwd[i]);
}
toku_free(loader->i->inames_in_env);
toku_free(loader->i->inames_in_cwd);
toku_free(loader->i->brt_loader);
// TODO: release table locks
}
......
......@@ -11,7 +11,6 @@ const char *toku_copyright_string = "Copyright (c) 2007-2009 Tokutek Inc. All r
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
......@@ -319,14 +318,11 @@ static int toku_c_del(DBC *c, u_int32_t flags);
static int toku_c_count(DBC *cursor, db_recno_t *count, u_int32_t flags);
static int toku_c_close(DBC * c);
/* misc */
static char *construct_full_name(int count, ...);
static int delete_rolltmp_files(DB_ENV *env) {
const char *datadir=env->i->dir;
char *logdir;
if (env->i->lg_dir) {
logdir = construct_full_name(2, env->i->dir, env->i->lg_dir);
logdir = toku_construct_full_name(2, env->i->dir, env->i->lg_dir);
} else {
logdir = toku_strdup(env->i->dir);
}
......@@ -340,7 +336,7 @@ ydb_do_recovery (DB_ENV *env) {
const char *envdir=env->i->dir;
char *logdir;
if (env->i->lg_dir) {
logdir = construct_full_name(2, env->i->dir, env->i->lg_dir);
logdir = toku_construct_full_name(2, env->i->dir, env->i->lg_dir);
} else {
logdir = toku_strdup(env->i->dir);
}
......@@ -356,7 +352,7 @@ ydb_do_recovery (DB_ENV *env) {
static int needs_recovery (DB_ENV *env) {
char *logdir;
if (env->i->lg_dir) {
logdir = construct_full_name(2, env->i->dir, env->i->lg_dir);
logdir = toku_construct_full_name(2, env->i->dir, env->i->lg_dir);
} else {
logdir = toku_strdup(env->i->dir);
}
......@@ -448,7 +444,7 @@ static int
ydb_recover_log_exists(DB_ENV *env) {
char *logdir;
if (env->i->lg_dir) {
logdir = construct_full_name(2, env->i->dir, env->i->lg_dir);
logdir = toku_construct_full_name(2, env->i->dir, env->i->lg_dir);
} else {
logdir = toku_strdup(env->i->dir);
}
......@@ -471,7 +467,7 @@ validate_env(DB_ENV * env, BOOL * valid_newenv) {
char* path = NULL;
// Test for persistent environment
path = construct_full_name(2, env->i->dir, environmentdictionary);
path = toku_construct_full_name(2, env->i->dir, environmentdictionary);
assert(path);
r = toku_stat(path, &buf);
toku_free(path);
......@@ -489,7 +485,7 @@ validate_env(DB_ENV * env, BOOL * valid_newenv) {
// Test for fileops directory
if (r == 0) {
path = construct_full_name(2, env->i->dir, fileopsdirectory);
path = toku_construct_full_name(2, env->i->dir, fileopsdirectory);
assert(path);
r = toku_stat(path, &buf);
toku_free(path);
......@@ -629,7 +625,7 @@ toku_env_open(DB_ENV * env, const char *home, u_int32_t flags, int mode) {
if (flags & (DB_INIT_TXN | DB_INIT_LOG)) {
char* full_dir = NULL;
if (env->i->lg_dir) {
full_dir = construct_full_name(2, env->i->dir, env->i->lg_dir);
full_dir = toku_construct_full_name(2, env->i->dir, env->i->lg_dir);
assert(full_dir);
}
assert(env->i->logger);
......@@ -665,6 +661,8 @@ toku_env_open(DB_ENV * env, const char *home, u_int32_t flags, int mode) {
r = toku_brt_create_cachetable(&env->i->cachetable, env->i->cachetable_size, ZERO_LSN, env->i->logger);
if (r!=0) goto died2;
toku_cachetable_set_env_dir(env->i->cachetable, env->i->dir);
int using_txns = env->i->open_flags & DB_INIT_TXN;
if (env->i->logger) {
assert (using_txns);
......@@ -3888,30 +3886,6 @@ static int toku_db_key_range(DB * db, DB_TXN * txn, DBT * dbt, DB_KEY_RANGE * kr
}
#endif
static char *construct_full_name(int count, ...) {
va_list ap;
char *name = NULL;
size_t n = 0;
int i;
va_start(ap, count);
for (i=0; i<count; i++) {
char *arg = va_arg(ap, char *);
if (arg) {
n += 1 + strlen(arg) + 1;
char *newname = toku_xmalloc(n);
if (name && !toku_os_is_absolute_name(arg))
snprintf(newname, n, "%s/%s", name, arg);
else
snprintf(newname, n, "%s", arg);
toku_free(name);
name = newname;
}
}
va_end(ap);
return name;
}
static int toku_db_lt_panic(DB* db, int r) {
assert(r!=0);
assert(db && db->i && db->dbenv && db->dbenv->i);
......@@ -4019,9 +3993,9 @@ create_iname(DB_ENV *env, u_int64_t id, char *hint, int n) {
assert(bytes<=(int)sizeof(inamebase)-1);
char *rval;
if (env->i->data_dir)
rval = construct_full_name(2, env->i->data_dir, inamebase);
rval = toku_construct_full_name(2, env->i->data_dir, inamebase);
else
rval = construct_full_name(1, inamebase);
rval = toku_construct_full_name(1, inamebase);
assert(rval);
return rval;
}
......@@ -4178,14 +4152,11 @@ db_open_iname(DB * db, DB_TXN * txn, const char *iname_in_env, u_int32_t flags,
db->i->open_flags = flags;
db->i->open_mode = mode;
char *iname_in_cwd = construct_full_name(2, db->dbenv->i->dir, iname_in_env); // allocates memory for iname_in_cwd
assert(iname_in_cwd);
r = toku_brt_open(db->i->brt, iname_in_env, iname_in_cwd,
r = toku_brt_open(db->i->brt, iname_in_env,
is_db_create, is_db_excl,
db->dbenv->i->cachetable,
txn ? db_txn_struct_i(txn)->tokutxn : NULL_TXN,
db);
toku_free(iname_in_cwd);
if (r != 0)
goto error_cleanup;
......@@ -4469,13 +4440,8 @@ toku_env_dbremove(DB_ENV * env, DB_TXN *txn, const char *fname, const char *dbna
// remove (dname,iname) from directory
r = toku_db_del(env->i->directory, child, &dname_dbt, DB_DELETE_ANY);
if (r == 0) {
char *iname_within_cwd = construct_full_name(2, env->i->dir, iname_dbt.data);
assert(iname_within_cwd);
DBT iname_within_cwd_dbt;
toku_fill_dbt(&iname_within_cwd_dbt, iname_within_cwd, strlen(iname_within_cwd)+1);
if (using_txns) {
r = toku_brt_remove_on_commit(db_txn_struct_i(child)->tokutxn,
&iname_dbt, &iname_within_cwd_dbt);
r = toku_brt_remove_on_commit(db_txn_struct_i(child)->tokutxn, &iname_dbt);
assert(r==0);
//Now that we have a writelock on dname, verify that there are still no handles open. (to prevent race conditions)
if (r==0 && env_is_db_with_dname_open(env, dname))
......@@ -4489,10 +4455,9 @@ toku_env_dbremove(DB_ENV * env, DB_TXN *txn, const char *fname, const char *dbna
}
}
else {
r = toku_brt_remove_now(env->i->cachetable, &iname_dbt, &iname_within_cwd_dbt);
r = toku_brt_remove_now(env->i->cachetable, &iname_dbt);
assert(r==0);
}
toku_free(iname_within_cwd);
}
}
......@@ -5322,7 +5287,7 @@ env_get_iname(DB_ENV* env, DBT* dname_dbt, DBT* iname_dbt) {
// It is the caller's responsibility to free them.
// Return 0 on success (could fail if write lock not available).
int
ydb_load_inames(DB_ENV * env, DB_TXN * txn, int N, DB * dbs[N], char * new_inames_in_env[N], char * new_inames_in_cwd[N]) {
ydb_load_inames(DB_ENV * env, DB_TXN * txn, int N, DB * dbs[N], char * new_inames_in_env[N]) {
int rval;
int i;
......@@ -5334,7 +5299,6 @@ ydb_load_inames(DB_ENV * env, DB_TXN * txn, int N, DB * dbs[N], char * new_iname
for (i=0; i<N; i++) {
new_inames_in_env[i] = NULL;
new_inames_in_cwd[i] = NULL;
}
// begin child (unless transactionless)
......@@ -5354,7 +5318,19 @@ ydb_load_inames(DB_ENV * env, DB_TXN * txn, int N, DB * dbs[N], char * new_iname
rval = toku_db_put(env->i->directory, child, &dname_dbt, &iname_dbt, DB_YESOVERWRITE); // DB_YESOVERWRITE necessary
if (rval) break;
new_inames_in_env[i] = new_iname;
new_inames_in_cwd[i] = construct_full_name(2, env->i->dir, new_iname); // allocates memory for iname_in_cwd
}
// Generate load log entries.
if (!rval && using_txns) {
TOKUTXN ttxn = db_txn_struct_i(txn)->tokutxn;
int do_fsync = 0;
for (i = 0; i < N; i++) {
BRT brt = dbs[i]->i->brt;
//Fsync is necessary for the last one only.
if (i==N-1) do_fsync = 1; //We only need a single fsync of logs.
rval = toku_brt_load(brt, ttxn, new_inames_in_env[i], do_fsync);
if (rval) break;
}
}
if (using_txns) {
......@@ -5371,10 +5347,6 @@ ydb_load_inames(DB_ENV * env, DB_TXN * txn, int N, DB * dbs[N], char * new_iname
toku_free(new_inames_in_env[i]);
new_inames_in_env[i] = NULL;
}
if (new_inames_in_cwd[i]) {
toku_free(new_inames_in_cwd[i]);
new_inames_in_cwd[i] = NULL;
}
}
}
}
......@@ -5391,7 +5363,6 @@ test_db_redirect_dictionary(DB * db, char * dname_of_new_file, DB_TXN *dbtxn) {
DBT dname_dbt;
DBT iname_dbt;
char * new_iname_in_env;
char * new_iname_in_cwd;
BRT brt = db->i->brt;
TOKUTXN tokutxn = db_txn_struct_i(dbtxn)->tokutxn;
......@@ -5401,12 +5372,9 @@ test_db_redirect_dictionary(DB * db, char * dname_of_new_file, DB_TXN *dbtxn) {
r = toku_db_get(db->dbenv->i->directory, dbtxn, &dname_dbt, &iname_dbt, 0); // allocates memory for iname
assert(r==0);
new_iname_in_env = iname_dbt.data;
new_iname_in_cwd = construct_full_name(2, db->dbenv->i->dir, new_iname_in_env); // allocates memory for new_iname_in_cwd
assert(new_iname_in_cwd);
r = toku_dictionary_redirect(new_iname_in_env, new_iname_in_cwd, brt, tokutxn);
r = toku_dictionary_redirect(new_iname_in_env, brt, tokutxn);
toku_free(new_iname_in_env);
toku_free(new_iname_in_cwd);
return r;
}
......@@ -23,8 +23,7 @@ int ydb_load_inames(DB_ENV * env,
DB_TXN * txn,
int N,
DB * dbs[/*N*/],
/*out*/ char * new_inames_in_env[N],
/*out*/ char * new_inames_in_cwd[N]);
/*out*/ char * new_inames_in_env[N]);
#endif
......@@ -7,7 +7,7 @@ include $(TOKUROOT)toku_include/Makefile.include
SKIP_WARNING += $(ICC_NOWARN)1418 #Non static functions do not need prototypes.
SRCS = $(wildcard test-*.c)
SRCS=$(sort $(filter-out dir.%.c,$(wildcard *.c)))
BINS_RAW = $(patsubst %.c,%,$(SRCS))
#Bins will be generated.
$(BINS): $(LIBPORTABILITY)
......
#include "test.h"
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include "toku_time.h"
#define ENVDIR "dir."__FILE__
int verbose = 0;
static void
create_files(int N, int fds[N]) {
int r;
int i;
char name[30];
for (i = 0; i < N; i++) {
snprintf(name, sizeof(name), "%d", i);
fds[i] = open(name, O_CREAT|O_WRONLY);
if (fds[i] < 0) {
r = errno;
CKERR(r);
}
}
}
static void
write_to_files(int N, int bytes, int fds[N]) {
char junk[bytes];
int i;
for (i = 0; i < bytes; i++) {
junk[i] = random() & 0xFF;
}
int r;
for (i = 0; i < N; i++) {
r = toku_os_write(fds[i], junk, bytes);
CKERR(r);
}
}
static void
time_many_fsyncs_one_file(int N, int bytes, int fds[N]) {
if (verbose>1) {
printf("Starting %s\n", __FUNCTION__);
fflush(stdout);
}
struct timeval begin;
struct timeval after_first;
struct timeval end;
write_to_files(1, bytes, fds);
if (verbose>1) {
printf("Done writing to os buffers\n");
fflush(stdout);
}
int i;
int r;
r = gettimeofday(&begin, NULL);
CKERR(r);
r = fsync(fds[0]);
CKERR(r);
r = gettimeofday(&after_first, NULL);
CKERR(r);
for (i = 0; i < N; i++) {
r = fsync(fds[0]);
CKERR(r);
}
r = gettimeofday(&end, NULL);
CKERR(r);
if (verbose) {
printf("Fsyncing one file %d times:\n"
"\tFirst fsync took: [%f] seconds\n"
"\tRemaining %d fsyncs took additional: [%f] seconds\n"
"\tTotal time [%f] seconds\n",
N + 1,
toku_tdiff(&after_first, &begin),
N,
toku_tdiff(&end, &after_first),
toku_tdiff(&end, &begin));
fflush(stdout);
}
}
static void
time_fsyncs_many_files(int N, int bytes, int fds[N]) {
if (verbose>1) {
printf("Starting %s\n", __FUNCTION__);
fflush(stdout);
}
write_to_files(N, bytes, fds);
if (verbose>1) {
printf("Done writing to os buffers\n");
fflush(stdout);
}
struct timeval begin;
struct timeval after_first;
struct timeval end;
int i;
int r;
r = gettimeofday(&begin, NULL);
CKERR(r);
for (i = 0; i < N; i++) {
r = fsync(fds[i]);
CKERR(r);
if (i==0) {
r = gettimeofday(&after_first, NULL);
CKERR(r);
}
if (verbose>2) {
printf("Done fsyncing %d\n", i);
fflush(stdout);
}
}
r = gettimeofday(&end, NULL);
CKERR(r);
if (verbose) {
printf("Fsyncing %d files:\n"
"\tFirst fsync took: [%f] seconds\n"
"\tRemaining %d fsyncs took additional: [%f] seconds\n"
"\tTotal time [%f] seconds\n",
N,
toku_tdiff(&after_first, &begin),
N-1,
toku_tdiff(&end, &after_first),
toku_tdiff(&end, &begin));
fflush(stdout);
}
}
#if !TOKU_WINDOWS
//sync() does not appear to have an analogue on windows.
static void
time_sync_fsyncs_many_files(int N, int bytes, int fds[N]) {
if (verbose>1) {
printf("Starting %s\n", __FUNCTION__);
fflush(stdout);
}
//TODO: timing
write_to_files(N, bytes, fds);
if (verbose>1) {
printf("Done writing to os buffers\n");
fflush(stdout);
}
int i;
int r;
struct timeval begin;
struct timeval after_sync;
struct timeval end;
r = gettimeofday(&begin, NULL);
CKERR(r);
sync();
r = gettimeofday(&after_sync, NULL);
CKERR(r);
if (verbose>1) {
printf("Done with sync()\n");
fflush(stdout);
}
for (i = 0; i < N; i++) {
r = fsync(fds[i]);
CKERR(r);
if (verbose>2) {
printf("Done fsyncing %d\n", i);
fflush(stdout);
}
}
r = gettimeofday(&end, NULL);
CKERR(r);
if (verbose) {
printf("sync() then fsyncing %d files:\n"
"\tsync() took: [%f] seconds\n"
"\tRemaining %d fsyncs took additional: [%f] seconds\n"
"\tTotal time [%f] seconds\n",
N,
toku_tdiff(&after_sync, &begin),
N,
toku_tdiff(&end, &after_sync),
toku_tdiff(&end, &begin));
fflush(stdout);
}
}
#endif
int test_main(int argc, char *const argv[]) {
int i;
int r;
int N = 1000;
int bytes = 4096;
for (i=1; i<argc; i++) {
if (strcmp(argv[i], "-v") == 0) {
if (verbose < 0) verbose = 0;
verbose++;
continue;
}
if (strcmp(argv[i], "-q") == 0) {
verbose = 0;
continue;
}
if (strcmp(argv[i], "-b") == 0) {
i++;
if (i>=argc) exit(1);
bytes = atoi(argv[i]);
if (bytes <= 0) exit(1);
continue;
}
if (strcmp(argv[i], "-n") == 0) {
i++;
if (i>=argc) exit(1);
N = atoi(argv[i]);
if (N <= 0) exit(1);
continue;
}
}
r = system("rm -rf " ENVDIR);
CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO);
CKERR(r);
r = chdir(ENVDIR);
CKERR(r);
int fds[N];
create_files(N, fds);
time_many_fsyncs_one_file(N, bytes, fds);
time_fsyncs_many_files(N, bytes, fds);
#if !TOKU_WINDOWS
time_sync_fsyncs_many_files(N, bytes, fds);
#endif
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment