mirror of
https://github.com/MariaDB/server.git
synced 2025-02-01 19:41:47 +01:00
fixes #5423 fixes #5424 fixes #5503 fixes #5225 fsync always succeeds and returns void, no more ft panic or logger panic, no more impossible error paths
git-svn-id: file:///svn/toku/tokudb@48076 c7de825b-a66e-492c-adef-691d508d4ae1
This commit is contained in:
parent
3dbcdf4794
commit
0bc5013e30
211 changed files with 1621 additions and 2647 deletions
|
@ -696,21 +696,21 @@ int main (int argc, char *const argv[] __attribute__((__unused__))) {
|
|||
printf("const char *db_strerror(int) %s;\n", VISIBLE);
|
||||
printf("const char *db_version(int*,int *,int *) %s;\n", VISIBLE);
|
||||
printf("int log_compare (const DB_LSN*, const DB_LSN *) %s;\n", VISIBLE);
|
||||
printf("int db_env_set_func_fsync (int (*)(int)) %s;\n", VISIBLE);
|
||||
printf("int toku_set_trace_file (const char *fname) %s;\n", VISIBLE);
|
||||
printf("int toku_close_trace_file (void) %s;\n", VISIBLE);
|
||||
printf("int db_env_set_func_free (void (*)(void*)) %s;\n", VISIBLE);
|
||||
printf("int db_env_set_func_malloc (void *(*)(size_t)) %s;\n", VISIBLE);
|
||||
printf("int db_env_set_func_realloc (void *(*)(void*, size_t)) %s;\n", VISIBLE);
|
||||
printf("int db_env_set_func_pwrite (ssize_t (*)(int, const void *, size_t, toku_off_t)) %s;\n", VISIBLE);
|
||||
printf("int db_env_set_func_full_pwrite (ssize_t (*)(int, const void *, size_t, toku_off_t)) %s;\n", VISIBLE);
|
||||
printf("int db_env_set_func_write (ssize_t (*)(int, const void *, size_t)) %s;\n", VISIBLE);
|
||||
printf("int db_env_set_func_full_write (ssize_t (*)(int, const void *, size_t)) %s;\n", VISIBLE);
|
||||
printf("int db_env_set_func_fdopen (FILE* (*)(int, const char *)) %s;\n", VISIBLE);
|
||||
printf("int db_env_set_func_fopen (FILE* (*)(const char *, const char *)) %s;\n", VISIBLE);
|
||||
printf("int db_env_set_func_open (int (*)(const char *, int, int)) %s;\n", VISIBLE);
|
||||
printf("int db_env_set_func_fclose (int (*)(FILE*)) %s;\n", VISIBLE);
|
||||
printf("int db_env_set_func_pread (ssize_t (*)(int, void *, size_t, off_t)) %s;\n", VISIBLE);
|
||||
printf("void db_env_set_func_fsync (int (*)(int)) %s;\n", VISIBLE);
|
||||
printf("void db_env_set_func_free (void (*)(void*)) %s;\n", VISIBLE);
|
||||
printf("void db_env_set_func_malloc (void *(*)(size_t)) %s;\n", VISIBLE);
|
||||
printf("void db_env_set_func_realloc (void *(*)(void*, size_t)) %s;\n", VISIBLE);
|
||||
printf("void db_env_set_func_pwrite (ssize_t (*)(int, const void *, size_t, toku_off_t)) %s;\n", VISIBLE);
|
||||
printf("void db_env_set_func_full_pwrite (ssize_t (*)(int, const void *, size_t, toku_off_t)) %s;\n", VISIBLE);
|
||||
printf("void db_env_set_func_write (ssize_t (*)(int, const void *, size_t)) %s;\n", VISIBLE);
|
||||
printf("void db_env_set_func_full_write (ssize_t (*)(int, const void *, size_t)) %s;\n", VISIBLE);
|
||||
printf("void db_env_set_func_fdopen (FILE* (*)(int, const char *)) %s;\n", VISIBLE);
|
||||
printf("void db_env_set_func_fopen (FILE* (*)(const char *, const char *)) %s;\n", VISIBLE);
|
||||
printf("void db_env_set_func_open (int (*)(const char *, int, int)) %s;\n", VISIBLE);
|
||||
printf("void db_env_set_func_fclose (int (*)(FILE*)) %s;\n", VISIBLE);
|
||||
printf("void db_env_set_func_pread (ssize_t (*)(int, void *, size_t, off_t)) %s;\n", VISIBLE);
|
||||
printf("void db_env_set_func_loader_fwrite (size_t (*fwrite_fun)(const void*,size_t,size_t,FILE*)) %s;\n", VISIBLE);
|
||||
printf("void db_env_set_checkpoint_callback (void (*)(void*), void*) %s;\n", VISIBLE);
|
||||
printf("void db_env_set_checkpoint_callback2 (void (*)(void*), void*) %s;\n", VISIBLE);
|
||||
|
|
|
@ -365,16 +365,6 @@ toku_ft_unlock (FT ft) {
|
|||
unlock_for_blocktable(bt);
|
||||
}
|
||||
|
||||
// This is a special debugging function used only in the brt-serialize-test.
|
||||
void
|
||||
toku_block_alloc(BLOCK_TABLE bt, uint64_t size, uint64_t *offset) {
|
||||
lock_for_blocktable(bt);
|
||||
PRNTF("allocSomethingUnknown", 0L, (int64_t)size, 0L, bt);
|
||||
block_allocator_alloc_block(bt->block_allocator, size, offset);
|
||||
PRNTF("allocSomethingUnknownd", 0L, (int64_t)size, (int64_t)*offset, bt);
|
||||
unlock_for_blocktable(bt);
|
||||
}
|
||||
|
||||
// Also used only in brt-serialize-test.
|
||||
void
|
||||
toku_block_free(BLOCK_TABLE bt, uint64_t offset) {
|
||||
|
|
|
@ -57,7 +57,6 @@ void toku_block_table_swap_for_redirect(BLOCK_TABLE old_bt, BLOCK_TABLE new_bt);
|
|||
//DEBUG ONLY (ftdump included), tests included
|
||||
void toku_blocknum_dump_translation(BLOCK_TABLE bt, BLOCKNUM b);
|
||||
void toku_dump_translation_table(FILE *f, BLOCK_TABLE bt);
|
||||
void toku_block_alloc(BLOCK_TABLE bt, uint64_t size, uint64_t *offset);
|
||||
void toku_block_free(BLOCK_TABLE bt, uint64_t offset);
|
||||
typedef int(*BLOCKTABLE_CALLBACK)(BLOCKNUM b, int64_t size, int64_t address, void *extra);
|
||||
enum translation_type {TRANSLATION_NONE=0,
|
||||
|
|
|
@ -108,14 +108,14 @@ struct cachefile {
|
|||
char *fname_in_env; /* Used for logging */
|
||||
|
||||
void *userdata;
|
||||
int (*log_fassociate_during_checkpoint)(CACHEFILE cf, void *userdata); // When starting a checkpoint we must log all open files.
|
||||
int (*log_suppress_rollback_during_checkpoint)(CACHEFILE cf, void *userdata); // When starting a checkpoint we must log which files need rollbacks suppressed
|
||||
int (*close_userdata)(CACHEFILE cf, int fd, void *userdata, char **error_string, bool lsnvalid, LSN); // when closing the last reference to a cachefile, first call this function.
|
||||
int (*begin_checkpoint_userdata)(LSN lsn_of_checkpoint, void *userdata); // before checkpointing cachefiles call this function.
|
||||
void (*log_fassociate_during_checkpoint)(CACHEFILE cf, void *userdata); // When starting a checkpoint we must log all open files.
|
||||
void (*log_suppress_rollback_during_checkpoint)(CACHEFILE cf, void *userdata); // When starting a checkpoint we must log which files need rollbacks suppressed
|
||||
int (*close_userdata)(CACHEFILE cf, int fd, void *userdata, bool lsnvalid, LSN); // when closing the last reference to a cachefile, first call this function.
|
||||
void (*begin_checkpoint_userdata)(LSN lsn_of_checkpoint, void *userdata); // before checkpointing cachefiles call this function.
|
||||
int (*checkpoint_userdata)(CACHEFILE cf, int fd, void *userdata); // when checkpointing a cachefile, call this function.
|
||||
int (*end_checkpoint_userdata)(CACHEFILE cf, int fd, void *userdata); // after checkpointing cachefiles call this function.
|
||||
int (*note_pin_by_checkpoint)(CACHEFILE cf, void *userdata); // add a reference to the userdata to prevent it from being removed from memory
|
||||
int (*note_unpin_by_checkpoint)(CACHEFILE cf, void *userdata); // add a reference to the userdata to prevent it from being removed from memory
|
||||
void (*end_checkpoint_userdata)(CACHEFILE cf, int fd, void *userdata); // after checkpointing cachefiles call this function.
|
||||
void (*note_pin_by_checkpoint)(CACHEFILE cf, void *userdata); // add a reference to the userdata to prevent it from being removed from memory
|
||||
void (*note_unpin_by_checkpoint)(CACHEFILE cf, void *userdata); // add a reference to the userdata to prevent it from being removed from memory
|
||||
BACKGROUND_JOB_MANAGER bjm;
|
||||
};
|
||||
|
||||
|
@ -262,7 +262,7 @@ public:
|
|||
toku_pthread_rwlock_t m_pending_lock_expensive;
|
||||
toku_pthread_rwlock_t m_pending_lock_cheap;
|
||||
void init();
|
||||
int destroy();
|
||||
void destroy();
|
||||
void evict(PAIR pair);
|
||||
void put(PAIR pair);
|
||||
PAIR find_pair(CACHEFILE file, CACHEKEY key, uint32_t hash);
|
||||
|
@ -317,14 +317,14 @@ class checkpointer {
|
|||
public:
|
||||
void init(pair_list *_pl, TOKULOGGER _logger, evictor *_ev, cachefile_list *files);
|
||||
void destroy();
|
||||
int set_checkpoint_period(uint32_t new_period);
|
||||
void set_checkpoint_period(uint32_t new_period);
|
||||
uint32_t get_checkpoint_period();
|
||||
int shutdown();
|
||||
bool has_been_shutdown();
|
||||
int begin_checkpoint();
|
||||
void begin_checkpoint();
|
||||
void add_background_job();
|
||||
void remove_background_job();
|
||||
int end_checkpoint(void (*testcallback_f)(void*), void* testextra);
|
||||
void end_checkpoint(void (*testcallback_f)(void*), void* testextra);
|
||||
TOKULOGGER get_logger();
|
||||
// used during begin_checkpoint
|
||||
void increment_num_txns();
|
||||
|
@ -351,7 +351,7 @@ private:
|
|||
void checkpoint_userdata(CACHEFILE* checkpoint_cfs);
|
||||
void log_end_checkpoint();
|
||||
void end_checkpoint_userdata(CACHEFILE* checkpoint_cfs);
|
||||
int remove_cachefiles(CACHEFILE* checkpoint_cfs);
|
||||
void remove_cachefiles(CACHEFILE* checkpoint_cfs);
|
||||
|
||||
// Unit test struct needs access to private members.
|
||||
friend struct checkpointer_test;
|
||||
|
|
312
ft/cachetable.cc
312
ft/cachetable.cc
|
@ -151,8 +151,8 @@ checkpoint_thread (void *checkpointer_v)
|
|||
return r;
|
||||
}
|
||||
|
||||
int toku_set_checkpoint_period (CACHETABLE ct, uint32_t new_period) {
|
||||
return ct->cp.set_checkpoint_period(new_period);
|
||||
void toku_set_checkpoint_period (CACHETABLE ct, uint32_t new_period) {
|
||||
ct->cp.set_checkpoint_period(new_period);
|
||||
}
|
||||
|
||||
uint32_t toku_get_checkpoint_period (CACHETABLE ct) {
|
||||
|
@ -163,9 +163,8 @@ uint32_t toku_get_checkpoint_period_unlocked (CACHETABLE ct) {
|
|||
return ct->cp.get_checkpoint_period();
|
||||
}
|
||||
|
||||
int toku_set_cleaner_period (CACHETABLE ct, uint32_t new_period) {
|
||||
void toku_set_cleaner_period (CACHETABLE ct, uint32_t new_period) {
|
||||
ct->cl.set_period(new_period);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t toku_get_cleaner_period (CACHETABLE ct) {
|
||||
|
@ -176,9 +175,8 @@ uint32_t toku_get_cleaner_period_unlocked (CACHETABLE ct) {
|
|||
return ct->cl.get_period_unlocked();
|
||||
}
|
||||
|
||||
int toku_set_cleaner_iterations (CACHETABLE ct, uint32_t new_iterations) {
|
||||
void toku_set_cleaner_iterations (CACHETABLE ct, uint32_t new_iterations) {
|
||||
ct->cl.set_iterations(new_iterations);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t toku_get_cleaner_iterations (CACHETABLE ct) {
|
||||
|
@ -192,14 +190,12 @@ uint32_t toku_get_cleaner_iterations_unlocked (CACHETABLE ct) {
|
|||
// reserve 25% as "unreservable". The loader cannot have it.
|
||||
#define unreservable_memory(size) ((size)/4)
|
||||
|
||||
int toku_create_cachetable(CACHETABLE *result, long size_limit, LSN UU(initial_lsn), TOKULOGGER logger) {
|
||||
void toku_cachetable_create(CACHETABLE *result, long size_limit, LSN UU(initial_lsn), TOKULOGGER logger) {
|
||||
if (size_limit == 0) {
|
||||
size_limit = 128*1024*1024;
|
||||
}
|
||||
CACHETABLE MALLOC(ct);
|
||||
if (ct == 0) return ENOMEM;
|
||||
memset(ct, 0, sizeof(*ct));
|
||||
|
||||
CACHETABLE XCALLOC(ct);
|
||||
ct->list.init();
|
||||
ct->cf_list.init();
|
||||
|
||||
|
@ -214,7 +210,6 @@ int toku_create_cachetable(CACHETABLE *result, long size_limit, LSN UU(initial_l
|
|||
ct->cl.init(1, &ct->list, ct); // by default, start with one iteration
|
||||
ct->env_dir = toku_xstrdup(".");
|
||||
*result = ct;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Returns a pointer to the checkpoint contained within
|
||||
|
@ -393,7 +388,7 @@ int toku_cachefile_set_fd (CACHEFILE cf, int fd, const char *fname_in_env) {
|
|||
if (r != 0) {
|
||||
r=get_error_errno(); close(fd); goto cleanup; // no change for t:2444
|
||||
}
|
||||
if (cf->close_userdata && (r = cf->close_userdata(cf, cf->fd, cf->userdata, 0, false, ZERO_LSN))) {
|
||||
if (cf->close_userdata && (r = cf->close_userdata(cf, cf->fd, cf->userdata, false, ZERO_LSN))) {
|
||||
goto cleanup;
|
||||
}
|
||||
cf->close_userdata = NULL;
|
||||
|
@ -445,7 +440,7 @@ static void remove_cf_from_cachefiles_list (CACHEFILE cf) {
|
|||
|
||||
// TODO: (Zardosht) review locking of this function carefully in code review
|
||||
int
|
||||
toku_cachefile_close(CACHEFILE *cfp, char **error_string, bool oplsn_valid, LSN oplsn) {
|
||||
toku_cachefile_close(CACHEFILE *cfp, bool oplsn_valid, LSN oplsn) {
|
||||
int r, close_error = 0;
|
||||
CACHEFILE cf = *cfp;
|
||||
CACHETABLE ct = cf->cachetable;
|
||||
|
@ -463,7 +458,7 @@ toku_cachefile_close(CACHEFILE *cfp, char **error_string, bool oplsn_valid, LSN
|
|||
// Call the close userdata callback to notify the client this cachefile
|
||||
// and its underlying file are going to be closed
|
||||
if (cf->close_userdata) {
|
||||
close_error = cf->close_userdata(cf, cf->fd, cf->userdata, error_string, oplsn_valid, oplsn);
|
||||
close_error = cf->close_userdata(cf, cf->fd, cf->userdata, oplsn_valid, oplsn);
|
||||
}
|
||||
|
||||
remove_cf_from_cachefiles_list(cf);
|
||||
|
@ -471,8 +466,7 @@ toku_cachefile_close(CACHEFILE *cfp, char **error_string, bool oplsn_valid, LSN
|
|||
cf->bjm = NULL;
|
||||
|
||||
// fsync and close the fd.
|
||||
r = toku_file_fsync_without_accounting(cf->fd);
|
||||
assert(r == 0);
|
||||
toku_file_fsync_without_accounting(cf->fd);
|
||||
r = close(cf->fd);
|
||||
assert(r == 0);
|
||||
|
||||
|
@ -499,11 +493,10 @@ toku_cachefile_close(CACHEFILE *cfp, char **error_string, bool oplsn_valid, LSN
|
|||
// while this function is called, no other thread does work on the
|
||||
// cachefile.
|
||||
//
|
||||
int toku_cachefile_flush (CACHEFILE cf) {
|
||||
void toku_cachefile_flush (CACHEFILE cf) {
|
||||
bjm_wait_for_jobs_to_finish(cf->bjm);
|
||||
CACHETABLE ct = cf->cachetable;
|
||||
cachetable_flush_cachefile(ct, cf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This hash function comes from Jenkins: http://burtleburtle.net/bob/c/lookup3.c
|
||||
|
@ -825,37 +818,23 @@ static PAIR cachetable_insert_at(CACHETABLE ct,
|
|||
//
|
||||
// Requires pair list's write lock to be held on entry
|
||||
//
|
||||
static int cachetable_put_internal(
|
||||
static void cachetable_put_internal(
|
||||
CACHEFILE cachefile,
|
||||
CACHEKEY key,
|
||||
uint32_t fullhash,
|
||||
void*value,
|
||||
void *value,
|
||||
PAIR_ATTR attr,
|
||||
CACHETABLE_WRITE_CALLBACK write_callback,
|
||||
CACHETABLE_PUT_CALLBACK put_callback
|
||||
)
|
||||
{
|
||||
CACHETABLE ct = cachefile->cachetable;
|
||||
{
|
||||
PAIR p = ct->list.find_pair(cachefile, key, fullhash);
|
||||
if (p != NULL) {
|
||||
// Ideally, we would like to just assert(false) here
|
||||
// and not return an error, but as of Dr. Noga,
|
||||
// cachetable-test2 depends on this behavior.
|
||||
// To replace the following with an assert(false)
|
||||
// we need to change the behavior of cachetable-test2
|
||||
//
|
||||
// Semantically, these two asserts are not strictly right. After all, when are two functions eq?
|
||||
// In practice, the functions better be the same.
|
||||
assert(p->flush_callback == write_callback.flush_callback);
|
||||
assert(p->pe_callback == write_callback.pe_callback);
|
||||
assert(p->cleaner_callback == write_callback.cleaner_callback);
|
||||
return -1; /* Already present, don't grab lock. */
|
||||
}
|
||||
}
|
||||
PAIR p = ct->list.find_pair(cachefile, key, fullhash);
|
||||
invariant_null(p);
|
||||
|
||||
// flushing could change the table size, but wont' change the fullhash
|
||||
cachetable_puts++;
|
||||
PAIR p = cachetable_insert_at(
|
||||
p = cachetable_insert_at(
|
||||
ct,
|
||||
cachefile,
|
||||
key,
|
||||
|
@ -872,7 +851,6 @@ static int cachetable_put_internal(
|
|||
//note_hash_count(count);
|
||||
invariant_notnull(put_callback);
|
||||
put_callback(value, p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Pair mutex (p->mutex) is may or may not be held on entry,
|
||||
|
@ -1090,10 +1068,10 @@ static void get_pairs(
|
|||
}
|
||||
}
|
||||
|
||||
int toku_cachetable_put_with_dep_pairs(
|
||||
void toku_cachetable_put_with_dep_pairs(
|
||||
CACHEFILE cachefile,
|
||||
CACHETABLE_GET_KEY_AND_FULLHASH get_key_and_fullhash,
|
||||
void*value,
|
||||
void *value,
|
||||
PAIR_ATTR attr,
|
||||
CACHETABLE_WRITE_CALLBACK write_callback,
|
||||
void *get_key_and_fullhash_extra,
|
||||
|
@ -1117,54 +1095,49 @@ int toku_cachetable_put_with_dep_pairs(
|
|||
if (ct->ev.should_client_wake_eviction_thread()) {
|
||||
ct->ev.signal_eviction_thread();
|
||||
}
|
||||
int rval;
|
||||
{
|
||||
ct->list.write_list_lock();
|
||||
get_key_and_fullhash(key, fullhash, get_key_and_fullhash_extra);
|
||||
rval = cachetable_put_internal(
|
||||
cachefile,
|
||||
*key,
|
||||
*fullhash,
|
||||
value,
|
||||
attr,
|
||||
write_callback,
|
||||
put_callback
|
||||
);
|
||||
PAIR dependent_pairs[num_dependent_pairs];
|
||||
get_pairs(
|
||||
&ct->list,
|
||||
num_dependent_pairs,
|
||||
dependent_cfs,
|
||||
dependent_keys,
|
||||
dependent_fullhash,
|
||||
dependent_pairs
|
||||
);
|
||||
bool checkpoint_pending[num_dependent_pairs];
|
||||
ct->list.write_pending_cheap_lock();
|
||||
for (uint32_t i = 0; i < num_dependent_pairs; i++) {
|
||||
checkpoint_pending[i] = dependent_pairs[i]->checkpoint_pending;
|
||||
dependent_pairs[i]->checkpoint_pending = false;
|
||||
}
|
||||
ct->list.write_pending_cheap_unlock();
|
||||
ct->list.write_list_unlock();
|
||||
|
||||
//
|
||||
// now that we have inserted the row, let's checkpoint the
|
||||
// dependent nodes, if they need checkpointing
|
||||
//
|
||||
checkpoint_dependent_pairs(
|
||||
ct,
|
||||
num_dependent_pairs,
|
||||
dependent_pairs,
|
||||
checkpoint_pending,
|
||||
dependent_dirty
|
||||
);
|
||||
ct->list.write_list_lock();
|
||||
get_key_and_fullhash(key, fullhash, get_key_and_fullhash_extra);
|
||||
cachetable_put_internal(
|
||||
cachefile,
|
||||
*key,
|
||||
*fullhash,
|
||||
value,
|
||||
attr,
|
||||
write_callback,
|
||||
put_callback
|
||||
);
|
||||
PAIR dependent_pairs[num_dependent_pairs];
|
||||
get_pairs(
|
||||
&ct->list,
|
||||
num_dependent_pairs,
|
||||
dependent_cfs,
|
||||
dependent_keys,
|
||||
dependent_fullhash,
|
||||
dependent_pairs
|
||||
);
|
||||
bool checkpoint_pending[num_dependent_pairs];
|
||||
ct->list.write_pending_cheap_lock();
|
||||
for (uint32_t i = 0; i < num_dependent_pairs; i++) {
|
||||
checkpoint_pending[i] = dependent_pairs[i]->checkpoint_pending;
|
||||
dependent_pairs[i]->checkpoint_pending = false;
|
||||
}
|
||||
return rval;
|
||||
ct->list.write_pending_cheap_unlock();
|
||||
ct->list.write_list_unlock();
|
||||
|
||||
//
|
||||
// now that we have inserted the row, let's checkpoint the
|
||||
// dependent nodes, if they need checkpointing
|
||||
//
|
||||
checkpoint_dependent_pairs(
|
||||
ct,
|
||||
num_dependent_pairs,
|
||||
dependent_pairs,
|
||||
checkpoint_pending,
|
||||
dependent_dirty
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
int toku_cachetable_put(CACHEFILE cachefile, CACHEKEY key, uint32_t fullhash, void*value, PAIR_ATTR attr,
|
||||
void toku_cachetable_put(CACHEFILE cachefile, CACHEKEY key, uint32_t fullhash, void*value, PAIR_ATTR attr,
|
||||
CACHETABLE_WRITE_CALLBACK write_callback,
|
||||
CACHETABLE_PUT_CALLBACK put_callback
|
||||
) {
|
||||
|
@ -1176,7 +1149,7 @@ int toku_cachetable_put(CACHEFILE cachefile, CACHEKEY key, uint32_t fullhash, vo
|
|||
ct->ev.signal_eviction_thread();
|
||||
}
|
||||
ct->list.write_list_lock();
|
||||
int r = cachetable_put_internal(
|
||||
cachetable_put_internal(
|
||||
cachefile,
|
||||
key,
|
||||
fullhash,
|
||||
|
@ -1186,7 +1159,6 @@ int toku_cachetable_put(CACHEFILE cachefile, CACHEKEY key, uint32_t fullhash, vo
|
|||
put_callback
|
||||
);
|
||||
ct->list.write_list_unlock();
|
||||
return r;
|
||||
}
|
||||
|
||||
static uint64_t get_tnow(void) {
|
||||
|
@ -2560,21 +2532,14 @@ toku_cachetable_minicron_shutdown(CACHETABLE ct) {
|
|||
ct->cl.destroy();
|
||||
}
|
||||
|
||||
/* Require that it all be flushed. */
|
||||
int
|
||||
toku_cachetable_close (CACHETABLE *ctp) {
|
||||
int r = 0;
|
||||
CACHETABLE ct=*ctp;
|
||||
/* Requires that it all be flushed. */
|
||||
void toku_cachetable_close (CACHETABLE *ctp) {
|
||||
CACHETABLE ct = *ctp;
|
||||
ct->cp.destroy();
|
||||
ct->cl.destroy();
|
||||
cachetable_flush_cachefile(ct, NULL);
|
||||
ct->ev.destroy();
|
||||
r = ct->list.destroy();
|
||||
if (r != 0) {
|
||||
// This means that there were still pairs in the
|
||||
// pair list, which is bad.
|
||||
return -1;
|
||||
}
|
||||
ct->list.destroy();
|
||||
ct->cf_list.destroy();
|
||||
|
||||
toku_kibbutz_destroy(ct->client_kibbutz);
|
||||
|
@ -2583,7 +2548,6 @@ toku_cachetable_close (CACHETABLE *ctp) {
|
|||
toku_free(ct->env_dir);
|
||||
toku_free(ct);
|
||||
*ctp = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PAIR test_get_pair(CACHEFILE cachefile, CACHEKEY key, uint32_t fullhash, bool have_ct_lock) {
|
||||
|
@ -2775,35 +2739,33 @@ int log_open_txn (const TOKUTXN &txn, const uint32_t UU(index), checkpointer * c
|
|||
invariant(r==0);
|
||||
switch (toku_txn_get_state(txn)) {
|
||||
case TOKUTXN_LIVE:{
|
||||
r = toku_log_xstillopen(logger, NULL, 0, txn,
|
||||
toku_txn_get_txnid(txn),
|
||||
toku_txn_get_txnid(toku_logger_txn_parent(txn)),
|
||||
txn->roll_info.rollentry_raw_count,
|
||||
open_filenums,
|
||||
txn->force_fsync_on_commit,
|
||||
txn->roll_info.num_rollback_nodes,
|
||||
txn->roll_info.num_rollentries,
|
||||
txn->roll_info.spilled_rollback_head,
|
||||
txn->roll_info.spilled_rollback_tail,
|
||||
txn->roll_info.current_rollback);
|
||||
lazy_assert_zero(r);
|
||||
toku_log_xstillopen(logger, NULL, 0, txn,
|
||||
toku_txn_get_txnid(txn),
|
||||
toku_txn_get_txnid(toku_logger_txn_parent(txn)),
|
||||
txn->roll_info.rollentry_raw_count,
|
||||
open_filenums,
|
||||
txn->force_fsync_on_commit,
|
||||
txn->roll_info.num_rollback_nodes,
|
||||
txn->roll_info.num_rollentries,
|
||||
txn->roll_info.spilled_rollback_head,
|
||||
txn->roll_info.spilled_rollback_tail,
|
||||
txn->roll_info.current_rollback);
|
||||
goto cleanup;
|
||||
}
|
||||
case TOKUTXN_PREPARING: {
|
||||
TOKU_XA_XID xa_xid;
|
||||
toku_txn_get_prepared_xa_xid(txn, &xa_xid);
|
||||
r = toku_log_xstillopenprepared(logger, NULL, 0, txn,
|
||||
toku_txn_get_txnid(txn),
|
||||
&xa_xid,
|
||||
txn->roll_info.rollentry_raw_count,
|
||||
open_filenums,
|
||||
txn->force_fsync_on_commit,
|
||||
txn->roll_info.num_rollback_nodes,
|
||||
txn->roll_info.num_rollentries,
|
||||
txn->roll_info.spilled_rollback_head,
|
||||
txn->roll_info.spilled_rollback_tail,
|
||||
txn->roll_info.current_rollback);
|
||||
lazy_assert_zero(r);
|
||||
toku_log_xstillopenprepared(logger, NULL, 0, txn,
|
||||
toku_txn_get_txnid(txn),
|
||||
&xa_xid,
|
||||
txn->roll_info.rollentry_raw_count,
|
||||
open_filenums,
|
||||
txn->force_fsync_on_commit,
|
||||
txn->roll_info.num_rollback_nodes,
|
||||
txn->roll_info.num_rollentries,
|
||||
txn->roll_info.spilled_rollback_head,
|
||||
txn->roll_info.spilled_rollback_tail,
|
||||
txn->roll_info.current_rollback);
|
||||
goto cleanup;
|
||||
}
|
||||
case TOKUTXN_RETIRED:
|
||||
|
@ -2823,9 +2785,8 @@ cleanup:
|
|||
// Use the begin_checkpoint callback to take necessary snapshots (header, btt)
|
||||
// Mark every dirty node as "pending." ("Pending" means that the node must be
|
||||
// written to disk before it can be modified.)
|
||||
int
|
||||
toku_cachetable_begin_checkpoint (CHECKPOINTER cp, TOKULOGGER UU(logger)) {
|
||||
return cp->begin_checkpoint();
|
||||
void toku_cachetable_begin_checkpoint (CHECKPOINTER cp, TOKULOGGER UU(logger)) {
|
||||
cp->begin_checkpoint();
|
||||
}
|
||||
|
||||
|
||||
|
@ -2843,10 +2804,9 @@ int toku_cachetable_get_checkpointing_user_data_status (void) {
|
|||
// Use checkpoint callback to write snapshot information to disk (header, btt)
|
||||
// Use end_checkpoint callback to fsync dictionary and log, and to free unused blocks
|
||||
// Note: If testcallback is null (for testing purposes only), call it after writing dictionary but before writing log
|
||||
int
|
||||
toku_cachetable_end_checkpoint(CHECKPOINTER cp, TOKULOGGER UU(logger),
|
||||
void toku_cachetable_end_checkpoint(CHECKPOINTER cp, TOKULOGGER UU(logger),
|
||||
void (*testcallback_f)(void*), void* testextra) {
|
||||
return cp->end_checkpoint(testcallback_f, testextra);
|
||||
cp->end_checkpoint(testcallback_f, testextra);
|
||||
}
|
||||
|
||||
TOKULOGGER toku_cachefile_logger (CACHEFILE cf) {
|
||||
|
@ -2958,14 +2918,14 @@ int toku_cachetable_get_key_state (CACHETABLE ct, CACHEKEY key, CACHEFILE cf, vo
|
|||
void
|
||||
toku_cachefile_set_userdata (CACHEFILE cf,
|
||||
void *userdata,
|
||||
int (*log_fassociate_during_checkpoint)(CACHEFILE, void*),
|
||||
int (*log_suppress_rollback_during_checkpoint)(CACHEFILE, void*),
|
||||
int (*close_userdata)(CACHEFILE, int, void*, char**, bool, LSN),
|
||||
void (*log_fassociate_during_checkpoint)(CACHEFILE, void*),
|
||||
void (*log_suppress_rollback_during_checkpoint)(CACHEFILE, void*),
|
||||
int (*close_userdata)(CACHEFILE, int, void*, bool, LSN),
|
||||
int (*checkpoint_userdata)(CACHEFILE, int, void*),
|
||||
int (*begin_checkpoint_userdata)(LSN, void*),
|
||||
int (*end_checkpoint_userdata)(CACHEFILE, int, void*),
|
||||
int (*note_pin_by_checkpoint)(CACHEFILE, void*),
|
||||
int (*note_unpin_by_checkpoint)(CACHEFILE, void*)) {
|
||||
void (*begin_checkpoint_userdata)(LSN, void*),
|
||||
void (*end_checkpoint_userdata)(CACHEFILE, int, void*),
|
||||
void (*note_pin_by_checkpoint)(CACHEFILE, void*),
|
||||
void (*note_unpin_by_checkpoint)(CACHEFILE, void*)) {
|
||||
cf->userdata = userdata;
|
||||
cf->log_fassociate_during_checkpoint = log_fassociate_during_checkpoint;
|
||||
cf->log_suppress_rollback_during_checkpoint = log_suppress_rollback_during_checkpoint;
|
||||
|
@ -2988,23 +2948,18 @@ toku_cachefile_get_cachetable(CACHEFILE cf) {
|
|||
|
||||
//Only called by ft_end_checkpoint
|
||||
//Must have access to cf->fd (must be protected)
|
||||
int
|
||||
toku_cachefile_fsync(CACHEFILE cf) {
|
||||
int r;
|
||||
r = toku_file_fsync(cf->fd);
|
||||
return r;
|
||||
void toku_cachefile_fsync(CACHEFILE cf) {
|
||||
toku_file_fsync(cf->fd);
|
||||
}
|
||||
|
||||
// Make it so when the cachefile closes, the underlying file is unlinked
|
||||
void
|
||||
toku_cachefile_unlink_on_close(CACHEFILE cf) {
|
||||
void toku_cachefile_unlink_on_close(CACHEFILE cf) {
|
||||
assert(!cf->unlink_on_close);
|
||||
cf->unlink_on_close = true;
|
||||
}
|
||||
|
||||
// is this cachefile marked as unlink on close?
|
||||
bool
|
||||
toku_cachefile_is_unlink_on_close(CACHEFILE cf) {
|
||||
bool toku_cachefile_is_unlink_on_close(CACHEFILE cf) {
|
||||
return cf->unlink_on_close;
|
||||
}
|
||||
|
||||
|
@ -3105,8 +3060,7 @@ uint32_t cleaner::get_period_unlocked(void) {
|
|||
}
|
||||
|
||||
void cleaner::set_period(uint32_t new_period) {
|
||||
int r = toku_minicron_change_period(&m_cleaner_cron, new_period);
|
||||
assert_zero(r);
|
||||
toku_minicron_change_period(&m_cleaner_cron, new_period);
|
||||
}
|
||||
|
||||
// Effect: runs a cleaner.
|
||||
|
@ -3274,18 +3228,15 @@ void pair_list::init() {
|
|||
// Frees the pair_list hash table. It is expected to be empty by
|
||||
// the time this is called. Returns an error if there are any
|
||||
// pairs in any of the hash table slots.
|
||||
int pair_list::destroy() {
|
||||
void pair_list::destroy() {
|
||||
// Check if any entries exist in the hash table.
|
||||
for (uint32_t i = 0; i < m_table_size; ++i) {
|
||||
if (m_table[i]) {
|
||||
return -1;
|
||||
}
|
||||
invariant_null(m_table[i]);
|
||||
}
|
||||
toku_pthread_rwlock_destroy(&m_list_lock);
|
||||
toku_pthread_rwlock_destroy(&m_pending_lock_expensive);
|
||||
toku_pthread_rwlock_destroy(&m_pending_lock_cheap);
|
||||
toku_free(m_table);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This places the given pair inside of the pair list.
|
||||
|
@ -4206,8 +4157,8 @@ void checkpointer::destroy() {
|
|||
//
|
||||
// Sets how often the checkpoint thread will run.
|
||||
//
|
||||
int checkpointer::set_checkpoint_period(uint32_t new_period) {
|
||||
return toku_minicron_change_period(&m_checkpointer_cron, new_period);
|
||||
void checkpointer::set_checkpoint_period(uint32_t new_period) {
|
||||
toku_minicron_change_period(&m_checkpointer_cron, new_period);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -4243,14 +4194,12 @@ void checkpointer::increment_num_txns() {
|
|||
// Update the user data in any cachefiles in our checkpoint list.
|
||||
//
|
||||
void checkpointer::update_cachefiles() {
|
||||
int r = 0;
|
||||
CACHEFILE cf;
|
||||
for(cf = m_cf_list->m_head; cf; cf=cf->next) {
|
||||
assert(cf->begin_checkpoint_userdata);
|
||||
if (cf->for_checkpoint) {
|
||||
r = cf->begin_checkpoint_userdata(m_lsn_of_checkpoint_in_progress,
|
||||
cf->begin_checkpoint_userdata(m_lsn_of_checkpoint_in_progress,
|
||||
cf->userdata);
|
||||
assert(r == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4258,9 +4207,8 @@ void checkpointer::update_cachefiles() {
|
|||
//
|
||||
// Sets up and kicks off a checkpoint.
|
||||
//
|
||||
int checkpointer::begin_checkpoint() {
|
||||
void checkpointer::begin_checkpoint() {
|
||||
// 1. Initialize the accountability counters.
|
||||
int r = 0;
|
||||
m_checkpoint_num_files = 0;
|
||||
m_checkpoint_num_txns = 0;
|
||||
|
||||
|
@ -4275,8 +4223,7 @@ int checkpointer::begin_checkpoint() {
|
|||
// Putting this check here so that this method may be called
|
||||
// by cachetable tests.
|
||||
assert(cf->note_pin_by_checkpoint);
|
||||
r = cf->note_pin_by_checkpoint(cf, cf->userdata);
|
||||
assert(r == 0);
|
||||
cf->note_pin_by_checkpoint(cf, cf->userdata);
|
||||
cf->for_checkpoint = true;
|
||||
m_checkpoint_num_files++;
|
||||
}
|
||||
|
@ -4302,7 +4249,6 @@ int checkpointer::begin_checkpoint() {
|
|||
m_cf_list->read_unlock();
|
||||
m_list->read_list_unlock();
|
||||
m_list->write_pending_exp_unlock();
|
||||
return r;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -4324,15 +4270,13 @@ void checkpointer::log_begin_checkpoint() {
|
|||
LSN begin_lsn={ .lsn = (uint64_t) -1 }; // we'll need to store the lsn of the checkpoint begin in all the trees that are checkpointed.
|
||||
TXN_MANAGER mgr = toku_logger_get_txn_manager(m_logger);
|
||||
TXNID last_xid = toku_txn_manager_get_last_xid(mgr);
|
||||
r = toku_log_begin_checkpoint(m_logger, &begin_lsn, 0, 0, last_xid);
|
||||
assert(r==0);
|
||||
toku_log_begin_checkpoint(m_logger, &begin_lsn, 0, 0, last_xid);
|
||||
m_lsn_of_checkpoint_in_progress = begin_lsn;
|
||||
|
||||
// Log the list of open dictionaries.
|
||||
for (CACHEFILE cf = m_cf_list->m_head; cf; cf = cf->next) {
|
||||
assert(cf->log_fassociate_during_checkpoint);
|
||||
r = cf->log_fassociate_during_checkpoint(cf, cf->userdata);
|
||||
assert(r == 0);
|
||||
cf->log_fassociate_during_checkpoint(cf, cf->userdata);
|
||||
}
|
||||
|
||||
// Write open transactions to the log.
|
||||
|
@ -4345,8 +4289,7 @@ void checkpointer::log_begin_checkpoint() {
|
|||
// rollback logs suppressed.
|
||||
for (CACHEFILE cf = m_cf_list->m_head; cf; cf = cf->next) {
|
||||
assert(cf->log_suppress_rollback_during_checkpoint);
|
||||
r = cf->log_suppress_rollback_during_checkpoint(cf, cf->userdata);
|
||||
assert(r == 0);
|
||||
cf->log_suppress_rollback_during_checkpoint(cf, cf->userdata);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4396,8 +4339,7 @@ void checkpointer::remove_background_job() {
|
|||
bjm_remove_background_job(m_checkpoint_clones_bjm);
|
||||
}
|
||||
|
||||
int checkpointer::end_checkpoint(void (*testcallback_f)(void*), void* testextra) {
|
||||
int r = 0;
|
||||
void checkpointer::end_checkpoint(void (*testcallback_f)(void*), void* testextra) {
|
||||
CACHEFILE *XMALLOC_N(m_checkpoint_num_files, checkpoint_cfs);
|
||||
|
||||
this->fill_checkpoint_cfs(checkpoint_cfs);
|
||||
|
@ -4411,9 +4353,8 @@ int checkpointer::end_checkpoint(void (*testcallback_f)(void*), void* testextra
|
|||
this->end_checkpoint_userdata(checkpoint_cfs);
|
||||
|
||||
//Delete list of cachefiles in the checkpoint,
|
||||
r = this->remove_cachefiles(checkpoint_cfs);
|
||||
this->remove_cachefiles(checkpoint_cfs);
|
||||
toku_free(checkpoint_cfs);
|
||||
return r;
|
||||
}
|
||||
|
||||
void checkpointer::fill_checkpoint_cfs(CACHEFILE* checkpoint_cfs) {
|
||||
|
@ -4464,13 +4405,12 @@ void checkpointer::checkpoint_userdata(CACHEFILE* checkpoint_cfs) {
|
|||
|
||||
void checkpointer::log_end_checkpoint() {
|
||||
if (m_logger) {
|
||||
int r = toku_log_end_checkpoint(m_logger, NULL,
|
||||
1, // want the end_checkpoint to be fsync'd
|
||||
m_lsn_of_checkpoint_in_progress,
|
||||
0,
|
||||
m_checkpoint_num_files,
|
||||
m_checkpoint_num_txns);
|
||||
assert(r==0);
|
||||
toku_log_end_checkpoint(m_logger, NULL,
|
||||
1, // want the end_checkpoint to be fsync'd
|
||||
m_lsn_of_checkpoint_in_progress,
|
||||
0,
|
||||
m_checkpoint_num_files,
|
||||
m_checkpoint_num_txns);
|
||||
toku_logger_note_checkpoint(m_logger, m_lsn_of_checkpoint_in_progress);
|
||||
}
|
||||
}
|
||||
|
@ -4484,16 +4424,14 @@ void checkpointer::end_checkpoint_userdata(CACHEFILE* checkpoint_cfs) {
|
|||
CACHEFILE cf = checkpoint_cfs[i];
|
||||
assert(cf->for_checkpoint);
|
||||
assert(cf->end_checkpoint_userdata);
|
||||
int r = cf->end_checkpoint_userdata(cf, cf->fd, cf->userdata);
|
||||
assert(r==0);
|
||||
cf->end_checkpoint_userdata(cf, cf->fd, cf->userdata);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Deletes all the cachefiles in this checkpointers cachefile list.
|
||||
//
|
||||
int checkpointer::remove_cachefiles(CACHEFILE* checkpoint_cfs) {
|
||||
int r = 0;
|
||||
void checkpointer::remove_cachefiles(CACHEFILE* checkpoint_cfs) {
|
||||
// making this a while loop because note_unpin_by_checkpoint may destroy the cachefile
|
||||
for (uint32_t i = 0; i < m_checkpoint_num_files; i++) {
|
||||
CACHEFILE cf = checkpoint_cfs[i];
|
||||
|
@ -4503,12 +4441,8 @@ int checkpointer::remove_cachefiles(CACHEFILE* checkpoint_cfs) {
|
|||
cf->for_checkpoint = false;
|
||||
assert(cf->note_unpin_by_checkpoint);
|
||||
// Clear the bit saying theis file is in the checkpoint.
|
||||
r = cf->note_unpin_by_checkpoint(cf, cf->userdata);
|
||||
if (r != 0) {
|
||||
return r;
|
||||
}
|
||||
cf->note_unpin_by_checkpoint(cf, cf->userdata);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "fttypes.h"
|
||||
#include "minicron.h"
|
||||
|
||||
|
||||
// Maintain a cache mapping from cachekeys to values (void*)
|
||||
// Some of the keys can be pinned. Don't pin too many or for too long.
|
||||
// If the cachetable is too full, it will call the flush_callback() function with the key, the value, and the otherargs
|
||||
|
@ -27,10 +26,10 @@
|
|||
|
||||
typedef BLOCKNUM CACHEKEY;
|
||||
|
||||
int toku_set_cleaner_period (CACHETABLE ct, uint32_t new_period);
|
||||
void toku_set_cleaner_period (CACHETABLE ct, uint32_t new_period);
|
||||
uint32_t toku_get_cleaner_period (CACHETABLE ct);
|
||||
uint32_t toku_get_cleaner_period_unlocked (CACHETABLE ct);
|
||||
int toku_set_cleaner_iterations (CACHETABLE ct, uint32_t new_iterations);
|
||||
void toku_set_cleaner_iterations (CACHETABLE ct, uint32_t new_iterations);
|
||||
uint32_t toku_get_cleaner_iterations (CACHETABLE ct);
|
||||
uint32_t toku_get_cleaner_iterations_unlocked (CACHETABLE ct);
|
||||
|
||||
|
@ -39,7 +38,7 @@ uint32_t toku_get_cleaner_iterations_unlocked (CACHETABLE ct);
|
|||
// create and initialize a cache table
|
||||
// size_limit is the upper limit on the size of the size of the values in the table
|
||||
// pass 0 if you want the default
|
||||
int toku_create_cachetable(CACHETABLE *result, long size_limit, LSN initial_lsn, TOKULOGGER);
|
||||
void toku_cachetable_create(CACHETABLE *result, long size_limit, LSN initial_lsn, TOKULOGGER);
|
||||
|
||||
// Create a new cachetable.
|
||||
// Effects: a new cachetable is created and initialized.
|
||||
|
@ -62,11 +61,11 @@ int toku_cachefile_of_iname_in_env (CACHETABLE ct, const char *iname_in_env, CAC
|
|||
|
||||
// Get the iname (within the cwd) associated with the cachefile
|
||||
// Return the filename
|
||||
char * toku_cachefile_fname_in_cwd (CACHEFILE cf);
|
||||
char *toku_cachefile_fname_in_cwd (CACHEFILE cf);
|
||||
|
||||
// TODO: #1510 Add comments on how these behave
|
||||
int toku_cachetable_begin_checkpoint (CHECKPOINTER cp, TOKULOGGER);
|
||||
int toku_cachetable_end_checkpoint(CHECKPOINTER cp, TOKULOGGER logger,
|
||||
void toku_cachetable_begin_checkpoint (CHECKPOINTER cp, TOKULOGGER);
|
||||
|
||||
void toku_cachetable_end_checkpoint(CHECKPOINTER cp, TOKULOGGER logger,
|
||||
void (*testcallback_f)(void*), void * testextra);
|
||||
|
||||
// Shuts down checkpoint thread
|
||||
|
@ -75,15 +74,15 @@ void toku_cachetable_minicron_shutdown(CACHETABLE ct);
|
|||
|
||||
// Close the cachetable.
|
||||
// Effects: All of the memory objects are flushed to disk, and the cachetable is destroyed.
|
||||
int toku_cachetable_close (CACHETABLE*); /* Flushes everything to disk, and destroys the cachetable. */
|
||||
void toku_cachetable_close(CACHETABLE *ct);
|
||||
|
||||
// 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*/, 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)*/
|
||||
int toku_cachetable_openfd_with_filenum (CACHEFILE *,CACHETABLE, int /*fd*/,
|
||||
int toku_cachetable_openfd(CACHEFILE *,CACHETABLE, int fd,
|
||||
const char *fname_relative_to_env);
|
||||
int toku_cachetable_openfd_with_filenum (CACHEFILE *,CACHETABLE, int fd,
|
||||
const char *fname_in_env,
|
||||
FILENUM filenum);
|
||||
|
||||
|
@ -100,8 +99,7 @@ void toku_cachetable_release_reserved_memory(CACHETABLE, uint64_t);
|
|||
// cachefile operations
|
||||
|
||||
// Does an fsync of a cachefile.
|
||||
// Handles the case where cf points to /dev/null
|
||||
int toku_cachefile_fsync(CACHEFILE cf);
|
||||
void toku_cachefile_fsync(CACHEFILE cf);
|
||||
|
||||
enum partial_eviction_cost {
|
||||
PE_CHEAP=0, // running partial eviction is cheap, and can be done on the client thread
|
||||
|
@ -189,14 +187,14 @@ typedef void (*CACHETABLE_GET_KEY_AND_FULLHASH)(CACHEKEY* cachekey, uint32_t* fu
|
|||
typedef void (*CACHETABLE_REMOVE_KEY)(CACHEKEY* cachekey, bool for_checkpoint, void* extra);
|
||||
|
||||
void toku_cachefile_set_userdata(CACHEFILE cf, void *userdata,
|
||||
int (*log_fassociate_during_checkpoint)(CACHEFILE, void*),
|
||||
int (*log_suppress_rollback_during_checkpoint)(CACHEFILE, void*),
|
||||
int (*close_userdata)(CACHEFILE, int, void*, char **/*error_string*/, bool, LSN),
|
||||
void (*log_fassociate_during_checkpoint)(CACHEFILE, void*),
|
||||
void (*log_suppress_rollback_during_checkpoint)(CACHEFILE, void*),
|
||||
int (*close_userdata)(CACHEFILE, int, void*, bool, LSN),
|
||||
int (*checkpoint_userdata)(CACHEFILE, int, void*),
|
||||
int (*begin_checkpoint_userdata)(LSN, void*),
|
||||
int (*end_checkpoint_userdata)(CACHEFILE, int, void*),
|
||||
int (*note_pin_by_checkpoint)(CACHEFILE, void*),
|
||||
int (*note_unpin_by_checkpoint)(CACHEFILE, void*));
|
||||
void (*begin_checkpoint_userdata)(LSN, void*),
|
||||
void (*end_checkpoint_userdata)(CACHEFILE, int, void*),
|
||||
void (*note_pin_by_checkpoint)(CACHEFILE, void*),
|
||||
void (*note_unpin_by_checkpoint)(CACHEFILE, void*));
|
||||
// Effect: Store some cachefile-specific user data. When the last reference to a cachefile is closed, we call close_userdata().
|
||||
// Before starting a checkpoint, we call checkpoint_prepare_userdata().
|
||||
// When the cachefile needs to be checkpointed, we call checkpoint_userdata().
|
||||
|
@ -220,10 +218,10 @@ typedef enum {
|
|||
|
||||
// put something into the cachetable and checkpoint dependent pairs
|
||||
// if the checkpointing is necessary
|
||||
int toku_cachetable_put_with_dep_pairs(
|
||||
void toku_cachetable_put_with_dep_pairs(
|
||||
CACHEFILE cachefile,
|
||||
CACHETABLE_GET_KEY_AND_FULLHASH get_key_and_fullhash,
|
||||
void*value,
|
||||
void *value,
|
||||
PAIR_ATTR attr,
|
||||
CACHETABLE_WRITE_CALLBACK write_callback,
|
||||
void *get_key_and_fullhash_extra,
|
||||
|
@ -241,9 +239,7 @@ int toku_cachetable_put_with_dep_pairs(
|
|||
// Effects: Lookup the key in the cachetable. If the key is not in the cachetable,
|
||||
// then insert the pair and pin it. Otherwise return an error. Some of the key
|
||||
// value pairs may be evicted from the cachetable when the cachetable gets too big.
|
||||
// Returns: 0 if the memory object is placed into the cachetable, otherwise an
|
||||
// error number.
|
||||
int toku_cachetable_put(CACHEFILE cf, CACHEKEY key, uint32_t fullhash,
|
||||
void toku_cachetable_put(CACHEFILE cf, CACHEKEY key, uint32_t fullhash,
|
||||
void *value, PAIR_ATTR size,
|
||||
CACHETABLE_WRITE_CALLBACK write_callback,
|
||||
CACHETABLE_PUT_CALLBACK put_callback
|
||||
|
@ -386,8 +382,6 @@ int toku_cachetable_get_and_pin_nonblocking (
|
|||
UNLOCKERS unlockers
|
||||
);
|
||||
|
||||
#define CAN_RELEASE_LOCK_DURING_IO
|
||||
|
||||
int toku_cachetable_maybe_get_and_pin (CACHEFILE, CACHEKEY, uint32_t /*fullhash*/, void**);
|
||||
// Effect: Maybe get and pin a memory object.
|
||||
// This function is similar to the get_and_pin function except that it
|
||||
|
@ -459,13 +453,13 @@ int toku_cachefile_count_pinned (CACHEFILE, int /*printthem*/ );
|
|||
// object is freed.
|
||||
// If oplsn_valid is true then use oplsn as the LSN of the close instead of asking the logger. oplsn_valid being true is only allowed during recovery, and requires that you are removing the last reference (otherwise the lsn wouldn't make it in.)
|
||||
// Returns: 0 if success, otherwise returns an error number.
|
||||
int toku_cachefile_close (CACHEFILE*, char **error_string, bool oplsn_valid, LSN oplsn);
|
||||
int toku_cachefile_close (CACHEFILE*, bool oplsn_valid, LSN oplsn);
|
||||
|
||||
// Flush the cachefile.
|
||||
// Effect: Flush everything owned by the cachefile from the cachetable. All dirty
|
||||
// blocks are written. All unpinned blocks are evicted from the cachetable.
|
||||
// Returns: 0 if success, otherwise returns an error number.
|
||||
int toku_cachefile_flush (CACHEFILE);
|
||||
void toku_cachefile_flush(CACHEFILE);
|
||||
|
||||
// Return on success (different from pread and pwrite)
|
||||
//int cachefile_pwrite (CACHEFILE, const void *buf, size_t count, toku_off_t offset);
|
||||
|
@ -527,8 +521,6 @@ void toku_cachetable_verify (CACHETABLE t);
|
|||
// Not for use in production, but useful for testing.
|
||||
void toku_cachetable_print_hash_histogram (void) __attribute__((__visibility__("default")));
|
||||
|
||||
#define TOKU_CACHETABLE_DO_EVICT_FROM_WRITER 0
|
||||
|
||||
void toku_cachetable_maybe_flush_some(CACHETABLE ct);
|
||||
|
||||
// for stat64
|
||||
|
@ -572,11 +564,10 @@ void remove_background_job_from_cf (CACHEFILE cf);
|
|||
// the cachetable must be notified.
|
||||
|
||||
// test-only function
|
||||
extern int toku_cachetable_get_checkpointing_user_data_status(void);
|
||||
int toku_cachetable_get_checkpointing_user_data_status(void);
|
||||
|
||||
// test-only function
|
||||
int toku_cleaner_thread_for_test (CACHETABLE ct);
|
||||
int toku_cleaner_thread (void *cleaner_v);
|
||||
int toku_cleaner_thread_for_test(CACHETABLE ct);
|
||||
int toku_cleaner_thread(void *cleaner_v);
|
||||
|
||||
|
||||
#endif
|
||||
#endif /* CACHETABLE_H */
|
||||
|
|
|
@ -222,7 +222,7 @@ toku_checkpoint(CHECKPOINTER cp, TOKULOGGER logger,
|
|||
void (*callback_f)(void*), void * extra,
|
||||
void (*callback2_f)(void*), void * extra2,
|
||||
checkpoint_caller_t caller_id) {
|
||||
int r;
|
||||
int r = 0;
|
||||
int footprint_offset = (int) caller_id * 1000;
|
||||
|
||||
assert(initialized);
|
||||
|
@ -241,7 +241,7 @@ toku_checkpoint(CHECKPOINTER cp, TOKULOGGER logger,
|
|||
|
||||
SET_CHECKPOINT_FOOTPRINT(30);
|
||||
STATUS_VALUE(CP_TIME_LAST_CHECKPOINT_BEGIN) = time(NULL);
|
||||
r = toku_cachetable_begin_checkpoint(cp, logger);
|
||||
toku_cachetable_begin_checkpoint(cp, logger);
|
||||
|
||||
toku_ft_open_close_unlock();
|
||||
multi_operation_checkpoint_unlock();
|
||||
|
@ -250,7 +250,7 @@ toku_checkpoint(CHECKPOINTER cp, TOKULOGGER logger,
|
|||
if (r==0) {
|
||||
if (callback_f)
|
||||
callback_f(extra); // callback is called with checkpoint_safe_lock still held
|
||||
r = toku_cachetable_end_checkpoint(cp, logger, callback2_f, extra2);
|
||||
toku_cachetable_end_checkpoint(cp, logger, callback2_f, extra2);
|
||||
}
|
||||
SET_CHECKPOINT_FOOTPRINT(50);
|
||||
if (r==0 && logger) {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#ident "$Id$"
|
||||
|
||||
|
||||
int toku_set_checkpoint_period(CACHETABLE ct, uint32_t new_period);
|
||||
void toku_set_checkpoint_period(CACHETABLE ct, uint32_t new_period);
|
||||
//Effect: Change [end checkpoint (n) - begin checkpoint (n+1)] delay to
|
||||
// new_period seconds. 0 means disable.
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ cachetable_put_empty_node_with_dep_nodes(
|
|||
dependent_dirty_bits[i] = (enum cachetable_dirty) dependent_nodes[i]->dirty;
|
||||
}
|
||||
|
||||
int r = toku_cachetable_put_with_dep_pairs(
|
||||
toku_cachetable_put_with_dep_pairs(
|
||||
h->cf,
|
||||
ftnode_get_key_and_fullhash,
|
||||
new_node,
|
||||
|
@ -60,7 +60,6 @@ cachetable_put_empty_node_with_dep_nodes(
|
|||
name,
|
||||
fullhash,
|
||||
toku_node_save_ct_pair);
|
||||
assert_zero(r);
|
||||
*result = new_node;
|
||||
}
|
||||
|
||||
|
|
|
@ -1034,7 +1034,6 @@ flush_this_child(
|
|||
// Effect: Push everything in the CHILDNUMth buffer of node down into the child.
|
||||
{
|
||||
update_flush_status(child, 0);
|
||||
int r;
|
||||
toku_assert_entire_node_in_memory(node);
|
||||
if (fa->should_destroy_basement_nodes(fa)) {
|
||||
maybe_destroy_child_blbs(node, child, h);
|
||||
|
@ -1053,7 +1052,7 @@ flush_this_child(
|
|||
set_BNC(node, childnum, toku_create_empty_nl());
|
||||
|
||||
// now we have a bnc to flush to the child
|
||||
r = toku_bnc_flush_to_child(h, bnc, child); assert_zero(r);
|
||||
toku_bnc_flush_to_child(h, bnc, child);
|
||||
destroy_nonleaf_childinfo(bnc);
|
||||
}
|
||||
|
||||
|
@ -1136,8 +1135,7 @@ merge_leaf_nodes(FTNODE a, FTNODE b)
|
|||
b->n_children = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
balance_leaf_nodes(
|
||||
static void balance_leaf_nodes(
|
||||
FTNODE a,
|
||||
FTNODE b,
|
||||
DBT *splitk)
|
||||
|
@ -1151,8 +1149,6 @@ balance_leaf_nodes(
|
|||
// now split them
|
||||
// because we are not creating a new node, we can pass in no dependent nodes
|
||||
ftleaf_split(NULL, a, &a, &b, splitk, false, 0, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1184,8 +1180,7 @@ maybe_merge_pinned_leaf_nodes(
|
|||
// one is less than 1/4 of a node, and together they are more than 3/4 of a node.
|
||||
toku_free(parent_splitk->data); // We don't need the parent_splitk any more. If we need a splitk (if we don't merge) we'll malloc a new one.
|
||||
*did_rebalance = true;
|
||||
int r = balance_leaf_nodes(a, b, splitk);
|
||||
assert(r==0);
|
||||
balance_leaf_nodes(a, b, splitk);
|
||||
} else {
|
||||
// we are merging them.
|
||||
*did_merge = true;
|
||||
|
@ -1478,7 +1473,6 @@ flush_some_child(
|
|||
call_flusher_thread_callback(flt_flush_before_child_pin);
|
||||
|
||||
// get the child into memory
|
||||
int r;
|
||||
BLOCKNUM targetchild = BP_BLOCKNUM(parent, childnum);
|
||||
toku_verify_blocknum_allocated(h->blocktable, targetchild);
|
||||
uint32_t childfullhash = compute_child_fullhash(h->cf, parent, childnum);
|
||||
|
@ -1557,12 +1551,11 @@ flush_some_child(
|
|||
child->dirty = 1;
|
||||
}
|
||||
// do the actual flush
|
||||
r = toku_bnc_flush_to_child(
|
||||
toku_bnc_flush_to_child(
|
||||
h,
|
||||
bnc,
|
||||
child
|
||||
);
|
||||
assert_zero(r);
|
||||
destroy_nonleaf_childinfo(bnc);
|
||||
}
|
||||
|
||||
|
@ -1736,7 +1729,6 @@ struct flusher_extra {
|
|||
//
|
||||
static void flush_node_fun(void *fe_v)
|
||||
{
|
||||
int r;
|
||||
struct flusher_extra* fe = (struct flusher_extra *) fe_v;
|
||||
// The node that has been placed on the background
|
||||
// thread may not be fully in memory. Some message
|
||||
|
@ -1761,12 +1753,11 @@ static void flush_node_fun(void *fe_v)
|
|||
// for test purposes
|
||||
call_flusher_thread_callback(flt_flush_before_applying_inbox);
|
||||
|
||||
r = toku_bnc_flush_to_child(
|
||||
toku_bnc_flush_to_child(
|
||||
fe->h,
|
||||
fe->bnc,
|
||||
fe->node
|
||||
);
|
||||
assert_zero(r);
|
||||
destroy_nonleaf_childinfo(fe->bnc);
|
||||
|
||||
// after the flush has completed, now check to see if the node needs flushing
|
||||
|
|
|
@ -131,15 +131,10 @@ unsigned int toku_bnc_nbytesinbuf(NONLEAF_CHILDINFO bnc);
|
|||
int toku_bnc_n_entries(NONLEAF_CHILDINFO bnc);
|
||||
long toku_bnc_memory_size(NONLEAF_CHILDINFO bnc);
|
||||
long toku_bnc_memory_used(NONLEAF_CHILDINFO bnc);
|
||||
int toku_bnc_insert_msg(NONLEAF_CHILDINFO bnc, const void *key, ITEMLEN keylen, const void *data, ITEMLEN datalen, enum ft_msg_type type, MSN msn, XIDS xids, bool is_fresh, DESCRIPTOR desc, ft_compare_func cmp);
|
||||
void toku_bnc_insert_msg(NONLEAF_CHILDINFO bnc, const void *key, ITEMLEN keylen, const void *data, ITEMLEN datalen, enum ft_msg_type type, MSN msn, XIDS xids, bool is_fresh, DESCRIPTOR desc, ft_compare_func cmp);
|
||||
void toku_bnc_empty(NONLEAF_CHILDINFO bnc);
|
||||
int toku_bnc_flush_to_child(
|
||||
FT h,
|
||||
NONLEAF_CHILDINFO bnc,
|
||||
FTNODE child
|
||||
);
|
||||
bool
|
||||
toku_ft_nonleaf_is_gorged(FTNODE node, uint32_t nodesize);
|
||||
void toku_bnc_flush_to_child(FT h, NONLEAF_CHILDINFO bnc, FTNODE child);
|
||||
bool toku_ft_nonleaf_is_gorged(FTNODE node, uint32_t nodesize);
|
||||
|
||||
|
||||
enum reactivity get_nonleaf_reactivity (FTNODE node);
|
||||
|
@ -463,11 +458,6 @@ struct ft {
|
|||
// A checkpoint is running. If true, then keep this header around for checkpoint, like a transaction
|
||||
bool pinned_by_checkpoint;
|
||||
|
||||
// If nonzero there was a write error. Don't write any more, because it probably only gets worse. This is the error code.
|
||||
int panic;
|
||||
// A malloced string that can indicate what went wrong.
|
||||
char *panic_string;
|
||||
|
||||
// is this ft a blackhole? if so, all messages are dropped.
|
||||
bool blackhole;
|
||||
};
|
||||
|
@ -550,8 +540,7 @@ deserialize_ft_from_fd_into_rbuf(int fd,
|
|||
int
|
||||
deserialize_ft_versioned(int fd, struct rbuf *rb, FT *ft, uint32_t version);
|
||||
|
||||
int
|
||||
read_block_from_fd_into_rbuf(
|
||||
void read_block_from_fd_into_rbuf(
|
||||
int fd,
|
||||
BLOCKNUM blocknum,
|
||||
FT h,
|
||||
|
@ -582,9 +571,9 @@ unsigned int toku_serialize_ftnode_size(FTNODE node); /* How much space will it
|
|||
|
||||
void toku_verify_or_set_counts(FTNODE);
|
||||
|
||||
int toku_serialize_ft_size (FT_HEADER h);
|
||||
int toku_serialize_ft_to (int fd, FT_HEADER h, BLOCK_TABLE blocktable, CACHEFILE cf);
|
||||
int toku_serialize_ft_to_wbuf (
|
||||
size_t toku_serialize_ft_size (FT_HEADER h);
|
||||
void toku_serialize_ft_to (int fd, FT_HEADER h, BLOCK_TABLE blocktable, CACHEFILE cf);
|
||||
void toku_serialize_ft_to_wbuf (
|
||||
struct wbuf *wbuf,
|
||||
FT_HEADER h,
|
||||
DISKOFF translation_location_on_disk,
|
||||
|
@ -892,8 +881,7 @@ int toku_cmd_leafval_heaviside (OMTVALUE leafentry, void *extra)
|
|||
__attribute__((__warn_unused_result__));
|
||||
|
||||
// toku_ft_root_put_cmd() accepts non-constant cmd because this is where we set the msn
|
||||
int toku_ft_root_put_cmd(FT h, FT_MSG_S * cmd)
|
||||
__attribute__((__warn_unused_result__));
|
||||
void toku_ft_root_put_cmd(FT h, FT_MSG_S * cmd);
|
||||
|
||||
void *mempool_malloc_from_omt(OMT omt, struct mempool *mp, size_t size, void **maybe_free);
|
||||
// Effect: Allocate a new object of size SIZE in MP. If MP runs out of space, allocate new a new mempool space, and copy all the items
|
||||
|
|
349
ft/ft-ops.cc
349
ft/ft-ops.cc
|
@ -329,21 +329,6 @@ uint32_t compute_child_fullhash (CACHEFILE cf, FTNODE node, int childnum) {
|
|||
return toku_cachetable_hash(cf, BP_BLOCKNUM(node, childnum));
|
||||
}
|
||||
|
||||
// TODO: (Zardosht) look into this and possibly fix and use
|
||||
static void __attribute__((__unused__))
|
||||
ft_leaf_check_leaf_stats (FTNODE node)
|
||||
{
|
||||
assert(node);
|
||||
assert(false);
|
||||
// static int count=0; count++;
|
||||
// if (node->height>0) return;
|
||||
// struct subtree_estimates e = calc_leaf_stats(node);
|
||||
// assert(e.ndata == node->u.l.leaf_stats.ndata);
|
||||
// assert(e.nkeys == node->u.l.leaf_stats.nkeys);
|
||||
// assert(e.dsize == node->u.l.leaf_stats.dsize);
|
||||
// assert(node->u.l.leaf_stats.exact);
|
||||
}
|
||||
|
||||
int
|
||||
toku_bnc_n_entries(NONLEAF_CHILDINFO bnc)
|
||||
{
|
||||
|
@ -729,12 +714,10 @@ void toku_ftnode_flush_callback (
|
|||
if (height == 0 && !is_clone) {
|
||||
ftnode_update_disk_stats(ftnode, h, for_checkpoint);
|
||||
}
|
||||
if (!h->panic) { // if the brt panicked, stop writing, otherwise try to write it.
|
||||
toku_assert_entire_node_in_memory(ftnode);
|
||||
int r = toku_serialize_ftnode_to(fd, ftnode->thisnodename, ftnode, ndd, !is_clone, h, for_checkpoint);
|
||||
assert_zero(r);
|
||||
ftnode->layout_version_read_from_disk = FT_LAYOUT_VERSION;
|
||||
}
|
||||
toku_assert_entire_node_in_memory(ftnode);
|
||||
int r = toku_serialize_ftnode_to(fd, ftnode->thisnodename, ftnode, ndd, !is_clone, h, for_checkpoint);
|
||||
assert_zero(r);
|
||||
ftnode->layout_version_read_from_disk = FT_LAYOUT_VERSION;
|
||||
ft_status_update_flush_reason(ftnode, for_checkpoint);
|
||||
}
|
||||
if (!keep_me) {
|
||||
|
@ -1425,8 +1408,6 @@ toku_ft_bn_apply_cmd_once (
|
|||
// idx is the location where it goes
|
||||
// le is old leafentry
|
||||
{
|
||||
// ft_leaf_check_leaf_stats(node);
|
||||
|
||||
size_t newsize=0, oldsize=0, workdone_this_le=0;
|
||||
LEAFENTRY new_le=0;
|
||||
void *maybe_free = 0;
|
||||
|
@ -1861,8 +1842,7 @@ toku_fifo_entry_key_msn_cmp(const struct toku_fifo_entry_key_msn_cmp_extra &extr
|
|||
extra.desc, extra.cmp);
|
||||
}
|
||||
|
||||
int
|
||||
toku_bnc_insert_msg(NONLEAF_CHILDINFO bnc, const void *key, ITEMLEN keylen, const void *data, ITEMLEN datalen, enum ft_msg_type type, MSN msn, XIDS xids, bool is_fresh, DESCRIPTOR desc, ft_compare_func cmp)
|
||||
void toku_bnc_insert_msg(NONLEAF_CHILDINFO bnc, const void *key, ITEMLEN keylen, const void *data, ITEMLEN datalen, enum ft_msg_type type, MSN msn, XIDS xids, bool is_fresh, DESCRIPTOR desc, ft_compare_func cmp)
|
||||
// Effect: Enqueue the message represented by the parameters into the
|
||||
// bnc's buffer, and put it in either the fresh or stale message tree,
|
||||
// or the broadcast list.
|
||||
|
@ -1882,23 +1862,19 @@ toku_bnc_insert_msg(NONLEAF_CHILDINFO bnc, const void *key, ITEMLEN keylen, cons
|
|||
r = bnc->stale_message_tree.insert<struct toku_fifo_entry_key_msn_heaviside_extra, toku_fifo_entry_key_msn_heaviside>(offset, extra, nullptr);
|
||||
assert_zero(r);
|
||||
}
|
||||
} else if (ft_msg_type_applies_all(type) || ft_msg_type_does_nothing(type)) {
|
||||
} else {
|
||||
invariant(ft_msg_type_applies_all(type) || ft_msg_type_does_nothing(type));
|
||||
const uint32_t idx = bnc->broadcast_list.size();
|
||||
r = bnc->broadcast_list.insert_at(offset, idx);
|
||||
assert_zero(r);
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
// append a cmd to a nonleaf node's child buffer
|
||||
// should be static, but used by test programs
|
||||
void
|
||||
toku_ft_append_to_child_buffer(ft_compare_func compare_fun, DESCRIPTOR desc, FTNODE node, int childnum, enum ft_msg_type type, MSN msn, XIDS xids, bool is_fresh, const DBT *key, const DBT *val) {
|
||||
void toku_ft_append_to_child_buffer(ft_compare_func compare_fun, DESCRIPTOR desc, FTNODE node, int childnum, enum ft_msg_type type, MSN msn, XIDS xids, bool is_fresh, const DBT *key, const DBT *val) {
|
||||
assert(BP_STATE(node,childnum) == PT_AVAIL);
|
||||
int r = toku_bnc_insert_msg(BNC(node, childnum), key->data, key->size, val->data, val->size, type, msn, xids, is_fresh, desc, compare_fun);
|
||||
invariant_zero(r);
|
||||
toku_bnc_insert_msg(BNC(node, childnum), key->data, key->size, val->data, val->size, type, msn, xids, is_fresh, desc, compare_fun);
|
||||
node->dirty = 1;
|
||||
}
|
||||
|
||||
|
@ -2240,8 +2216,7 @@ ft_leaf_gc_all_les(FTNODE node,
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
toku_bnc_flush_to_child(
|
||||
void toku_bnc_flush_to_child(
|
||||
FT h,
|
||||
NONLEAF_CHILDINFO bnc,
|
||||
FTNODE child
|
||||
|
@ -2293,8 +2268,6 @@ toku_bnc_flush_to_child(
|
|||
live_root_txns.destroy();
|
||||
referenced_xids.destroy();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bring_node_fully_into_memory(FTNODE node, FT h)
|
||||
|
@ -2477,8 +2450,7 @@ static void push_something_at_root (FT h, FTNODE *nodep, FT_MSG cmd)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
toku_ft_root_put_cmd (FT ft, FT_MSG_S * cmd)
|
||||
void toku_ft_root_put_cmd(FT ft, FT_MSG_S * cmd)
|
||||
// Effect:
|
||||
// - assign msn to cmd
|
||||
// - push the cmd into the brt
|
||||
|
@ -2486,7 +2458,7 @@ toku_ft_root_put_cmd (FT ft, FT_MSG_S * cmd)
|
|||
{
|
||||
// blackhole fractal trees drop all messages, so do nothing.
|
||||
if (ft->blackhole) {
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
FTNODE node;
|
||||
|
@ -2567,58 +2539,47 @@ toku_ft_root_put_cmd (FT ft, FT_MSG_S * cmd)
|
|||
else {
|
||||
toku_unpin_ftnode(ft, node); // unpin root
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Effect: Insert the key-val pair into brt.
|
||||
int toku_ft_insert (FT_HANDLE brt, DBT *key, DBT *val, TOKUTXN txn) {
|
||||
return toku_ft_maybe_insert(brt, key, val, txn, false, ZERO_LSN, true, FT_INSERT);
|
||||
void toku_ft_insert (FT_HANDLE brt, DBT *key, DBT *val, TOKUTXN txn) {
|
||||
toku_ft_maybe_insert(brt, key, val, txn, false, ZERO_LSN, true, FT_INSERT);
|
||||
}
|
||||
|
||||
int
|
||||
toku_ft_load_recovery(TOKUTXN txn, FILENUM old_filenum, char const * new_iname, int do_fsync, int do_log, LSN *load_lsn) {
|
||||
int r = 0;
|
||||
void toku_ft_load_recovery(TOKUTXN txn, FILENUM old_filenum, char const * new_iname, int do_fsync, int do_log, LSN *load_lsn) {
|
||||
assert(txn);
|
||||
toku_txn_force_fsync_on_commit(txn); //If the txn commits, the commit MUST be in the log
|
||||
//before the (old) file is actually unlinked
|
||||
TOKULOGGER logger = toku_txn_logger(txn);
|
||||
|
||||
BYTESTRING new_iname_bs = {.len=(uint32_t) strlen(new_iname), .data=(char*)new_iname};
|
||||
r = toku_logger_save_rollback_load(txn, old_filenum, &new_iname_bs);
|
||||
if (r==0 && do_log && logger) {
|
||||
toku_logger_save_rollback_load(txn, old_filenum, &new_iname_bs);
|
||||
if (do_log && logger) {
|
||||
TXNID xid = toku_txn_get_txnid(txn);
|
||||
r = toku_log_load(logger, load_lsn, do_fsync, txn, xid, old_filenum, new_iname_bs);
|
||||
toku_log_load(logger, load_lsn, do_fsync, txn, xid, old_filenum, new_iname_bs);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
// 2954
|
||||
// this function handles the tasks needed to be recoverable
|
||||
// - write to rollback log
|
||||
// - write to recovery log
|
||||
int
|
||||
toku_ft_hot_index_recovery(TOKUTXN txn, FILENUMS filenums, int do_fsync, int do_log, LSN *hot_index_lsn)
|
||||
void toku_ft_hot_index_recovery(TOKUTXN txn, FILENUMS filenums, int do_fsync, int do_log, LSN *hot_index_lsn)
|
||||
{
|
||||
int r = 0;
|
||||
assert(txn);
|
||||
TOKULOGGER logger = toku_txn_logger(txn);
|
||||
|
||||
// write to the rollback log
|
||||
r = toku_logger_save_rollback_hot_index(txn, &filenums);
|
||||
if ( r==0 && do_log && logger) {
|
||||
toku_logger_save_rollback_hot_index(txn, &filenums);
|
||||
if (do_log && logger) {
|
||||
TXNID xid = toku_txn_get_txnid(txn);
|
||||
// write to the recovery log
|
||||
r = toku_log_hot_index(logger, hot_index_lsn, do_fsync, txn, xid, filenums);
|
||||
toku_log_hot_index(logger, hot_index_lsn, do_fsync, txn, xid, filenums);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
// Effect: Optimize the brt.
|
||||
int
|
||||
toku_ft_optimize (FT_HANDLE brt) {
|
||||
int r = 0;
|
||||
|
||||
// Effect: Optimize the ft.
|
||||
void toku_ft_optimize (FT_HANDLE brt) {
|
||||
TOKULOGGER logger = toku_cachefile_logger(brt->ft->cf);
|
||||
if (logger) {
|
||||
TXNID oldest = toku_txn_manager_get_oldest_living_xid(logger->txn_manager);
|
||||
|
@ -2629,8 +2590,8 @@ toku_ft_optimize (FT_HANDLE brt) {
|
|||
message_xids = root_xids;
|
||||
}
|
||||
else {
|
||||
r = xids_create_child(root_xids, &message_xids, oldest);
|
||||
invariant(r==0);
|
||||
int r = xids_create_child(root_xids, &message_xids, oldest);
|
||||
invariant(r == 0);
|
||||
}
|
||||
|
||||
DBT key;
|
||||
|
@ -2638,50 +2599,36 @@ toku_ft_optimize (FT_HANDLE brt) {
|
|||
toku_init_dbt(&key);
|
||||
toku_init_dbt(&val);
|
||||
FT_MSG_S ftcmd = { FT_OPTIMIZE, ZERO_MSN, message_xids, .u = { .id = {&key,&val} } };
|
||||
r = toku_ft_root_put_cmd(brt->ft, &ftcmd);
|
||||
toku_ft_root_put_cmd(brt->ft, &ftcmd);
|
||||
xids_destroy(&message_xids);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
toku_ft_load(FT_HANDLE brt, TOKUTXN txn, char const * new_iname, int do_fsync, LSN *load_lsn) {
|
||||
int r = 0;
|
||||
void toku_ft_load(FT_HANDLE brt, TOKUTXN txn, char const * new_iname, int do_fsync, LSN *load_lsn) {
|
||||
FILENUM old_filenum = toku_cachefile_filenum(brt->ft->cf);
|
||||
int do_log = 1;
|
||||
r = toku_ft_load_recovery(txn, old_filenum, new_iname, do_fsync, do_log, load_lsn);
|
||||
return r;
|
||||
toku_ft_load_recovery(txn, old_filenum, new_iname, do_fsync, do_log, load_lsn);
|
||||
}
|
||||
|
||||
// 2954
|
||||
// brt actions for logging hot index filenums
|
||||
int
|
||||
toku_ft_hot_index(FT_HANDLE brt __attribute__ ((unused)), TOKUTXN txn, FILENUMS filenums, int do_fsync, LSN *lsn) {
|
||||
int r = 0;
|
||||
// ft actions for logging hot index filenums
|
||||
void toku_ft_hot_index(FT_HANDLE brt __attribute__ ((unused)), TOKUTXN txn, FILENUMS filenums, int do_fsync, LSN *lsn) {
|
||||
int do_log = 1;
|
||||
r = toku_ft_hot_index_recovery(txn, filenums, do_fsync, do_log, lsn);
|
||||
return r;
|
||||
toku_ft_hot_index_recovery(txn, filenums, do_fsync, do_log, lsn);
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
toku_ft_log_put (TOKUTXN txn, FT_HANDLE brt, const DBT *key, const DBT *val) {
|
||||
int r = 0;
|
||||
TOKULOGGER logger = toku_txn_logger(txn);
|
||||
if (logger && brt->ft->txnid_that_suppressed_recovery_logs == TXNID_NONE) {
|
||||
BYTESTRING keybs = {.len=key->size, .data=(char *) key->data};
|
||||
BYTESTRING valbs = {.len=val->size, .data=(char *) val->data};
|
||||
TXNID xid = toku_txn_get_txnid(txn);
|
||||
// if (type == FT_INSERT)
|
||||
r = toku_log_enq_insert(logger, (LSN*)0, 0, txn, toku_cachefile_filenum(brt->ft->cf), xid, keybs, valbs);
|
||||
// else
|
||||
// r = toku_log_enq_insert_no_overwrite(logger, (LSN*)0, 0, toku_cachefile_filenum(brt->ft->cf), xid, keybs, valbs);
|
||||
toku_log_enq_insert(logger, (LSN*)0, 0, txn, toku_cachefile_filenum(brt->ft->cf), xid, keybs, valbs);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
toku_ft_log_put_multiple (TOKUTXN txn, FT_HANDLE src_ft, FT_HANDLE *brts, int num_fts, const DBT *key, const DBT *val) {
|
||||
int r = 0;
|
||||
assert(txn);
|
||||
assert(num_fts > 0);
|
||||
TOKULOGGER logger = toku_txn_logger(txn);
|
||||
|
@ -2701,23 +2648,19 @@ toku_ft_log_put_multiple (TOKUTXN txn, FT_HANDLE src_ft, FT_HANDLE *brts, int nu
|
|||
BYTESTRING valbs = {.len=val->size, .data=(char *) val->data};
|
||||
TXNID xid = toku_txn_get_txnid(txn);
|
||||
FILENUM src_filenum = src_ft ? toku_cachefile_filenum(src_ft->ft->cf) : FILENUM_NONE;
|
||||
r = toku_log_enq_insert_multiple(logger, (LSN*)0, 0, txn, src_filenum, filenums, xid, keybs, valbs);
|
||||
toku_log_enq_insert_multiple(logger, (LSN*)0, 0, txn, src_filenum, filenums, xid, keybs, valbs);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
toku_ft_maybe_insert (FT_HANDLE ft_h, DBT *key, DBT *val, TOKUTXN txn, bool oplsn_valid, LSN oplsn, bool do_logging, enum ft_msg_type type) {
|
||||
void toku_ft_maybe_insert (FT_HANDLE ft_h, DBT *key, DBT *val, TOKUTXN txn, bool oplsn_valid, LSN oplsn, bool do_logging, enum ft_msg_type type) {
|
||||
assert(type==FT_INSERT || type==FT_INSERT_NO_OVERWRITE);
|
||||
int r = 0;
|
||||
XIDS message_xids = xids_get_root_xids(); //By default use committed messages
|
||||
TXNID xid = toku_txn_get_txnid(txn);
|
||||
if (txn) {
|
||||
if (ft_h->ft->txnid_that_created_or_locked_when_empty != xid) {
|
||||
BYTESTRING keybs = {key->size, (char *) key->data};
|
||||
r = toku_logger_save_rollback_cmdinsert(txn, toku_cachefile_filenum(ft_h->ft->cf), &keybs);
|
||||
if (r!=0) return r;
|
||||
toku_logger_save_rollback_cmdinsert(txn, toku_cachefile_filenum(ft_h->ft->cf), &keybs);
|
||||
toku_txn_maybe_note_ft(txn, ft_h->ft);
|
||||
//We have transactions, and this is not 2440. We must send the full root-to-leaf-path
|
||||
message_xids = toku_txn_get_xids(txn);
|
||||
|
@ -2733,44 +2676,37 @@ toku_ft_maybe_insert (FT_HANDLE ft_h, DBT *key, DBT *val, TOKUTXN txn, bool opls
|
|||
BYTESTRING keybs = {.len=key->size, .data=(char *) key->data};
|
||||
BYTESTRING valbs = {.len=val->size, .data=(char *) val->data};
|
||||
if (type == FT_INSERT) {
|
||||
r = toku_log_enq_insert(logger, (LSN*)0, 0, txn, toku_cachefile_filenum(ft_h->ft->cf), xid, keybs, valbs);
|
||||
toku_log_enq_insert(logger, (LSN*)0, 0, txn, toku_cachefile_filenum(ft_h->ft->cf), xid, keybs, valbs);
|
||||
}
|
||||
else {
|
||||
r = toku_log_enq_insert_no_overwrite(logger, (LSN*)0, 0, txn, toku_cachefile_filenum(ft_h->ft->cf), xid, keybs, valbs);
|
||||
toku_log_enq_insert_no_overwrite(logger, (LSN*)0, 0, txn, toku_cachefile_filenum(ft_h->ft->cf), xid, keybs, valbs);
|
||||
}
|
||||
if (r!=0) return r;
|
||||
}
|
||||
|
||||
LSN treelsn;
|
||||
if (oplsn_valid && oplsn.lsn <= (treelsn = toku_ft_checkpoint_lsn(ft_h->ft)).lsn) {
|
||||
r = 0;
|
||||
// do nothing
|
||||
} else {
|
||||
r = toku_ft_send_insert(ft_h, key, val, message_xids, type);
|
||||
toku_ft_send_insert(ft_h, key, val, message_xids, type);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
ft_send_update_msg(FT_HANDLE brt, FT_MSG_S *msg, TOKUTXN txn) {
|
||||
msg->xids = (txn
|
||||
? toku_txn_get_xids(txn)
|
||||
: xids_get_root_xids());
|
||||
int r = toku_ft_root_put_cmd(brt->ft, msg);
|
||||
return r;
|
||||
toku_ft_root_put_cmd(brt->ft, msg);
|
||||
}
|
||||
|
||||
int
|
||||
toku_ft_maybe_update(FT_HANDLE ft_h, const DBT *key, const DBT *update_function_extra,
|
||||
void toku_ft_maybe_update(FT_HANDLE ft_h, const DBT *key, const DBT *update_function_extra,
|
||||
TOKUTXN txn, bool oplsn_valid, LSN oplsn,
|
||||
bool do_logging) {
|
||||
int r = 0;
|
||||
|
||||
TXNID xid = toku_txn_get_txnid(txn);
|
||||
if (txn) {
|
||||
BYTESTRING keybs = { key->size, (char *) key->data };
|
||||
r = toku_logger_save_rollback_cmdupdate(
|
||||
toku_logger_save_rollback_cmdupdate(
|
||||
txn, toku_cachefile_filenum(ft_h->ft->cf), &keybs);
|
||||
if (r != 0) { goto cleanup; }
|
||||
toku_txn_maybe_note_ft(txn, ft_h->ft);
|
||||
}
|
||||
|
||||
|
@ -2781,37 +2717,28 @@ toku_ft_maybe_update(FT_HANDLE ft_h, const DBT *key, const DBT *update_function_
|
|||
BYTESTRING keybs = {.len=key->size, .data=(char *) key->data};
|
||||
BYTESTRING extrabs = {.len=update_function_extra->size,
|
||||
.data = (char *) update_function_extra->data};
|
||||
r = toku_log_enq_update(logger, NULL, 0, txn,
|
||||
toku_log_enq_update(logger, NULL, 0, txn,
|
||||
toku_cachefile_filenum(ft_h->ft->cf),
|
||||
xid, keybs, extrabs);
|
||||
if (r != 0) { goto cleanup; }
|
||||
}
|
||||
|
||||
LSN treelsn;
|
||||
if (oplsn_valid &&
|
||||
oplsn.lsn <= (treelsn = toku_ft_checkpoint_lsn(ft_h->ft)).lsn) {
|
||||
r = 0;
|
||||
if (oplsn_valid && oplsn.lsn <= (treelsn = toku_ft_checkpoint_lsn(ft_h->ft)).lsn) {
|
||||
// do nothing
|
||||
} else {
|
||||
FT_MSG_S msg = { FT_UPDATE, ZERO_MSN, NULL,
|
||||
.u = { .id = { key, update_function_extra } } };
|
||||
r = ft_send_update_msg(ft_h, &msg, txn);
|
||||
ft_send_update_msg(ft_h, &msg, txn);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
toku_ft_maybe_update_broadcast(FT_HANDLE ft_h, const DBT *update_function_extra,
|
||||
void toku_ft_maybe_update_broadcast(FT_HANDLE ft_h, const DBT *update_function_extra,
|
||||
TOKUTXN txn, bool oplsn_valid, LSN oplsn,
|
||||
bool do_logging, bool is_resetting_op) {
|
||||
int r = 0;
|
||||
|
||||
TXNID xid = toku_txn_get_txnid(txn);
|
||||
uint8_t resetting = is_resetting_op ? 1 : 0;
|
||||
if (txn) {
|
||||
r = toku_logger_save_rollback_cmdupdatebroadcast(txn, toku_cachefile_filenum(ft_h->ft->cf), resetting);
|
||||
if (r != 0) { goto cleanup; }
|
||||
toku_logger_save_rollback_cmdupdatebroadcast(txn, toku_cachefile_filenum(ft_h->ft->cf), resetting);
|
||||
toku_txn_maybe_note_ft(txn, ft_h->ft);
|
||||
}
|
||||
|
||||
|
@ -2821,63 +2748,52 @@ toku_ft_maybe_update_broadcast(FT_HANDLE ft_h, const DBT *update_function_extra,
|
|||
ft_h->ft->txnid_that_suppressed_recovery_logs == TXNID_NONE) {
|
||||
BYTESTRING extrabs = {.len=update_function_extra->size,
|
||||
.data = (char *) update_function_extra->data};
|
||||
r = toku_log_enq_updatebroadcast(logger, NULL, 0, txn,
|
||||
toku_log_enq_updatebroadcast(logger, NULL, 0, txn,
|
||||
toku_cachefile_filenum(ft_h->ft->cf),
|
||||
xid, extrabs, resetting);
|
||||
if (r != 0) { goto cleanup; }
|
||||
}
|
||||
|
||||
//TODO(yoni): remove treelsn here and similar calls (no longer being used)
|
||||
LSN treelsn;
|
||||
if (oplsn_valid &&
|
||||
oplsn.lsn <= (treelsn = toku_ft_checkpoint_lsn(ft_h->ft)).lsn) {
|
||||
r = 0;
|
||||
|
||||
} else {
|
||||
DBT nullkey;
|
||||
const DBT *nullkeyp = toku_init_dbt(&nullkey);
|
||||
FT_MSG_S msg = { FT_UPDATE_BROADCAST_ALL, ZERO_MSN, NULL,
|
||||
.u = { .id = { nullkeyp, update_function_extra } } };
|
||||
r = ft_send_update_msg(ft_h, &msg, txn);
|
||||
ft_send_update_msg(ft_h, &msg, txn);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
toku_ft_send_insert(FT_HANDLE brt, DBT *key, DBT *val, XIDS xids, enum ft_msg_type type) {
|
||||
void toku_ft_send_insert(FT_HANDLE brt, DBT *key, DBT *val, XIDS xids, enum ft_msg_type type) {
|
||||
FT_MSG_S ftcmd = { type, ZERO_MSN, xids, .u = { .id = { key, val } } };
|
||||
int r = toku_ft_root_put_cmd(brt->ft, &ftcmd);
|
||||
return r;
|
||||
toku_ft_root_put_cmd(brt->ft, &ftcmd);
|
||||
}
|
||||
|
||||
int
|
||||
toku_ft_send_commit_any(FT_HANDLE brt, DBT *key, XIDS xids) {
|
||||
void toku_ft_send_commit_any(FT_HANDLE brt, DBT *key, XIDS xids) {
|
||||
DBT val;
|
||||
FT_MSG_S ftcmd = { FT_COMMIT_ANY, ZERO_MSN, xids, .u = { .id = { key, toku_init_dbt(&val) } } };
|
||||
int r = toku_ft_root_put_cmd(brt->ft, &ftcmd);
|
||||
return r;
|
||||
toku_ft_root_put_cmd(brt->ft, &ftcmd);
|
||||
}
|
||||
|
||||
int toku_ft_delete(FT_HANDLE brt, DBT *key, TOKUTXN txn) {
|
||||
return toku_ft_maybe_delete(brt, key, txn, false, ZERO_LSN, true);
|
||||
void toku_ft_delete(FT_HANDLE brt, DBT *key, TOKUTXN txn) {
|
||||
toku_ft_maybe_delete(brt, key, txn, false, ZERO_LSN, true);
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
toku_ft_log_del(TOKUTXN txn, FT_HANDLE brt, const DBT *key) {
|
||||
int r = 0;
|
||||
TOKULOGGER logger = toku_txn_logger(txn);
|
||||
if (logger && brt->ft->txnid_that_suppressed_recovery_logs == TXNID_NONE) {
|
||||
BYTESTRING keybs = {.len=key->size, .data=(char *) key->data};
|
||||
TXNID xid = toku_txn_get_txnid(txn);
|
||||
r = toku_log_enq_delete_any(logger, (LSN*)0, 0, txn, toku_cachefile_filenum(brt->ft->cf), xid, keybs);
|
||||
toku_log_enq_delete_any(logger, (LSN*)0, 0, txn, toku_cachefile_filenum(brt->ft->cf), xid, keybs);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
toku_ft_log_del_multiple (TOKUTXN txn, FT_HANDLE src_ft, FT_HANDLE *brts, int num_fts, const DBT *key, const DBT *val) {
|
||||
int r = 0;
|
||||
assert(txn);
|
||||
assert(num_fts > 0);
|
||||
TOKULOGGER logger = toku_txn_logger(txn);
|
||||
|
@ -2897,22 +2813,18 @@ toku_ft_log_del_multiple (TOKUTXN txn, FT_HANDLE src_ft, FT_HANDLE *brts, int nu
|
|||
BYTESTRING valbs = {.len=val->size, .data=(char *) val->data};
|
||||
TXNID xid = toku_txn_get_txnid(txn);
|
||||
FILENUM src_filenum = src_ft ? toku_cachefile_filenum(src_ft->ft->cf) : FILENUM_NONE;
|
||||
r = toku_log_enq_delete_multiple(logger, (LSN*)0, 0, txn, src_filenum, filenums, xid, keybs, valbs);
|
||||
toku_log_enq_delete_multiple(logger, (LSN*)0, 0, txn, src_filenum, filenums, xid, keybs, valbs);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
toku_ft_maybe_delete(FT_HANDLE ft_h, DBT *key, TOKUTXN txn, bool oplsn_valid, LSN oplsn, bool do_logging) {
|
||||
int r;
|
||||
void toku_ft_maybe_delete(FT_HANDLE ft_h, DBT *key, TOKUTXN txn, bool oplsn_valid, LSN oplsn, bool do_logging) {
|
||||
XIDS message_xids = xids_get_root_xids(); //By default use committed messages
|
||||
TXNID xid = toku_txn_get_txnid(txn);
|
||||
if (txn) {
|
||||
if (ft_h->ft->txnid_that_created_or_locked_when_empty != xid) {
|
||||
BYTESTRING keybs = {key->size, (char *) key->data};
|
||||
r = toku_logger_save_rollback_cmddelete(txn, toku_cachefile_filenum(ft_h->ft->cf), &keybs);
|
||||
if (r!=0) return r;
|
||||
toku_logger_save_rollback_cmddelete(txn, toku_cachefile_filenum(ft_h->ft->cf), &keybs);
|
||||
toku_txn_maybe_note_ft(txn, ft_h->ft);
|
||||
//We have transactions, and this is not 2440. We must send the full root-to-leaf-path
|
||||
message_xids = toku_txn_get_xids(txn);
|
||||
|
@ -2926,25 +2838,21 @@ toku_ft_maybe_delete(FT_HANDLE ft_h, DBT *key, TOKUTXN txn, bool oplsn_valid, LS
|
|||
if (do_logging && logger &&
|
||||
ft_h->ft->txnid_that_suppressed_recovery_logs == TXNID_NONE) {
|
||||
BYTESTRING keybs = {.len=key->size, .data=(char *) key->data};
|
||||
r = toku_log_enq_delete_any(logger, (LSN*)0, 0, txn, toku_cachefile_filenum(ft_h->ft->cf), xid, keybs);
|
||||
if (r!=0) return r;
|
||||
toku_log_enq_delete_any(logger, (LSN*)0, 0, txn, toku_cachefile_filenum(ft_h->ft->cf), xid, keybs);
|
||||
}
|
||||
|
||||
LSN treelsn;
|
||||
if (oplsn_valid && oplsn.lsn <= (treelsn = toku_ft_checkpoint_lsn(ft_h->ft)).lsn) {
|
||||
r = 0;
|
||||
// do nothing
|
||||
} else {
|
||||
r = toku_ft_send_delete(ft_h, key, message_xids);
|
||||
toku_ft_send_delete(ft_h, key, message_xids);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
toku_ft_send_delete(FT_HANDLE brt, DBT *key, XIDS xids) {
|
||||
void toku_ft_send_delete(FT_HANDLE brt, DBT *key, XIDS xids) {
|
||||
DBT val; toku_init_dbt(&val);
|
||||
FT_MSG_S ftcmd = { FT_DELETE_ANY, ZERO_MSN, xids, .u = { .id = { key, &val } } };
|
||||
int result = toku_ft_root_put_cmd(brt->ft, &ftcmd);
|
||||
return result;
|
||||
toku_ft_root_put_cmd(brt->ft, &ftcmd);
|
||||
}
|
||||
|
||||
/* mempool support */
|
||||
|
@ -2966,8 +2874,7 @@ static int move_it (OMTVALUE lev, uint32_t idx, void *v) {
|
|||
}
|
||||
|
||||
// Compress things, and grow the mempool if needed.
|
||||
// TODO 4092 should copy data to new memory, then call toku_mempool_destory() followed by toku_mempool_init()
|
||||
static int omt_compress_kvspace (OMT omt, struct mempool *memp, size_t added_size, void **maybe_free) {
|
||||
static void omt_compress_kvspace (OMT omt, struct mempool *memp, size_t added_size, void **maybe_free) {
|
||||
uint32_t total_size_needed = memp->free_offset-memp->frag_size + added_size;
|
||||
if (total_size_needed+total_size_needed/4 >= memp->size) {
|
||||
memp->size = total_size_needed+total_size_needed/4;
|
||||
|
@ -2984,17 +2891,15 @@ static int omt_compress_kvspace (OMT omt, struct mempool *memp, size_t added_siz
|
|||
toku_free(memp->base);
|
||||
}
|
||||
*memp = new_kvspace;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
mempool_malloc_from_omt(OMT omt, struct mempool *mp, size_t size, void **maybe_free) {
|
||||
void *v = toku_mempool_malloc(mp, size, 1);
|
||||
if (v==0) {
|
||||
if (0 == omt_compress_kvspace(omt, mp, size, maybe_free)) {
|
||||
v = toku_mempool_malloc(mp, size, 1);
|
||||
lazy_assert(v);
|
||||
}
|
||||
if (v == NULL) {
|
||||
omt_compress_kvspace(omt, mp, size, maybe_free);
|
||||
v = toku_mempool_malloc(mp, size, 1);
|
||||
lazy_assert(v);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
@ -3008,18 +2913,15 @@ int toku_open_ft_handle (const char *fname, int is_create, FT_HANDLE *ft_handle_
|
|||
CACHETABLE cachetable, TOKUTXN txn,
|
||||
int (*compare_fun)(DB *, const DBT*,const DBT*)) {
|
||||
FT_HANDLE brt;
|
||||
int r;
|
||||
const int only_create = 0;
|
||||
|
||||
r = toku_ft_handle_create(&brt);
|
||||
if (r != 0)
|
||||
return r;
|
||||
toku_ft_handle_create(&brt);
|
||||
toku_ft_handle_set_nodesize(brt, nodesize);
|
||||
toku_ft_handle_set_basementnodesize(brt, basementnodesize);
|
||||
toku_ft_handle_set_compression_method(brt, compression_method);
|
||||
r = toku_ft_set_bt_compare(brt, compare_fun); assert_zero(r);
|
||||
toku_ft_set_bt_compare(brt, compare_fun);
|
||||
|
||||
r = toku_ft_handle_open(brt, fname, is_create, only_create, cachetable, txn);
|
||||
int r = toku_ft_handle_open(brt, fname, is_create, only_create, cachetable, txn);
|
||||
if (r != 0) {
|
||||
return r;
|
||||
}
|
||||
|
@ -3098,8 +3000,7 @@ verify_builtin_comparisons_consistent(FT_HANDLE t, uint32_t flags) {
|
|||
// See comments in toku_db_change_descriptor to understand invariants
|
||||
// in the system when this function is called
|
||||
//
|
||||
int
|
||||
toku_ft_change_descriptor(
|
||||
void toku_ft_change_descriptor(
|
||||
FT_HANDLE ft_h,
|
||||
const DBT* old_descriptor,
|
||||
const DBT* new_descriptor,
|
||||
|
@ -3108,7 +3009,6 @@ toku_ft_change_descriptor(
|
|||
bool update_cmp_descriptor
|
||||
)
|
||||
{
|
||||
int r = 0;
|
||||
DESCRIPTOR_S new_d;
|
||||
|
||||
// if running with txns, save to rollback + write to recovery log
|
||||
|
@ -3116,18 +3016,17 @@ toku_ft_change_descriptor(
|
|||
// put information into rollback file
|
||||
BYTESTRING old_desc_bs = { old_descriptor->size, (char *) old_descriptor->data };
|
||||
BYTESTRING new_desc_bs = { new_descriptor->size, (char *) new_descriptor->data };
|
||||
r = toku_logger_save_rollback_change_fdescriptor(
|
||||
toku_logger_save_rollback_change_fdescriptor(
|
||||
txn,
|
||||
toku_cachefile_filenum(ft_h->ft->cf),
|
||||
&old_desc_bs
|
||||
);
|
||||
if (r != 0) { goto cleanup; }
|
||||
toku_txn_maybe_note_ft(txn, ft_h->ft);
|
||||
|
||||
if (do_log) {
|
||||
TOKULOGGER logger = toku_txn_logger(txn);
|
||||
TXNID xid = toku_txn_get_txnid(txn);
|
||||
r = toku_log_change_fdescriptor(
|
||||
toku_log_change_fdescriptor(
|
||||
logger, NULL, 0,
|
||||
txn,
|
||||
toku_cachefile_filenum(ft_h->ft->cf),
|
||||
|
@ -3136,7 +3035,6 @@ toku_ft_change_descriptor(
|
|||
new_desc_bs,
|
||||
update_cmp_descriptor
|
||||
);
|
||||
if (r != 0) { goto cleanup; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3144,16 +3042,11 @@ toku_ft_change_descriptor(
|
|||
new_d.dbt = *new_descriptor;
|
||||
toku_ft_update_descriptor(ft_h->ft, &new_d);
|
||||
// very infrequent operation, worth precise threadsafe count
|
||||
if (r == 0) {
|
||||
STATUS_INC(FT_DESCRIPTOR_SET, 1);
|
||||
}
|
||||
if (r!=0) goto cleanup;
|
||||
STATUS_INC(FT_DESCRIPTOR_SET, 1);
|
||||
|
||||
if (update_cmp_descriptor) {
|
||||
toku_ft_update_cmp_descriptor(ft_h->ft);
|
||||
}
|
||||
cleanup:
|
||||
return r;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -3188,10 +3081,6 @@ ft_handle_open(FT_HANDLE ft_h, const char *fname_in_env, int is_create, int only
|
|||
r = verify_builtin_comparisons_consistent(ft_h, ft_h->options.flags);
|
||||
if (r!=0) { goto exit; }
|
||||
}
|
||||
if (txn && txn->logger->is_panicked) {
|
||||
r = EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
assert(is_create || !only_create);
|
||||
FILENUM reserved_filenum;
|
||||
|
@ -3208,12 +3097,10 @@ ft_handle_open(FT_HANDLE ft_h, const char *fname_in_env, int is_create, int only
|
|||
mode_t mode = S_IRWXU|S_IRWXG|S_IRWXO;
|
||||
if (txn) {
|
||||
BYTESTRING bs = { .len=(uint32_t) strlen(fname_in_env), .data = (char*)fname_in_env };
|
||||
r = toku_logger_save_rollback_fcreate(txn, reserved_filenum, &bs); // bs is a copy of the fname relative to the environment
|
||||
assert_zero(r);
|
||||
toku_logger_save_rollback_fcreate(txn, reserved_filenum, &bs); // bs is a copy of the fname relative to the environment
|
||||
}
|
||||
txn_created = (bool)(txn!=NULL);
|
||||
r = toku_logger_log_fcreate(txn, fname_in_env, reserved_filenum, mode, ft_h->options.flags, ft_h->options.nodesize, ft_h->options.basementnodesize, ft_h->options.compression_method);
|
||||
assert_zero(r); // only possible failure is panic, which we check above
|
||||
toku_logger_log_fcreate(txn, fname_in_env, reserved_filenum, mode, ft_h->options.flags, ft_h->options.nodesize, ft_h->options.basementnodesize, ft_h->options.compression_method);
|
||||
r = ft_create_file(ft_h, fname_in_cwd, &fd);
|
||||
assert_zero(r);
|
||||
}
|
||||
|
@ -3255,8 +3142,7 @@ ft_handle_open(FT_HANDLE ft_h, const char *fname_in_env, int is_create, int only
|
|||
|
||||
if (!was_already_open) {
|
||||
if (!did_create) { //Only log the fopen that OPENs the file. If it was already open, don't log.
|
||||
r = toku_logger_log_fopen(txn, fname_in_env, toku_cachefile_filenum(cf), ft_h->options.flags);
|
||||
assert_zero(r);
|
||||
toku_logger_log_fopen(txn, fname_in_env, toku_cachefile_filenum(cf), ft_h->options.flags);
|
||||
}
|
||||
}
|
||||
int use_reserved_dict_id;
|
||||
|
@ -3317,13 +3203,12 @@ exit:
|
|||
toku_ft_release_reflock(ft);
|
||||
if (!needed) {
|
||||
//Close immediately.
|
||||
char *error_string = NULL;
|
||||
r = toku_ft_evict_from_memory(ft, &error_string, false, ZERO_LSN);
|
||||
r = toku_ft_evict_from_memory(ft, false, ZERO_LSN);
|
||||
lazy_assert_zero(r);
|
||||
}
|
||||
}
|
||||
else {
|
||||
toku_cachefile_close(&cf, 0, false, ZERO_LSN);
|
||||
toku_cachefile_close(&cf, false, ZERO_LSN);
|
||||
}
|
||||
}
|
||||
toku_ft_open_close_unlock();
|
||||
|
@ -3354,10 +3239,8 @@ toku_ft_handle_open(FT_HANDLE t, const char *fname_in_env, int is_create, int on
|
|||
// clone an ft handle. the cloned handle has a new dict_id but refers to the same fractal tree
|
||||
int
|
||||
toku_ft_handle_clone(FT_HANDLE *cloned_ft_handle, FT_HANDLE ft_handle, TOKUTXN txn) {
|
||||
int r;
|
||||
FT_HANDLE result_ft_handle;
|
||||
r = toku_ft_handle_create(&result_ft_handle);
|
||||
resource_assert_zero(r);
|
||||
toku_ft_handle_create(&result_ft_handle);
|
||||
|
||||
// we're cloning, so the handle better have an open ft and open cf
|
||||
invariant(ft_handle->ft);
|
||||
|
@ -3370,7 +3253,7 @@ toku_ft_handle_clone(FT_HANDLE *cloned_ft_handle, FT_HANDLE ft_handle, TOKUTXN t
|
|||
CACHEFILE cf = ft_handle->ft->cf;
|
||||
CACHETABLE ct = toku_cachefile_get_cachetable(cf);
|
||||
const char *fname_in_env = toku_cachefile_fname_in_env(cf);
|
||||
r = toku_ft_handle_open(result_ft_handle, fname_in_env, false, false, ct, txn);
|
||||
int r = toku_ft_handle_open(result_ft_handle, fname_in_env, false, false, ct, txn);
|
||||
if (r != 0) {
|
||||
toku_ft_handle_close(result_ft_handle);
|
||||
result_ft_handle = NULL;
|
||||
|
@ -3466,9 +3349,8 @@ void toku_ft_handle_get_basementnodesize(FT_HANDLE ft_handle, unsigned int *base
|
|||
}
|
||||
}
|
||||
|
||||
int toku_ft_set_bt_compare(FT_HANDLE brt, int (*bt_compare)(DB*, const DBT*, const DBT*)) {
|
||||
void toku_ft_set_bt_compare(FT_HANDLE brt, int (*bt_compare)(DB*, const DBT*, const DBT*)) {
|
||||
brt->options.compare_fun = bt_compare;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void toku_ft_set_redirect_callback(FT_HANDLE brt, on_redirect_callback redir_cb, void* extra) {
|
||||
|
@ -3476,9 +3358,8 @@ void toku_ft_set_redirect_callback(FT_HANDLE brt, on_redirect_callback redir_cb,
|
|||
brt->redirect_callback_extra = extra;
|
||||
}
|
||||
|
||||
int toku_ft_set_update(FT_HANDLE brt, ft_update_func update_fun) {
|
||||
void toku_ft_set_update(FT_HANDLE brt, ft_update_func update_fun) {
|
||||
brt->options.update_fun = update_fun;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ft_compare_func toku_ft_get_bt_compare (FT_HANDLE brt) {
|
||||
|
@ -3523,10 +3404,8 @@ toku_close_ft_handle_nolsn (FT_HANDLE ft_handle, char** UU(error_string)) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int toku_ft_handle_create(FT_HANDLE *ft_handle_ptr) {
|
||||
FT_HANDLE MALLOC(brt);
|
||||
if (brt == 0)
|
||||
return ENOMEM;
|
||||
void toku_ft_handle_create(FT_HANDLE *ft_handle_ptr) {
|
||||
FT_HANDLE XMALLOC(brt);
|
||||
memset(brt, 0, sizeof *brt);
|
||||
toku_list_init(&brt->live_ft_handle_link);
|
||||
brt->options.flags = 0;
|
||||
|
@ -3537,7 +3416,6 @@ int toku_ft_handle_create(FT_HANDLE *ft_handle_ptr) {
|
|||
brt->options.compare_fun = toku_builtin_compare_fun;
|
||||
brt->options.update_fun = NULL;
|
||||
*ft_handle_ptr = brt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ************* CURSORS ********************* */
|
||||
|
@ -3681,7 +3559,7 @@ toku_ft_cursor_set_range_lock(FT_CURSOR cursor, const DBT *left, const DBT *righ
|
|||
}
|
||||
}
|
||||
|
||||
int toku_ft_cursor_close(FT_CURSOR cursor) {
|
||||
void toku_ft_cursor_close(FT_CURSOR cursor) {
|
||||
ft_cursor_cleanup_dbts(cursor);
|
||||
if (cursor->range_lock_left_key.data) {
|
||||
toku_free(cursor->range_lock_left_key.data);
|
||||
|
@ -3692,7 +3570,6 @@ int toku_ft_cursor_close(FT_CURSOR cursor) {
|
|||
toku_destroy_dbt(&cursor->range_lock_right_key);
|
||||
}
|
||||
toku_free(cursor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ft_cursor_set_prefetching(FT_CURSOR cursor) {
|
||||
|
@ -5245,7 +5122,7 @@ toku_ft_lookup (FT_HANDLE brt, DBT *k, FT_GET_CALLBACK_FUNCTION getf, void *getf
|
|||
int op = DB_SET;
|
||||
r = toku_ft_cursor_get(cursor, k, getf, getf_v, op);
|
||||
|
||||
rr = toku_ft_cursor_close(cursor); assert_zero(rr);
|
||||
toku_ft_cursor_close(cursor);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -5271,7 +5148,7 @@ toku_ft_cursor_delete(FT_CURSOR cursor, int flags, TOKUTXN txn) {
|
|||
r = toku_ft_cursor_current(cursor, DB_CURRENT, getf_nothing, NULL);
|
||||
}
|
||||
if (r == 0) {
|
||||
r = toku_ft_delete(cursor->ft_handle, &cursor->key, txn);
|
||||
toku_ft_delete(cursor->ft_handle, &cursor->key, txn);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
|
@ -5394,8 +5271,7 @@ toku_ft_keyrange_internal (FT_HANDLE brt, FTNODE node,
|
|||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
toku_ft_keyrange (FT_HANDLE brt, DBT *key, uint64_t *less_p, uint64_t *equal_p, uint64_t *greater_p)
|
||||
void toku_ft_keyrange(FT_HANDLE brt, DBT *key, uint64_t *less_p, uint64_t *equal_p, uint64_t *greater_p)
|
||||
// Effect: Return an estimate of the number of keys to the left, the number equal, and the number to the right of the key.
|
||||
// The values are an estimate.
|
||||
// If you perform a keyrange on two keys that are in the same in-memory and uncompressed basement,
|
||||
|
@ -5452,14 +5328,11 @@ try_again:
|
|||
*equal_p = equal;
|
||||
*greater_p = greater;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
toku_ft_handle_stat64 (FT_HANDLE brt, TOKUTXN UU(txn), struct ftstat64_s *s) {
|
||||
void toku_ft_handle_stat64 (FT_HANDLE brt, TOKUTXN UU(txn), struct ftstat64_s *s) {
|
||||
assert(brt->ft);
|
||||
toku_ft_stat64(brt->ft, s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ********************* debugging dump ************************ */
|
||||
|
@ -5596,10 +5469,6 @@ toku_ft_suppress_recovery_logs (FT_HANDLE brt, TOKUTXN txn) {
|
|||
txn->checkpoint_needed_before_commit = true;
|
||||
}
|
||||
|
||||
int toku_ft_handle_set_panic(FT_HANDLE brt, int panic, const char *panic_string) {
|
||||
return toku_ft_set_panic(brt->ft, panic, panic_string);
|
||||
}
|
||||
|
||||
// Prepare to remove a dictionary from the database when this transaction is committed:
|
||||
// - mark transaction as NEED fsync on commit
|
||||
// - make entry in rollback log
|
||||
|
@ -5616,13 +5485,10 @@ int toku_ft_handle_set_panic(FT_HANDLE brt, int panic, const char *panic_string)
|
|||
// 3.) we're already holding the multi operation lock to
|
||||
// synchronize with begin checkpoint.
|
||||
// Contract: the iname of the ft should never be reused.
|
||||
int
|
||||
toku_ft_unlink_on_commit(FT_HANDLE handle, TOKUTXN txn) {
|
||||
int r;
|
||||
CACHEFILE cf;
|
||||
|
||||
void toku_ft_unlink_on_commit(FT_HANDLE handle, TOKUTXN txn) {
|
||||
assert(txn);
|
||||
cf = handle->ft->cf;
|
||||
|
||||
CACHEFILE cf = handle->ft->cf;
|
||||
FT CAST_FROM_VOIDP(ft, toku_cachefile_get_userdata(cf));
|
||||
|
||||
toku_txn_maybe_note_ft(txn, ft);
|
||||
|
@ -5631,11 +5497,9 @@ toku_ft_unlink_on_commit(FT_HANDLE handle, TOKUTXN txn) {
|
|||
toku_txn_force_fsync_on_commit(txn);
|
||||
// make entry in rollback log
|
||||
FILENUM filenum = toku_cachefile_filenum(cf);
|
||||
r = toku_logger_save_rollback_fdelete(txn, filenum);
|
||||
assert_zero(r);
|
||||
toku_logger_save_rollback_fdelete(txn, filenum);
|
||||
// make entry in recovery log
|
||||
r = toku_logger_log_fdelete(txn, filenum);
|
||||
return r;
|
||||
toku_logger_log_fdelete(txn, filenum);
|
||||
}
|
||||
|
||||
// Non-transactional version of fdelete
|
||||
|
@ -5644,8 +5508,7 @@ toku_ft_unlink_on_commit(FT_HANDLE handle, TOKUTXN txn) {
|
|||
// pinned by checkpoint. see toku_remove_ft_ref() and how unlink on
|
||||
// close works in toku_cachefile_close();
|
||||
// Requires: serialized with begin checkpoint
|
||||
void
|
||||
toku_ft_unlink(FT_HANDLE handle) {
|
||||
void toku_ft_unlink(FT_HANDLE handle) {
|
||||
CACHEFILE cf;
|
||||
cf = handle->ft->cf;
|
||||
toku_cachefile_unlink_on_close(cf);
|
||||
|
|
62
ft/ft-ops.h
62
ft/ft-ops.h
|
@ -37,10 +37,10 @@ int toku_open_ft_handle (const char *fname, int is_create, FT_HANDLE *, int node
|
|||
// - can only update cmp descriptor immidiately after opening the FIRST ft handle for this ft and before
|
||||
// ANY operations. to update the cmp descriptor after any operations have already happened, all handles
|
||||
// and transactions must close and reopen before the change, then you can update the cmp descriptor
|
||||
int toku_ft_change_descriptor(FT_HANDLE t, const DBT* old_descriptor, const DBT* new_descriptor, bool do_log, TOKUTXN txn, bool update_cmp_descriptor);
|
||||
void toku_ft_change_descriptor(FT_HANDLE t, const DBT* old_descriptor, const DBT* new_descriptor, bool do_log, TOKUTXN txn, bool update_cmp_descriptor);
|
||||
uint32_t toku_serialize_descriptor_size(const DESCRIPTOR desc);
|
||||
|
||||
int toku_ft_handle_create(FT_HANDLE *) __attribute__ ((warn_unused_result));
|
||||
void toku_ft_handle_create(FT_HANDLE *ft);
|
||||
void toku_ft_set_flags(FT_HANDLE, unsigned int flags);
|
||||
void toku_ft_get_flags(FT_HANDLE, unsigned int *flags);
|
||||
void toku_ft_handle_set_nodesize(FT_HANDLE, unsigned int nodesize);
|
||||
|
@ -51,7 +51,7 @@ void toku_ft_handle_get_basementnodesize(FT_HANDLE, unsigned int *basementnodesi
|
|||
void toku_ft_handle_set_compression_method(FT_HANDLE, enum toku_compression_method);
|
||||
void toku_ft_handle_get_compression_method(FT_HANDLE, enum toku_compression_method *);
|
||||
|
||||
int toku_ft_set_bt_compare(FT_HANDLE, ft_compare_func) __attribute__ ((warn_unused_result));
|
||||
void toku_ft_set_bt_compare(FT_HANDLE, ft_compare_func);
|
||||
ft_compare_func toku_ft_get_bt_compare (FT_HANDLE brt);
|
||||
|
||||
void toku_ft_set_redirect_callback(FT_HANDLE brt, on_redirect_callback redir_cb, void* extra);
|
||||
|
@ -92,7 +92,7 @@ void toku_ft_set_redirect_callback(FT_HANDLE brt, on_redirect_callback redir_cb,
|
|||
// Implementation note: Acquires a write lock on the entire database.
|
||||
// This function works by sending an BROADCAST-UPDATE message containing
|
||||
// the key and the extra.
|
||||
int toku_ft_set_update(FT_HANDLE brt, ft_update_func update_fun) __attribute__ ((warn_unused_result));
|
||||
void toku_ft_set_update(FT_HANDLE brt, ft_update_func update_fun);
|
||||
|
||||
int toku_ft_handle_open(FT_HANDLE, const char *fname_in_env,
|
||||
int is_create, int only_create, CACHETABLE ct, TOKUTXN txn) __attribute__ ((warn_unused_result));
|
||||
|
@ -122,52 +122,44 @@ toku_ft_handle_open_with_dict_id(
|
|||
int toku_ft_lookup (FT_HANDLE brt, DBT *k, FT_GET_CALLBACK_FUNCTION getf, void *getf_v) __attribute__ ((warn_unused_result));
|
||||
|
||||
// Effect: Insert a key and data pair into a brt
|
||||
// Returns 0 if successful
|
||||
int toku_ft_insert (FT_HANDLE brt, DBT *k, DBT *v, TOKUTXN txn) __attribute__ ((warn_unused_result));
|
||||
void toku_ft_insert (FT_HANDLE brt, DBT *k, DBT *v, TOKUTXN txn);
|
||||
|
||||
int toku_ft_optimize (FT_HANDLE brt) __attribute__ ((warn_unused_result));
|
||||
// Effect: Optimize the ft
|
||||
void toku_ft_optimize (FT_HANDLE brt);
|
||||
|
||||
// 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_ft_maybe_insert (FT_HANDLE brt, DBT *k, DBT *v, TOKUTXN txn, bool oplsn_valid, LSN oplsn, bool do_logging, enum ft_msg_type type) __attribute__ ((warn_unused_result));
|
||||
void toku_ft_maybe_insert (FT_HANDLE brt, DBT *k, DBT *v, TOKUTXN txn, bool oplsn_valid, LSN oplsn, bool do_logging, enum ft_msg_type type);
|
||||
|
||||
// Effect: Send an update message into a brt. This function is called
|
||||
// during recovery.
|
||||
// Returns 0 if successful
|
||||
int toku_ft_maybe_update(FT_HANDLE brt, const DBT *key, const DBT *update_function_extra, TOKUTXN txn, bool oplsn_valid, LSN oplsn, bool do_logging) __attribute__ ((warn_unused_result));
|
||||
void toku_ft_maybe_update(FT_HANDLE brt, const DBT *key, const DBT *update_function_extra, TOKUTXN txn, bool oplsn_valid, LSN oplsn, bool do_logging);
|
||||
|
||||
// Effect: Send a broadcasting update message into a brt. This function
|
||||
// is called during recovery.
|
||||
// Returns 0 if successful
|
||||
int toku_ft_maybe_update_broadcast(FT_HANDLE brt, const DBT *update_function_extra, TOKUTXN txn, bool oplsn_valid, LSN oplsn, bool do_logging, bool is_resetting_op) __attribute__ ((warn_unused_result));
|
||||
void toku_ft_maybe_update_broadcast(FT_HANDLE brt, const DBT *update_function_extra, TOKUTXN txn, bool oplsn_valid, LSN oplsn, bool do_logging, bool is_resetting_op);
|
||||
|
||||
int toku_ft_load_recovery(TOKUTXN txn, FILENUM old_filenum, char const * new_iname, int do_fsync, int do_log, LSN *load_lsn) __attribute__ ((warn_unused_result));
|
||||
int toku_ft_load(FT_HANDLE brt, TOKUTXN txn, char const * new_iname, int do_fsync, LSN *get_lsn) __attribute__ ((warn_unused_result));
|
||||
// 2954
|
||||
int toku_ft_hot_index_recovery(TOKUTXN txn, FILENUMS filenums, int do_fsync, int do_log, LSN *hot_index_lsn);
|
||||
int toku_ft_hot_index(FT_HANDLE brt, TOKUTXN txn, FILENUMS filenums, int do_fsync, LSN *lsn) __attribute__ ((warn_unused_result));
|
||||
void toku_ft_load_recovery(TOKUTXN txn, FILENUM old_filenum, char const * new_iname, int do_fsync, int do_log, LSN *load_lsn);
|
||||
void toku_ft_load(FT_HANDLE brt, TOKUTXN txn, char const * new_iname, int do_fsync, LSN *get_lsn);
|
||||
void toku_ft_hot_index_recovery(TOKUTXN txn, FILENUMS filenums, int do_fsync, int do_log, LSN *hot_index_lsn);
|
||||
void toku_ft_hot_index(FT_HANDLE brt, TOKUTXN txn, FILENUMS filenums, int do_fsync, LSN *lsn);
|
||||
|
||||
int toku_ft_log_put_multiple (TOKUTXN txn, FT_HANDLE src_ft, FT_HANDLE *brts, int num_fts, const DBT *key, const DBT *val) __attribute__ ((warn_unused_result));
|
||||
int toku_ft_log_put (TOKUTXN txn, FT_HANDLE brt, const DBT *key, const DBT *val) __attribute__ ((warn_unused_result));
|
||||
int toku_ft_log_del_multiple (TOKUTXN txn, FT_HANDLE src_ft, FT_HANDLE *brts, int num_fts, const DBT *key, const DBT *val) __attribute__ ((warn_unused_result));
|
||||
int toku_ft_log_del (TOKUTXN txn, FT_HANDLE brt, const DBT *key) __attribute__ ((warn_unused_result));
|
||||
void toku_ft_log_put_multiple (TOKUTXN txn, FT_HANDLE src_ft, FT_HANDLE *brts, int num_fts, const DBT *key, const DBT *val);
|
||||
void toku_ft_log_put (TOKUTXN txn, FT_HANDLE brt, const DBT *key, const DBT *val);
|
||||
void toku_ft_log_del_multiple (TOKUTXN txn, FT_HANDLE src_ft, FT_HANDLE *brts, int num_fts, const DBT *key, const DBT *val);
|
||||
void toku_ft_log_del (TOKUTXN txn, FT_HANDLE brt, const DBT *key);
|
||||
|
||||
// Effect: Delete a key from a brt
|
||||
// Returns 0 if successful
|
||||
int toku_ft_delete (FT_HANDLE brt, DBT *k, TOKUTXN txn) __attribute__ ((warn_unused_result));
|
||||
void toku_ft_delete (FT_HANDLE brt, DBT *k, TOKUTXN txn);
|
||||
|
||||
// Effect: Delete a key from a brt if the oplsn is newer than the brt lsn. This function is called during recovery.
|
||||
// Returns 0 if successful
|
||||
int toku_ft_maybe_delete (FT_HANDLE brt, DBT *k, TOKUTXN txn, bool oplsn_valid, LSN oplsn, bool do_logging) __attribute__ ((warn_unused_result));
|
||||
void toku_ft_maybe_delete (FT_HANDLE brt, DBT *k, TOKUTXN txn, bool oplsn_valid, LSN oplsn, bool do_logging);
|
||||
|
||||
int toku_ft_send_insert(FT_HANDLE brt, DBT *key, DBT *val, XIDS xids, enum ft_msg_type type) __attribute__ ((warn_unused_result));
|
||||
int toku_ft_send_delete(FT_HANDLE brt, DBT *key, XIDS xids) __attribute__ ((warn_unused_result));
|
||||
int toku_ft_send_commit_any(FT_HANDLE brt, DBT *key, XIDS xids) __attribute__ ((warn_unused_result));
|
||||
void toku_ft_send_insert(FT_HANDLE brt, DBT *key, DBT *val, XIDS xids, enum ft_msg_type type);
|
||||
void toku_ft_send_delete(FT_HANDLE brt, DBT *key, XIDS xids);
|
||||
void toku_ft_send_commit_any(FT_HANDLE brt, DBT *key, XIDS xids);
|
||||
|
||||
int toku_close_ft_handle_nolsn (FT_HANDLE, char **error_string) __attribute__ ((warn_unused_result));
|
||||
|
||||
int toku_ft_handle_set_panic(FT_HANDLE brt, int panic, const char *panic_string) __attribute__ ((warn_unused_result));
|
||||
|
||||
int toku_dump_ft (FILE *,FT_HANDLE brt) __attribute__ ((warn_unused_result));
|
||||
|
||||
extern int toku_ft_debug_mode;
|
||||
|
@ -200,7 +192,7 @@ int toku_ft_cursor_get_both_range(FT_CURSOR cursor, DBT *key, DBT *val, FT_GET_C
|
|||
int toku_ft_cursor_get_both_range_reverse(FT_CURSOR cursor, DBT *key, DBT *val, FT_GET_CALLBACK_FUNCTION getf, void *getf_v) __attribute__ ((warn_unused_result));
|
||||
|
||||
int toku_ft_cursor_delete(FT_CURSOR cursor, int flags, TOKUTXN) __attribute__ ((warn_unused_result));
|
||||
int toku_ft_cursor_close (FT_CURSOR curs) __attribute__ ((warn_unused_result));
|
||||
void toku_ft_cursor_close (FT_CURSOR curs);
|
||||
bool toku_ft_cursor_uninitialized(FT_CURSOR c) __attribute__ ((warn_unused_result));
|
||||
|
||||
void toku_ft_cursor_peek(FT_CURSOR cursor, const DBT **pkey, const DBT **pval);
|
||||
|
@ -214,8 +206,7 @@ enum ft_flags {
|
|||
TOKU_DB_VALCMP_BUILTIN_13 = (1<<3),
|
||||
};
|
||||
|
||||
int
|
||||
toku_ft_keyrange (FT_HANDLE brt, DBT *key, uint64_t *less, uint64_t *equal, uint64_t *greater) __attribute__ ((warn_unused_result));
|
||||
void toku_ft_keyrange(FT_HANDLE brt, DBT *key, uint64_t *less, uint64_t *equal, uint64_t *greater);
|
||||
|
||||
struct ftstat64_s {
|
||||
uint64_t nkeys; /* estimate how many unique keys (even when flattened this may be an estimate) */
|
||||
|
@ -228,8 +219,7 @@ struct ftstat64_s {
|
|||
uint64_t verify_time_sec; /* time of last verification, in seconds */
|
||||
};
|
||||
|
||||
int
|
||||
toku_ft_handle_stat64 (FT_HANDLE, TOKUTXN, struct ftstat64_s *stat) __attribute__ ((warn_unused_result));
|
||||
void toku_ft_handle_stat64 (FT_HANDLE, TOKUTXN, struct ftstat64_s *stat);
|
||||
|
||||
int toku_ft_layer_init(void) __attribute__ ((warn_unused_result));
|
||||
void toku_ft_open_close_lock(void);
|
||||
|
|
|
@ -149,8 +149,6 @@ deserialize_ft_versioned(int fd, struct rbuf *rb, FT *ftp, uint32_t version)
|
|||
|
||||
XCALLOC(ft);
|
||||
ft->checkpoint_header = NULL;
|
||||
ft->panic = 0;
|
||||
ft->panic_string = 0;
|
||||
toku_list_init(&ft->live_ft_handles);
|
||||
|
||||
//version MUST be in network order on disk regardless of disk order
|
||||
|
@ -364,10 +362,9 @@ exit:
|
|||
return r;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
static size_t
|
||||
serialize_ft_min_size (uint32_t version) {
|
||||
uint32_t size = 0;
|
||||
|
||||
size_t size = 0;
|
||||
|
||||
switch(version) {
|
||||
case FT_LAYOUT_VERSION_20:
|
||||
|
@ -418,6 +415,7 @@ serialize_ft_min_size (uint32_t version) {
|
|||
default:
|
||||
lazy_assert(false);
|
||||
}
|
||||
|
||||
lazy_assert(size <= BLOCK_ALLOCATOR_HEADER_RESERVE);
|
||||
return size;
|
||||
}
|
||||
|
@ -654,15 +652,15 @@ exit:
|
|||
}
|
||||
|
||||
|
||||
int toku_serialize_ft_size (FT_HEADER h) {
|
||||
uint32_t size = serialize_ft_min_size(h->layout_version);
|
||||
size_t toku_serialize_ft_size (FT_HEADER h) {
|
||||
size_t size = serialize_ft_min_size(h->layout_version);
|
||||
//There is no dynamic data.
|
||||
lazy_assert(size <= BLOCK_ALLOCATOR_HEADER_RESERVE);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
int toku_serialize_ft_to_wbuf (
|
||||
void toku_serialize_ft_to_wbuf (
|
||||
struct wbuf *wbuf,
|
||||
FT_HEADER h,
|
||||
DISKOFF translation_location_on_disk,
|
||||
|
@ -700,59 +698,47 @@ int toku_serialize_ft_to_wbuf (
|
|||
uint32_t checksum = x1764_finish(&wbuf->checksum);
|
||||
wbuf_int(wbuf, checksum);
|
||||
lazy_assert(wbuf->ndone == wbuf->size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int toku_serialize_ft_to (int fd, FT_HEADER h, BLOCK_TABLE blocktable, CACHEFILE cf) {
|
||||
int rr = 0;
|
||||
void toku_serialize_ft_to (int fd, FT_HEADER h, BLOCK_TABLE blocktable, CACHEFILE cf) {
|
||||
lazy_assert(h->type==FT_CHECKPOINT_INPROGRESS);
|
||||
struct wbuf w_translation;
|
||||
int64_t size_translation;
|
||||
int64_t address_translation;
|
||||
{
|
||||
//Must serialize translation first, to get address,size for header.
|
||||
toku_serialize_translation_to_wbuf(blocktable, fd, &w_translation,
|
||||
&address_translation,
|
||||
&size_translation);
|
||||
lazy_assert(size_translation==w_translation.size);
|
||||
}
|
||||
|
||||
//Must serialize translation first, to get address,size for header.
|
||||
toku_serialize_translation_to_wbuf(blocktable, fd, &w_translation,
|
||||
&address_translation,
|
||||
&size_translation);
|
||||
lazy_assert(size_translation == w_translation.size);
|
||||
|
||||
struct wbuf w_main;
|
||||
unsigned int size_main = toku_serialize_ft_size(h);
|
||||
{
|
||||
wbuf_init(&w_main, toku_xmalloc(size_main), size_main);
|
||||
{
|
||||
int r=toku_serialize_ft_to_wbuf(&w_main, h, address_translation, size_translation);
|
||||
lazy_assert_zero(r);
|
||||
}
|
||||
lazy_assert(w_main.ndone==size_main);
|
||||
size_t size_main = toku_serialize_ft_size(h);
|
||||
wbuf_init(&w_main, toku_xmalloc(size_main), size_main);
|
||||
toku_serialize_ft_to_wbuf(&w_main, h, address_translation, size_translation);
|
||||
lazy_assert(w_main.ndone == size_main);
|
||||
|
||||
//Actual Write translation table
|
||||
toku_os_full_pwrite(fd, w_translation.buf, size_translation, address_translation);
|
||||
|
||||
//Everything but the header MUST be on disk before header starts.
|
||||
//Otherwise we will think the header is good and some blocks might not
|
||||
//yet be on disk.
|
||||
//If the header has a cachefile we need to do cachefile fsync (to
|
||||
//prevent crash if we redirected to dev null)
|
||||
//If there is no cachefile we still need to do an fsync.
|
||||
if (cf) {
|
||||
toku_cachefile_fsync(cf);
|
||||
}
|
||||
{
|
||||
//Actual Write translation table
|
||||
toku_os_full_pwrite(fd, w_translation.buf,
|
||||
size_translation, address_translation);
|
||||
}
|
||||
{
|
||||
//Everything but the header MUST be on disk before header starts.
|
||||
//Otherwise we will think the header is good and some blocks might not
|
||||
//yet be on disk.
|
||||
//If the header has a cachefile we need to do cachefile fsync (to
|
||||
//prevent crash if we redirected to dev null)
|
||||
//If there is no cachefile we still need to do an fsync.
|
||||
if (cf) {
|
||||
rr = toku_cachefile_fsync(cf);
|
||||
}
|
||||
else {
|
||||
rr = toku_file_fsync(fd);
|
||||
}
|
||||
if (rr==0) {
|
||||
//Alternate writing header to two locations:
|
||||
// Beginning (0) or BLOCK_ALLOCATOR_HEADER_RESERVE
|
||||
toku_off_t main_offset;
|
||||
main_offset = (h->checkpoint_count & 0x1) ? 0 : BLOCK_ALLOCATOR_HEADER_RESERVE;
|
||||
toku_os_full_pwrite(fd, w_main.buf, w_main.ndone, main_offset);
|
||||
}
|
||||
else {
|
||||
toku_file_fsync(fd);
|
||||
}
|
||||
|
||||
//Alternate writing header to two locations:
|
||||
// Beginning (0) or BLOCK_ALLOCATOR_HEADER_RESERVE
|
||||
toku_off_t main_offset;
|
||||
main_offset = (h->checkpoint_count & 0x1) ? 0 : BLOCK_ALLOCATOR_HEADER_RESERVE;
|
||||
toku_os_full_pwrite(fd, w_main.buf, w_main.ndone, main_offset);
|
||||
toku_free(w_main.buf);
|
||||
toku_free(w_translation.buf);
|
||||
return rr;
|
||||
}
|
||||
|
|
|
@ -208,8 +208,7 @@ int toku_testsetup_insert_to_nonleaf (FT_HANDLE brt, BLOCKNUM blocknum, enum ft_
|
|||
|
||||
XIDS xids_0 = xids_get_root_xids();
|
||||
MSN msn = next_dummymsn();
|
||||
r = toku_bnc_insert_msg(BNC(node, childnum), key, keylen, val, vallen, cmdtype, msn, xids_0, true, NULL, testhelper_string_key_cmp);
|
||||
assert(r==0);
|
||||
toku_bnc_insert_msg(BNC(node, childnum), key, keylen, val, vallen, cmdtype, msn, xids_0, true, NULL, testhelper_string_key_cmp);
|
||||
// Hack to get the test working. The problem is that this test
|
||||
// is directly queueing something in a FIFO instead of
|
||||
// using brt APIs.
|
||||
|
|
212
ft/ft.cc
212
ft/ft.cc
|
@ -31,8 +31,6 @@ toku_reset_root_xid_that_created(FT ft, TXNID new_root_xid_that_created) {
|
|||
|
||||
static void
|
||||
ft_destroy(FT ft) {
|
||||
if (!ft->panic) assert(!ft->checkpoint_header);
|
||||
|
||||
//header and checkpoint_header have same Blocktable pointer
|
||||
//cannot destroy since it is still in use by CURRENT
|
||||
assert(ft->h->type == FT_CURRENT);
|
||||
|
@ -51,7 +49,6 @@ static void
|
|||
ft_copy_for_checkpoint_unlocked(FT ft, LSN checkpoint_lsn) {
|
||||
assert(ft->h->type == FT_CURRENT);
|
||||
assert(ft->checkpoint_header == NULL);
|
||||
assert(ft->panic==0);
|
||||
|
||||
FT_HEADER XMEMDUP(ch, ft->h);
|
||||
ch->type = FT_CHECKPOINT_INPROGRESS; //Different type
|
||||
|
@ -93,7 +90,7 @@ toku_ft_release_reflock(FT ft) {
|
|||
//
|
||||
|
||||
// maps to cf->log_fassociate_during_checkpoint
|
||||
static int
|
||||
static void
|
||||
ft_log_fassociate_during_checkpoint (CACHEFILE cf, void *header_v) {
|
||||
FT ft = (FT) header_v;
|
||||
char* fname_in_env = toku_cachefile_fname_in_env(cf);
|
||||
|
@ -102,14 +99,12 @@ ft_log_fassociate_during_checkpoint (CACHEFILE cf, void *header_v) {
|
|||
TOKULOGGER logger = toku_cachefile_logger(cf);
|
||||
FILENUM filenum = toku_cachefile_filenum(cf);
|
||||
bool unlink_on_close = toku_cachefile_is_unlink_on_close(cf);
|
||||
int r = toku_log_fassociate(logger, NULL, 0, filenum, ft->h->flags, bs, unlink_on_close);
|
||||
return r;
|
||||
toku_log_fassociate(logger, NULL, 0, filenum, ft->h->flags, bs, unlink_on_close);
|
||||
}
|
||||
|
||||
// maps to cf->log_suppress_rollback_during_checkpoint
|
||||
static int
|
||||
static void
|
||||
ft_log_suppress_rollback_during_checkpoint (CACHEFILE cf, void *header_v) {
|
||||
int r = 0;
|
||||
FT h = (FT) header_v;
|
||||
TXNID xid = h->txnid_that_created_or_locked_when_empty;
|
||||
if (xid != TXNID_NONE) {
|
||||
|
@ -119,9 +114,8 @@ ft_log_suppress_rollback_during_checkpoint (CACHEFILE cf, void *header_v) {
|
|||
// We don't have access to the txn here, but the txn is
|
||||
// necessarily already marked as non-readonly. Use NULL.
|
||||
TOKUTXN txn = NULL;
|
||||
r = toku_log_suppress_rollback(logger, NULL, 0, txn, filenum, xid);
|
||||
toku_log_suppress_rollback(logger, NULL, 0, txn, filenum, xid);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
// Maps to cf->begin_checkpoint_userdata
|
||||
|
@ -129,21 +123,16 @@ ft_log_suppress_rollback_during_checkpoint (CACHEFILE cf, void *header_v) {
|
|||
// Has access to fd (it is protected).
|
||||
//
|
||||
// Not reentrant for a single FT (see ft_checkpoint)
|
||||
static int
|
||||
ft_begin_checkpoint (LSN checkpoint_lsn, void *header_v) {
|
||||
static void ft_begin_checkpoint (LSN checkpoint_lsn, void *header_v) {
|
||||
FT ft = (FT) header_v;
|
||||
int r = ft->panic;
|
||||
if (r==0) {
|
||||
// hold lock around copying and clearing of dirty bit
|
||||
toku_ft_lock (ft);
|
||||
assert(ft->h->type == FT_CURRENT);
|
||||
assert(ft->checkpoint_header == NULL);
|
||||
ft_copy_for_checkpoint_unlocked(ft, checkpoint_lsn);
|
||||
ft->h->dirty = 0; // this is only place this bit is cleared (in currentheader)
|
||||
toku_block_translation_note_start_checkpoint_unlocked(ft->blocktable);
|
||||
toku_ft_unlock (ft);
|
||||
}
|
||||
return r;
|
||||
// hold lock around copying and clearing of dirty bit
|
||||
toku_ft_lock (ft);
|
||||
assert(ft->h->type == FT_CURRENT);
|
||||
assert(ft->checkpoint_header == NULL);
|
||||
ft_copy_for_checkpoint_unlocked(ft, checkpoint_lsn);
|
||||
ft->h->dirty = 0; // this is only place this bit is cleared (in currentheader)
|
||||
toku_block_translation_note_start_checkpoint_unlocked(ft->blocktable);
|
||||
toku_ft_unlock (ft);
|
||||
}
|
||||
|
||||
// #4922: Hack to remove data corruption race condition.
|
||||
|
@ -180,7 +169,6 @@ ft_checkpoint (CACHEFILE cf, int fd, void *header_v) {
|
|||
FT ft = (FT) header_v;
|
||||
FT_HEADER ch = ft->checkpoint_header;
|
||||
int r = 0;
|
||||
if (ft->panic!=0) goto handle_error;
|
||||
//printf("%s:%d allocated_limit=%lu writing queue to %lu\n", __FILE__, __LINE__,
|
||||
// block_allocator_allocated_limit(h->block_allocator), h->unused_blocks.b*h->nodesize);
|
||||
assert(ch);
|
||||
|
@ -198,15 +186,11 @@ ft_checkpoint (CACHEFILE cf, int fd, void *header_v) {
|
|||
ft_hack_highest_unused_msn_for_upgrade_for_checkpoint(ft);
|
||||
|
||||
// write translation and header to disk (or at least to OS internal buffer)
|
||||
r = toku_serialize_ft_to(fd, ch, ft->blocktable, ft->cf);
|
||||
if (r!=0) goto handle_error;
|
||||
toku_serialize_ft_to(fd, ch, ft->blocktable, ft->cf);
|
||||
ch->dirty = 0; // this is only place this bit is cleared (in checkpoint_header)
|
||||
|
||||
// fsync the cachefile
|
||||
r = toku_cachefile_fsync(cf);
|
||||
if (r!=0) {
|
||||
goto handle_error;
|
||||
}
|
||||
toku_cachefile_fsync(cf);
|
||||
ft->h->checkpoint_count++; // checkpoint succeeded, next checkpoint will save to alternate header location
|
||||
ft->h->checkpoint_lsn = ch->checkpoint_lsn; //Header updated.
|
||||
}
|
||||
|
@ -215,8 +199,7 @@ ft_checkpoint (CACHEFILE cf, int fd, void *header_v) {
|
|||
}
|
||||
if (0) {
|
||||
handle_error:
|
||||
if (ft->panic) r = ft->panic;
|
||||
else toku_block_translation_note_failed_checkpoint(ft->blocktable);
|
||||
toku_block_translation_note_failed_checkpoint(ft->blocktable);
|
||||
}
|
||||
return r;
|
||||
|
||||
|
@ -226,75 +209,56 @@ handle_error:
|
|||
// free unused disk space
|
||||
// (i.e. tell BlockAllocator to liberate blocks used by previous checkpoint).
|
||||
// Must have access to fd (protected)
|
||||
static int
|
||||
ft_end_checkpoint (CACHEFILE UU(cachefile), int fd, void *header_v) {
|
||||
static void ft_end_checkpoint (CACHEFILE UU(cachefile), int fd, void *header_v) {
|
||||
FT ft = (FT) header_v;
|
||||
int r = ft->panic;
|
||||
if (r==0) {
|
||||
assert(ft->h->type == FT_CURRENT);
|
||||
toku_block_translation_note_end_checkpoint(ft->blocktable, fd);
|
||||
}
|
||||
if (ft->checkpoint_header) { // could be NULL only if panic was true at begin_checkpoint
|
||||
assert(ft->h->type == FT_CURRENT);
|
||||
toku_block_translation_note_end_checkpoint(ft->blocktable, fd);
|
||||
if (ft->checkpoint_header) {
|
||||
toku_free(ft->checkpoint_header);
|
||||
ft->checkpoint_header = NULL;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
// maps to cf->close_userdata
|
||||
// Has access to fd (it is protected).
|
||||
static int
|
||||
ft_close (CACHEFILE cachefile, int fd, void *header_v, char **malloced_error_string, bool oplsn_valid, LSN oplsn) {
|
||||
ft_close(CACHEFILE cachefile, int fd, void *header_v, bool oplsn_valid, LSN oplsn) {
|
||||
FT ft = (FT) header_v;
|
||||
assert(ft->h->type == FT_CURRENT);
|
||||
// We already have exclusive access to this field already, so skip the locking.
|
||||
// This should already never fail.
|
||||
invariant(!toku_ft_needed_unlocked(ft));
|
||||
int r = 0;
|
||||
if (ft->panic) {
|
||||
r = ft->panic;
|
||||
} else {
|
||||
assert(ft->cf == cachefile);
|
||||
TOKULOGGER logger = toku_cachefile_logger(cachefile);
|
||||
LSN lsn = ZERO_LSN;
|
||||
//Get LSN
|
||||
if (oplsn_valid) {
|
||||
//Use recovery-specified lsn
|
||||
lsn = oplsn;
|
||||
//Recovery cannot reduce lsn of a header.
|
||||
if (lsn.lsn < ft->h->checkpoint_lsn.lsn)
|
||||
lsn = ft->h->checkpoint_lsn;
|
||||
}
|
||||
else {
|
||||
//Get LSN from logger
|
||||
lsn = ZERO_LSN; // if there is no logger, we use zero for the lsn
|
||||
if (logger) {
|
||||
char* fname_in_env = toku_cachefile_fname_in_env(cachefile);
|
||||
assert(fname_in_env);
|
||||
BYTESTRING bs = {.len=(uint32_t) strlen(fname_in_env), .data=fname_in_env};
|
||||
r = toku_log_fclose(logger, &lsn, ft->h->dirty, bs, toku_cachefile_filenum(cachefile)); // flush the log on close (if new header is being written), otherwise it might not make it out.
|
||||
if (r!=0) return r;
|
||||
}
|
||||
}
|
||||
if (ft->h->dirty) { // this is the only place this bit is tested (in currentheader)
|
||||
if (logger) { //Rollback cachefile MUST NOT BE CLOSED DIRTY
|
||||
//It can be checkpointed only via 'checkpoint'
|
||||
assert(logger->rollback_cachefile != cachefile);
|
||||
}
|
||||
int r2;
|
||||
//assert(lsn.lsn!=0);
|
||||
r2 = ft_begin_checkpoint(lsn, header_v);
|
||||
if (r==0) r = r2;
|
||||
r2 = ft_checkpoint(cachefile, fd, ft);
|
||||
if (r==0) r = r2;
|
||||
r2 = ft_end_checkpoint(cachefile, fd, header_v);
|
||||
if (r==0) r = r2;
|
||||
if (!ft->panic) assert(!ft->h->dirty); // dirty bit should be cleared by begin_checkpoint and never set again (because we're closing the dictionary)
|
||||
assert(ft->cf == cachefile);
|
||||
TOKULOGGER logger = toku_cachefile_logger(cachefile);
|
||||
LSN lsn = ZERO_LSN;
|
||||
//Get LSN
|
||||
if (oplsn_valid) {
|
||||
//Use recovery-specified lsn
|
||||
lsn = oplsn;
|
||||
//Recovery cannot reduce lsn of a header.
|
||||
if (lsn.lsn < ft->h->checkpoint_lsn.lsn)
|
||||
lsn = ft->h->checkpoint_lsn;
|
||||
}
|
||||
else {
|
||||
//Get LSN from logger
|
||||
lsn = ZERO_LSN; // if there is no logger, we use zero for the lsn
|
||||
if (logger) {
|
||||
char* fname_in_env = toku_cachefile_fname_in_env(cachefile);
|
||||
assert(fname_in_env);
|
||||
BYTESTRING bs = {.len=(uint32_t) strlen(fname_in_env), .data=fname_in_env};
|
||||
toku_log_fclose(logger, &lsn, ft->h->dirty, bs, toku_cachefile_filenum(cachefile)); // flush the log on close (if new header is being written), otherwise it might not make it out.
|
||||
}
|
||||
}
|
||||
if (malloced_error_string) *malloced_error_string = ft->panic_string;
|
||||
if (r == 0) {
|
||||
r = ft->panic;
|
||||
if (ft->h->dirty) { // this is the only place this bit is tested (in currentheader)
|
||||
if (logger) { //Rollback cachefile MUST NOT BE CLOSED DIRTY
|
||||
//It can be checkpointed only via 'checkpoint'
|
||||
assert(logger->rollback_cachefile != cachefile);
|
||||
}
|
||||
ft_begin_checkpoint(lsn, header_v);
|
||||
r = ft_checkpoint(cachefile, fd, ft);
|
||||
ft_end_checkpoint(cachefile, fd, header_v);
|
||||
assert(!ft->h->dirty); // dirty bit should be cleared by begin_checkpoint and never set again (because we're closing the dictionary)
|
||||
}
|
||||
toku_ft_free(ft);
|
||||
return r;
|
||||
|
@ -303,20 +267,14 @@ ft_close (CACHEFILE cachefile, int fd, void *header_v, char **malloced_error_str
|
|||
// maps to cf->note_pin_by_checkpoint
|
||||
//Must be protected by ydb lock.
|
||||
//Is only called by checkpoint begin, which holds it
|
||||
static int
|
||||
ft_note_pin_by_checkpoint (CACHEFILE UU(cachefile), void *header_v)
|
||||
{
|
||||
//Set arbitrary brt (for given header) as pinned by checkpoint.
|
||||
//Only one can be pinned (only one checkpoint at a time), but not worth verifying.
|
||||
FT ft = (FT) header_v;
|
||||
|
||||
static void ft_note_pin_by_checkpoint (CACHEFILE UU(cachefile), void *header_v) {
|
||||
// Note: open_close lock is held by checkpoint begin
|
||||
FT ft = (FT) header_v;
|
||||
toku_ft_grab_reflock(ft);
|
||||
assert(!ft->pinned_by_checkpoint);
|
||||
assert(toku_ft_needed_unlocked(ft));
|
||||
ft->pinned_by_checkpoint = true;
|
||||
toku_ft_release_reflock(ft);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -325,30 +283,27 @@ unpin_by_checkpoint_callback(FT ft, void *extra)
|
|||
{
|
||||
invariant(extra == NULL);
|
||||
invariant(ft->pinned_by_checkpoint);
|
||||
ft->pinned_by_checkpoint = false; //Unpin
|
||||
ft->pinned_by_checkpoint = false;
|
||||
}
|
||||
|
||||
// maps to cf->note_unpin_by_checkpoint
|
||||
//Must be protected by ydb lock.
|
||||
//Called by end_checkpoint, which grabs ydb lock around note_unpin
|
||||
static int
|
||||
ft_note_unpin_by_checkpoint (CACHEFILE UU(cachefile), void *header_v)
|
||||
{
|
||||
static void ft_note_unpin_by_checkpoint (CACHEFILE UU(cachefile), void *header_v) {
|
||||
FT ft = (FT) header_v;
|
||||
toku_ft_remove_reference(ft, false, ZERO_LSN, unpin_by_checkpoint_callback, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// End of Functions that are callbacks to the cachefile
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void toku_node_save_ct_pair(void *value_data, PAIR p) {
|
||||
FTNODE CAST_FROM_VOIDP(node, value_data);
|
||||
node->ct_pair = p;
|
||||
}
|
||||
|
||||
// TODO: can't fail
|
||||
static int setup_initial_ft_root_node (FT ft, BLOCKNUM blocknum) {
|
||||
FTNODE XMALLOC(node);
|
||||
toku_initialize_empty_ftnode(node, blocknum, 0, 1, ft->h->layout_version, ft->h->flags);
|
||||
|
@ -356,15 +311,12 @@ static int setup_initial_ft_root_node (FT ft, BLOCKNUM blocknum) {
|
|||
|
||||
uint32_t fullhash = toku_cachetable_hash(ft->cf, blocknum);
|
||||
node->fullhash = fullhash;
|
||||
int r = toku_cachetable_put(ft->cf, blocknum, fullhash,
|
||||
node, make_ftnode_pair_attr(node),
|
||||
get_write_callbacks_for_node(ft),
|
||||
toku_node_save_ct_pair);
|
||||
if (r != 0)
|
||||
toku_free(node);
|
||||
else
|
||||
toku_unpin_ftnode(ft, node);
|
||||
return r;
|
||||
toku_cachetable_put(ft->cf, blocknum, fullhash,
|
||||
node, make_ftnode_pair_attr(node),
|
||||
get_write_callbacks_for_node(ft),
|
||||
toku_node_save_ct_pair);
|
||||
toku_unpin_ftnode(ft, node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -554,16 +506,10 @@ toku_ft_has_one_reference_unlocked(FT ft) {
|
|||
|
||||
// evict a ft from memory by closing its cachefile. any future work
|
||||
// will have to read in the ft in a new cachefile and new FT object.
|
||||
int toku_ft_evict_from_memory(FT ft, char **error_string, bool oplsn_valid, LSN oplsn) {
|
||||
int toku_ft_evict_from_memory(FT ft, bool oplsn_valid, LSN oplsn) {
|
||||
int r = 0;
|
||||
assert(ft->cf);
|
||||
if (error_string) {
|
||||
assert(*error_string == 0);
|
||||
}
|
||||
r = toku_cachefile_close(&ft->cf, error_string, oplsn_valid, oplsn);
|
||||
if (r == 0 && error_string) {
|
||||
assert(*error_string == 0);
|
||||
}
|
||||
r = toku_cachefile_close(&ft->cf, oplsn_valid, oplsn);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -646,20 +592,16 @@ toku_ft_init(FT ft,
|
|||
// Open a brt for use by redirect. The new brt must have the same dict_id as the old_ft passed in. (FILENUM is assigned by the ft_handle_open() function.)
|
||||
static int
|
||||
ft_handle_open_for_redirect(FT_HANDLE *new_ftp, const char *fname_in_env, TOKUTXN txn, FT old_h) {
|
||||
int r;
|
||||
FT_HANDLE t;
|
||||
assert(old_h->dict_id.dictid != DICTIONARY_ID_NONE.dictid);
|
||||
r = toku_ft_handle_create(&t);
|
||||
assert_zero(r);
|
||||
r = toku_ft_set_bt_compare(t, old_h->compare_fun);
|
||||
assert_zero(r);
|
||||
r = toku_ft_set_update(t, old_h->update_fun);
|
||||
assert_zero(r);
|
||||
toku_ft_handle_create(&t);
|
||||
toku_ft_set_bt_compare(t, old_h->compare_fun);
|
||||
toku_ft_set_update(t, old_h->update_fun);
|
||||
toku_ft_handle_set_nodesize(t, old_h->h->nodesize);
|
||||
toku_ft_handle_set_basementnodesize(t, old_h->h->basementnodesize);
|
||||
toku_ft_handle_set_compression_method(t, old_h->h->compression_method);
|
||||
CACHETABLE ct = toku_cachefile_get_cachetable(old_h->cf);
|
||||
r = toku_ft_handle_open_with_dict_id(t, fname_in_env, 0, 0, ct, txn, old_h->dict_id);
|
||||
int r = toku_ft_handle_open_with_dict_id(t, fname_in_env, 0, 0, ct, txn, old_h->dict_id);
|
||||
assert_zero(r);
|
||||
assert(t->ft->dict_id.dictid == old_h->dict_id.dictid);
|
||||
|
||||
|
@ -813,13 +755,11 @@ toku_dictionary_redirect (const char *dst_fname_in_env, FT_HANDLE old_ft_h, TOKU
|
|||
|
||||
FILENUM old_filenum = toku_cachefile_filenum(old_ft->cf);
|
||||
FILENUM new_filenum = toku_cachefile_filenum(new_ft->cf);
|
||||
r = toku_logger_save_rollback_dictionary_redirect(txn, old_filenum, new_filenum);
|
||||
assert_zero(r);
|
||||
toku_logger_save_rollback_dictionary_redirect(txn, old_filenum, new_filenum);
|
||||
|
||||
TXNID xid = toku_txn_get_txnid(txn);
|
||||
toku_ft_suppress_rollbacks(new_ft, txn);
|
||||
r = toku_log_suppress_rollback(txn->logger, NULL, 0, txn, new_filenum, xid);
|
||||
assert_zero(r);
|
||||
toku_log_suppress_rollback(txn->logger, NULL, 0, txn, new_filenum, xid);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
@ -867,17 +807,6 @@ LSN toku_ft_checkpoint_lsn(FT ft) {
|
|||
return ft->h->checkpoint_lsn;
|
||||
}
|
||||
|
||||
int toku_ft_set_panic(FT ft, int panic, const char *panic_string) {
|
||||
if (ft->panic == 0) {
|
||||
ft->panic = panic;
|
||||
if (ft->panic_string) {
|
||||
toku_free(ft->panic_string);
|
||||
}
|
||||
ft->panic_string = toku_strdup(panic_string);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
toku_ft_stat64 (FT ft, struct ftstat64_s *s) {
|
||||
s->fsize = toku_cachefile_size(ft->cf);
|
||||
|
@ -986,11 +915,8 @@ toku_ft_remove_reference(FT ft, bool oplsn_valid, LSN oplsn, remove_ft_ref_callb
|
|||
}
|
||||
if (!needed) {
|
||||
// close header
|
||||
char *error_string = NULL;
|
||||
int r;
|
||||
r = toku_ft_evict_from_memory(ft, &error_string, oplsn_valid, oplsn);
|
||||
int r = toku_ft_evict_from_memory(ft, oplsn_valid, oplsn);
|
||||
assert_zero(r);
|
||||
assert(error_string == NULL);
|
||||
}
|
||||
|
||||
toku_ft_open_close_unlock();
|
||||
|
|
5
ft/ft.h
5
ft/ft.h
|
@ -18,7 +18,7 @@
|
|||
// unlink a ft from the filesystem with or without a txn.
|
||||
// if with a txn, then the unlink happens on commit.
|
||||
void toku_ft_unlink(FT_HANDLE handle);
|
||||
int toku_ft_unlink_on_commit(FT_HANDLE handle, TOKUTXN txn) __attribute__((__warn_unused_result__));
|
||||
void toku_ft_unlink_on_commit(FT_HANDLE handle, TOKUTXN txn);
|
||||
|
||||
//Effect: suppresses rollback logs
|
||||
void toku_ft_suppress_rollbacks(FT h, TOKUTXN txn);
|
||||
|
@ -39,7 +39,7 @@ bool toku_ft_has_one_reference_unlocked(FT ft);
|
|||
|
||||
// evict a ft from memory by closing its cachefile. any future work
|
||||
// will have to read in the ft in a new cachefile and new FT object.
|
||||
int toku_ft_evict_from_memory(FT ft, char **error_string, bool oplsn_valid, LSN oplsn) __attribute__ ((warn_unused_result));
|
||||
int toku_ft_evict_from_memory(FT ft, bool oplsn_valid, LSN oplsn) __attribute__ ((warn_unused_result));
|
||||
|
||||
FT_HANDLE toku_ft_get_only_existing_ft_handle(FT h);
|
||||
|
||||
|
@ -69,7 +69,6 @@ void toku_ft_remove_txn_ref(FT h);
|
|||
void toku_calculate_root_offset_pointer ( FT h, CACHEKEY* root_key, uint32_t *roothash);
|
||||
void toku_ft_set_new_root_blocknum(FT h, CACHEKEY new_root_key);
|
||||
LSN toku_ft_checkpoint_lsn(FT h) __attribute__ ((warn_unused_result));
|
||||
int toku_ft_set_panic(FT h, int panic, const char *panic_string) __attribute__ ((warn_unused_result));
|
||||
void toku_ft_stat64 (FT h, struct ftstat64_s *s);
|
||||
|
||||
// unconditionally set the descriptor for an open FT. can't do this when
|
||||
|
|
|
@ -1109,32 +1109,21 @@ void destroy_nonleaf_childinfo (NONLEAF_CHILDINFO nl)
|
|||
toku_free(nl);
|
||||
}
|
||||
|
||||
int
|
||||
read_block_from_fd_into_rbuf(
|
||||
void read_block_from_fd_into_rbuf(
|
||||
int fd,
|
||||
BLOCKNUM blocknum,
|
||||
FT h,
|
||||
struct rbuf *rb
|
||||
)
|
||||
{
|
||||
if (h->panic) {
|
||||
toku_trace("panic set, will not read block from fd into buf");
|
||||
return h->panic;
|
||||
}
|
||||
toku_trace("deserial start nopanic");
|
||||
|
||||
// get the file offset and block size for the block
|
||||
DISKOFF offset, size;
|
||||
toku_translate_blocknum_to_offset_size(h->blocktable, blocknum, &offset, &size);
|
||||
uint8_t *XMALLOC_N(size, raw_block);
|
||||
rbuf_init(rb, raw_block, size);
|
||||
{
|
||||
// read the block
|
||||
ssize_t rlen = toku_os_pread(fd, raw_block, size, offset);
|
||||
lazy_assert((DISKOFF)rlen == size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
// read the block
|
||||
ssize_t rlen = toku_os_pread(fd, raw_block, size, offset);
|
||||
lazy_assert((DISKOFF)rlen == size);
|
||||
}
|
||||
|
||||
static const int read_header_heuristic_max = 32*1024;
|
||||
|
@ -1144,7 +1133,6 @@ static const int read_header_heuristic_max = 32*1024;
|
|||
static void read_ftnode_header_from_fd_into_rbuf_if_small_enough (int fd, BLOCKNUM blocknum, FT h, struct rbuf *rb)
|
||||
// Effect: If the header part of the node is small enough, then read it into the rbuf. The rbuf will be allocated to be big enough in any case.
|
||||
{
|
||||
assert(!h->panic);
|
||||
DISKOFF offset, size;
|
||||
toku_translate_blocknum_to_offset_size(h->blocktable, blocknum, &offset, &size);
|
||||
DISKOFF read_size = MIN(read_header_heuristic_max, size);
|
||||
|
@ -2424,17 +2412,12 @@ deserialize_ftnode_from_fd(int fd,
|
|||
STAT64INFO info)
|
||||
{
|
||||
struct rbuf rb = RBUF_INITIALIZER;
|
||||
int r = 0;
|
||||
r = read_block_from_fd_into_rbuf(fd, blocknum, bfe->h, &rb);
|
||||
if (r != 0) {
|
||||
goto cleanup;
|
||||
} // if we were successful, then we are done.
|
||||
read_block_from_fd_into_rbuf(fd, blocknum, bfe->h, &rb);
|
||||
|
||||
r = deserialize_ftnode_from_rbuf(ftnode, ndd, blocknum, fullhash, bfe, info, &rb, fd);
|
||||
int r = deserialize_ftnode_from_rbuf(ftnode, ndd, blocknum, fullhash, bfe, info, &rb, fd);
|
||||
if (r != 0) {
|
||||
dump_bad_block(rb.buf,rb.size);
|
||||
}
|
||||
cleanup:
|
||||
toku_free(rb.buf);
|
||||
return r;
|
||||
}
|
||||
|
@ -2533,6 +2516,7 @@ serialize_rollback_log_node_to_buf(ROLLBACK_LOG_NODE log, char *buf, size_t calc
|
|||
lazy_assert(calculated_size==wb.ndone);
|
||||
}
|
||||
|
||||
// TODO: can't fail. assert on ENOMEM for compressed_buf...
|
||||
static int
|
||||
serialize_uncompressed_block_to_memory(char * uncompressed_buf,
|
||||
int n_sub_blocks,
|
||||
|
@ -2856,9 +2840,6 @@ read_and_decompress_block_from_fd_into_rbuf(int fd, BLOCKNUM blocknum,
|
|||
/* out */ int *layout_version_p) {
|
||||
int r = 0;
|
||||
if (0) printf("Deserializing Block %" PRId64 "\n", blocknum.b);
|
||||
if (h->panic) return h->panic;
|
||||
|
||||
toku_trace("deserial start nopanic");
|
||||
|
||||
// get the file offset and block size for the block
|
||||
DISKOFF offset, size;
|
||||
|
|
|
@ -512,10 +512,9 @@ main (int argc, const char *const argv[]) {
|
|||
int f = open(n, O_RDWR + O_BINARY); assert(f>=0);
|
||||
FT ft;
|
||||
// create a cachefile for the header
|
||||
int r = toku_create_cachetable(&ct, 1<<25, (LSN){0}, 0);
|
||||
assert(r == 0);
|
||||
toku_cachetable_create(&ct, 1<<25, (LSN){0}, 0);
|
||||
CACHEFILE cf = NULL;
|
||||
r = toku_cachetable_openfd (&cf, ct, f, n);
|
||||
int r = toku_cachetable_openfd (&cf, ct, f, n);
|
||||
assert(r==0);
|
||||
dump_header(f, &ft, cf);
|
||||
if (interactive) {
|
||||
|
|
|
@ -2784,7 +2784,7 @@ static int write_translation_table (struct dbout *out, long long *off_of_transla
|
|||
static int
|
||||
write_header (struct dbout *out, long long translation_location_on_disk, long long translation_size_on_disk) {
|
||||
int result = 0;
|
||||
unsigned int size = toku_serialize_ft_size (out->h->h);
|
||||
size_t size = toku_serialize_ft_size(out->h->h);
|
||||
struct wbuf wbuf;
|
||||
char *MALLOC_N(size, buf);
|
||||
if (buf == NULL) {
|
||||
|
|
|
@ -201,13 +201,7 @@ check_block(BLOCKNUM blocknum, int64_t UU(blocksize), int64_t UU(address), void
|
|||
// Let's read the block off of disk and fill a buffer with that
|
||||
// block.
|
||||
struct rbuf rb = RBUF_INITIALIZER;
|
||||
r = read_block_from_fd_into_rbuf(fd, blocknum, ft, &rb);
|
||||
if (r != 0) {
|
||||
// This is impossible without setting the panic member in
|
||||
// the ft, let's just pretend that it is not and exit.
|
||||
printf(" Read block failed.\n");
|
||||
failure++;
|
||||
}
|
||||
read_block_from_fd_into_rbuf(fd, blocknum, ft, &rb);
|
||||
|
||||
// Allocate the node.
|
||||
FTNODE XMALLOC(node);
|
||||
|
|
|
@ -52,11 +52,9 @@ toku_le_cursor_create(LE_CURSOR *le_cursor_result, FT_HANDLE ft_handle, TOKUTXN
|
|||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
toku_le_cursor_close(LE_CURSOR le_cursor) {
|
||||
int result = toku_ft_cursor_close(le_cursor->ft_cursor);
|
||||
void toku_le_cursor_close(LE_CURSOR le_cursor) {
|
||||
toku_ft_cursor_close(le_cursor->ft_cursor);
|
||||
toku_free(le_cursor);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Move to the next leaf entry under the LE_CURSOR
|
||||
|
|
|
@ -25,9 +25,7 @@ typedef struct le_cursor *LE_CURSOR;
|
|||
int toku_le_cursor_create(LE_CURSOR *le_cursor_result, FT_HANDLE brt, TOKUTXN txn);
|
||||
|
||||
// Close and free the LE_CURSOR
|
||||
// Success: returns 0
|
||||
// Failure: returns a non-zero error number
|
||||
int toku_le_cursor_close(LE_CURSOR le_cursor);
|
||||
void toku_le_cursor_close(LE_CURSOR le_cursor);
|
||||
|
||||
// Move to the next leaf entry under the LE_CURSOR
|
||||
// Success: returns zero, calls the getf callback with the getf_v parameter
|
||||
|
|
|
@ -63,10 +63,8 @@ struct tokulogger {
|
|||
bool output_is_available; // this is part of the predicate for the output condition. It's true if no thread is modifying the output (either doing an fsync or otherwise fiddling with the output).
|
||||
|
||||
bool is_open;
|
||||
bool is_panicked;
|
||||
bool write_log_files;
|
||||
bool trim_log_files; // for test purposes
|
||||
int panic_errno;
|
||||
char *directory; // file system directory
|
||||
DIR *dir; // descriptor for directory
|
||||
int fd;
|
||||
|
|
|
@ -156,6 +156,7 @@ verify_clean_shutdown_of_log_version(const char *log_dir, uint32_t version, LSN
|
|||
|
||||
|
||||
// Actually create a log file of the current version, making the environment be of the current version.
|
||||
// TODO: can't fail
|
||||
static int
|
||||
upgrade_log(const char *env_dir, const char *log_dir, LSN last_lsn, TXNID last_xid) { // the real deal
|
||||
int r;
|
||||
|
@ -169,8 +170,7 @@ upgrade_log(const char *env_dir, const char *log_dir, LSN last_lsn, TXNID last_x
|
|||
FOOTPRINT(1);
|
||||
|
||||
{ //Create temporary environment
|
||||
r = toku_create_cachetable(&ct, 1<<25, initial_lsn, NULL);
|
||||
assert(r == 0);
|
||||
toku_cachetable_create(&ct, 1<<25, initial_lsn, NULL);
|
||||
toku_cachetable_set_env_dir(ct, env_dir);
|
||||
r = toku_logger_create(&logger);
|
||||
assert(r == 0);
|
||||
|
@ -184,10 +184,8 @@ upgrade_log(const char *env_dir, const char *log_dir, LSN last_lsn, TXNID last_x
|
|||
assert(r == 0);
|
||||
}
|
||||
{ //Close cachetable and logger
|
||||
r = toku_logger_shutdown(logger);
|
||||
assert(r==0);
|
||||
r = toku_cachetable_close(&ct);
|
||||
assert(r==0);
|
||||
toku_logger_shutdown(logger);
|
||||
toku_cachetable_close(&ct);
|
||||
r = toku_logger_close(&logger);
|
||||
assert(r==0);
|
||||
}
|
||||
|
|
|
@ -395,7 +395,7 @@ generate_log_writer (void) {
|
|||
fprintf(hf, "static const size_t toku_log_%s_overhead = (+4+1+8", lt->name);
|
||||
DO_FIELDS(field_type, lt, fprintf(hf, "+sizeof(%s)", field_type->type));
|
||||
fprintf(hf, "+8);\n");
|
||||
fprintf2(cf, hf, "int toku_log_%s (TOKULOGGER logger, LSN *lsnp, int do_fsync", lt->name);
|
||||
fprintf2(cf, hf, "void toku_log_%s (TOKULOGGER logger, LSN *lsnp, int do_fsync", lt->name);
|
||||
switch (lt->log_begin_action) {
|
||||
case SHOULD_LOG_BEGIN:
|
||||
case ASSERT_BEGIN_WAS_LOGGED: {
|
||||
|
@ -407,8 +407,9 @@ generate_log_writer (void) {
|
|||
DO_FIELDS(field_type, lt, fprintf2(cf, hf, ", %s %s", field_type->type, field_type->name));
|
||||
fprintf(hf, ");\n");
|
||||
fprintf(cf, ") {\n");
|
||||
fprintf(cf, " int r = 0;\n");
|
||||
fprintf(cf, " if (logger==0) return 0;\n");
|
||||
fprintf(cf, " if (logger == NULL) {\n");
|
||||
fprintf(cf, " return;\n");
|
||||
fprintf(cf, " }\n");
|
||||
switch (lt->log_begin_action) {
|
||||
case SHOULD_LOG_BEGIN: {
|
||||
fprintf(cf, " //txn can be NULL during tests\n");
|
||||
|
@ -431,7 +432,7 @@ generate_log_writer (void) {
|
|||
fprintf(cf, " logger->lsn.lsn++;\n");
|
||||
fprintf(cf, " if (lsnp) *lsnp=logger->lsn;\n");
|
||||
fprintf(cf, " ml_unlock(&logger->input_lock);\n");
|
||||
fprintf(cf, " return 0;\n");
|
||||
fprintf(cf, " return;\n");
|
||||
fprintf(cf, " }\n");
|
||||
fprintf(cf, " const unsigned int buflen= (+4 // len at the beginning\n");
|
||||
fprintf(cf, " +1 // log command\n");
|
||||
|
@ -442,8 +443,7 @@ generate_log_writer (void) {
|
|||
fprintf(cf, " );\n");
|
||||
fprintf(cf, " struct wbuf wbuf;\n");
|
||||
fprintf(cf, " ml_lock(&logger->input_lock);\n");
|
||||
fprintf(cf, " r = toku_logger_make_space_in_inbuf(logger, buflen);\n");
|
||||
fprintf(cf, " if (r!=0) goto panic;\n");
|
||||
fprintf(cf, " toku_logger_make_space_in_inbuf(logger, buflen);\n");
|
||||
fprintf(cf, " wbuf_nocrc_init(&wbuf, logger->inbuf.buf+logger->inbuf.n_in_buf, buflen);\n");
|
||||
fprintf(cf, " wbuf_nocrc_int(&wbuf, buflen);\n");
|
||||
fprintf(cf, " wbuf_nocrc_char(&wbuf, '%c');\n", (char)(0xff<->command_and_flags));
|
||||
|
@ -459,12 +459,7 @@ generate_log_writer (void) {
|
|||
fprintf(cf, " wbuf_nocrc_int(&wbuf, buflen);\n");
|
||||
fprintf(cf, " assert(wbuf.ndone==buflen);\n");
|
||||
fprintf(cf, " logger->inbuf.n_in_buf += buflen;\n");
|
||||
fprintf(cf, " r = toku_logger_maybe_fsync(logger, logger->lsn, do_fsync);\n");
|
||||
fprintf(cf, " if (r!=0) goto panic;\n");
|
||||
fprintf(cf, " return 0;\n");
|
||||
fprintf(cf, " panic:\n");
|
||||
fprintf(cf, " toku_logger_panic(logger, r);\n");
|
||||
fprintf(cf, " return r;\n");
|
||||
fprintf(cf, " toku_logger_maybe_fsync(logger, logger->lsn, do_fsync);\n");
|
||||
fprintf(cf, "}\n\n");
|
||||
});
|
||||
}
|
||||
|
@ -595,7 +590,7 @@ generate_logprint (void) {
|
|||
fprintf(pf, " if (len_in_file!=len || crc_in_file!=actual_murmur) return DB_BADFORMAT;\n");
|
||||
fprintf(pf, " };\n");
|
||||
fprintf(pf, " fprintf(outf, \"\\n\");\n");
|
||||
fprintf(pf, " return 0;;\n\n");
|
||||
fprintf(pf, " return 0;\n\n");
|
||||
});
|
||||
fprintf(pf, " }\n");
|
||||
fprintf(pf, " fprintf(outf, \"Unknown command %%d ('%%c')\", cmd, cmd);\n");
|
||||
|
@ -606,7 +601,7 @@ generate_logprint (void) {
|
|||
static void
|
||||
generate_rollbacks (void) {
|
||||
DO_ROLLBACKS(lt, {
|
||||
fprintf2(cf, hf, "int toku_logger_save_rollback_%s (TOKUTXN txn", lt->name);
|
||||
fprintf2(cf, hf, "void toku_logger_save_rollback_%s (TOKUTXN txn", lt->name);
|
||||
DO_FIELDS(field_type, lt, {
|
||||
if ( strcmp(field_type->type, "BYTESTRING") == 0 ) {
|
||||
fprintf2(cf, hf, ", BYTESTRING *%s_ptr", field_type->name);
|
||||
|
@ -664,7 +659,7 @@ generate_rollbacks (void) {
|
|||
fprintf(cf, " toku_maybe_spill_rollbacks(txn, log);\n");
|
||||
fprintf(cf, " toku_rollback_log_unpin(txn, log);\n");
|
||||
fprintf(cf, " toku_txn_unlock(txn);\n");
|
||||
fprintf(cf, " return 0;\n}\n");
|
||||
fprintf(cf, "}\n");
|
||||
});
|
||||
|
||||
DO_ROLLBACKS(lt, {
|
||||
|
|
226
ft/logger.cc
226
ft/logger.cc
|
@ -10,7 +10,7 @@
|
|||
static const int log_format_version=TOKU_LOG_VERSION;
|
||||
|
||||
static int open_logfile (TOKULOGGER logger);
|
||||
static int toku_logger_write_buffer (TOKULOGGER logger, LSN *fsynced_lsn);
|
||||
static void logger_write_buffer (TOKULOGGER logger, LSN *fsynced_lsn);
|
||||
static int delete_logfile(TOKULOGGER logger, long long index, uint32_t version);
|
||||
static void grab_output(TOKULOGGER logger, LSN *fsynced_lsn);
|
||||
static void release_output(TOKULOGGER logger, LSN fsynced_lsn);
|
||||
|
@ -68,12 +68,11 @@ static bool is_a_logfile (const char *name, long long *number_result) {
|
|||
}
|
||||
|
||||
|
||||
// TODO: can't fail
|
||||
int toku_logger_create (TOKULOGGER *resultp) {
|
||||
TOKULOGGER CALLOC(result);
|
||||
if (result==0) return get_error_errno();
|
||||
result->is_open=false;
|
||||
result->is_panicked=false;
|
||||
result->panic_errno = 0;
|
||||
result->write_log_files = true;
|
||||
result->trim_log_files = true;
|
||||
result->directory=0;
|
||||
|
@ -104,8 +103,8 @@ int toku_logger_create (TOKULOGGER *resultp) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int fsync_logdir(TOKULOGGER logger) {
|
||||
return toku_fsync_dirfd_without_accounting(logger->dir);
|
||||
static void fsync_logdir(TOKULOGGER logger) {
|
||||
toku_fsync_dirfd_without_accounting(logger->dir);
|
||||
}
|
||||
|
||||
static int open_logdir(TOKULOGGER logger, const char *directory) {
|
||||
|
@ -138,7 +137,6 @@ static int close_logdir(TOKULOGGER logger) {
|
|||
int
|
||||
toku_logger_open_with_last_xid(const char *directory, TOKULOGGER logger, TXNID last_xid) {
|
||||
if (logger->is_open) return EINVAL;
|
||||
if (logger->is_panicked) return EINVAL;
|
||||
|
||||
int r;
|
||||
TXNID last_xid_if_clean_shutdown;
|
||||
|
@ -181,19 +179,14 @@ bool toku_logger_rollback_is_open (TOKULOGGER logger) {
|
|||
int
|
||||
toku_logger_open_rollback(TOKULOGGER logger, CACHETABLE cachetable, bool create) {
|
||||
assert(logger->is_open);
|
||||
assert(!logger->is_panicked);
|
||||
assert(!logger->rollback_cachefile);
|
||||
|
||||
int r;
|
||||
FT_HANDLE t = NULL; // Note, there is no DB associated with this BRT.
|
||||
|
||||
r = toku_ft_handle_create(&t);
|
||||
assert_zero(r);
|
||||
r = toku_ft_handle_open(t, ROLLBACK_CACHEFILE_NAME, create, create, cachetable, NULL_TXN);
|
||||
toku_ft_handle_create(&t);
|
||||
int r = toku_ft_handle_open(t, ROLLBACK_CACHEFILE_NAME, create, create, cachetable, NULL_TXN);
|
||||
assert_zero(r);
|
||||
logger->rollback_cachefile = t->ft->cf;
|
||||
//Verify it is empty
|
||||
assert(!t->ft->panic);
|
||||
//Must have no data blocks (rollback logs or otherwise).
|
||||
toku_block_verify_no_data_blocks_except_root_unlocked(t->ft->blocktable, t->ft->h->root_blocknum);
|
||||
bool is_empty;
|
||||
|
@ -207,24 +200,18 @@ toku_logger_open_rollback(TOKULOGGER logger, CACHETABLE cachetable, bool create)
|
|||
// so it will always be clean (!h->dirty) when about to be closed.
|
||||
// Rollback log can only be closed when there are no open transactions,
|
||||
// so it will always be empty (no data blocks) when about to be closed.
|
||||
// TODO: can't fail
|
||||
int
|
||||
toku_logger_close_rollback(TOKULOGGER logger, bool recovery_failed) {
|
||||
int r = 0;
|
||||
toku_logger_close_rollback(TOKULOGGER logger) {
|
||||
CACHEFILE cf = logger->rollback_cachefile; // stored in logger at rollback cachefile open
|
||||
if (!logger->is_panicked && cf) {
|
||||
if (cf) {
|
||||
FT_HANDLE ft_to_close;
|
||||
{ //Find "brt"
|
||||
FT CAST_FROM_VOIDP(ft, toku_cachefile_get_userdata(cf));
|
||||
if (!ft->panic && recovery_failed) {
|
||||
r = toku_ft_set_panic(ft, EINVAL, "Recovery failed");
|
||||
assert_zero(r);
|
||||
}
|
||||
//Verify it is safe to close it.
|
||||
if (!ft->panic) { //If paniced, it is safe to close.
|
||||
assert(!ft->h->dirty); //Must not be dirty.
|
||||
//Must have no data blocks (rollback logs or otherwise).
|
||||
toku_block_verify_no_data_blocks_except_root_unlocked(ft->blocktable, ft->h->root_blocknum);
|
||||
}
|
||||
assert(!ft->h->dirty); //Must not be dirty.
|
||||
//Must have no data blocks (rollback logs or otherwise).
|
||||
toku_block_verify_no_data_blocks_except_root_unlocked(ft->blocktable, ft->h->root_blocknum);
|
||||
assert(!ft->h->dirty);
|
||||
ft_to_close = toku_ft_get_only_existing_ft_handle(ft);
|
||||
{
|
||||
|
@ -239,61 +226,59 @@ toku_logger_close_rollback(TOKULOGGER logger, bool recovery_failed) {
|
|||
//Set as dealt with already.
|
||||
logger->rollback_cachefile = NULL;
|
||||
}
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// No locks held on entry
|
||||
// No locks held on exit.
|
||||
// No locks are needed, since you cannot legally close the log concurrently with doing anything else.
|
||||
// TODO: can't fail
|
||||
int toku_logger_close(TOKULOGGER *loggerp) {
|
||||
int r;
|
||||
TOKULOGGER logger = *loggerp;
|
||||
if (logger->is_panicked) return EINVAL;
|
||||
int r = 0;
|
||||
if (!logger->is_open) goto is_closed;
|
||||
if (!logger->is_open) {
|
||||
goto is_closed;
|
||||
}
|
||||
ml_lock(&logger->input_lock);
|
||||
logger->input_lock_ctr++;
|
||||
LSN fsynced_lsn;
|
||||
grab_output(logger, &fsynced_lsn);
|
||||
r = toku_logger_write_buffer(logger, &fsynced_lsn); if (r!=0) goto panic; //Releases the input lock
|
||||
logger_write_buffer(logger, &fsynced_lsn);
|
||||
if (logger->fd!=-1) {
|
||||
if ( logger->write_log_files ) {
|
||||
r = toku_file_fsync_without_accounting(logger->fd); if (r!=0) { r=get_error_errno(); goto panic; }
|
||||
toku_file_fsync_without_accounting(logger->fd);
|
||||
}
|
||||
r = close(logger->fd); if (r!=0) { r=get_error_errno(); goto panic; }
|
||||
r = close(logger->fd);
|
||||
assert(r == 0);
|
||||
}
|
||||
r = close_logdir(logger); if (r!=0) { r=get_error_errno(); goto panic; }
|
||||
r = close_logdir(logger);
|
||||
assert(r == 0);
|
||||
logger->fd=-1;
|
||||
release_output(logger, fsynced_lsn);
|
||||
|
||||
is_closed:
|
||||
is_closed:
|
||||
toku_free(logger->inbuf.buf);
|
||||
toku_free(logger->outbuf.buf);
|
||||
// before destroying locks they must be left in the unlocked state.
|
||||
ml_destroy(&logger->input_lock);
|
||||
toku_mutex_destroy(&logger->output_condition_lock);
|
||||
toku_cond_destroy(&logger->output_condition);
|
||||
logger->is_panicked=true; // Just in case this might help.
|
||||
toku_txn_manager_destroy(logger->txn_manager);
|
||||
if (logger->directory) toku_free(logger->directory);
|
||||
toku_logfilemgr_destroy(&logger->logfilemgr);
|
||||
toku_free(logger);
|
||||
*loggerp=0;
|
||||
return r;
|
||||
panic:
|
||||
toku_logger_panic(logger, r);
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int toku_logger_shutdown(TOKULOGGER logger) {
|
||||
int r = 0;
|
||||
void toku_logger_shutdown(TOKULOGGER logger) {
|
||||
if (logger->is_open) {
|
||||
TXN_MANAGER mgr = logger->txn_manager;
|
||||
if (toku_txn_manager_num_live_txns(mgr) == 0) {
|
||||
TXNID last_xid = toku_txn_manager_get_last_xid(mgr);
|
||||
r = toku_log_shutdown(logger, NULL, true, 0, last_xid);
|
||||
toku_log_shutdown(logger, NULL, true, 0, last_xid);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static int close_and_open_logfile (TOKULOGGER logger, LSN *fsynced_lsn)
|
||||
|
@ -303,7 +288,7 @@ static int close_and_open_logfile (TOKULOGGER logger, LSN *fsynced_lsn)
|
|||
{
|
||||
int r;
|
||||
if (logger->write_log_files) {
|
||||
r = toku_file_fsync_without_accounting(logger->fd); if (r!=0) return get_error_errno();
|
||||
toku_file_fsync_without_accounting(logger->fd);
|
||||
*fsynced_lsn = logger->written_lsn;
|
||||
toku_logfilemgr_update_last_lsn(logger->logfilemgr, logger->written_lsn); // fixes t:2294
|
||||
}
|
||||
|
@ -432,7 +417,7 @@ write_outbuf_to_logfile (TOKULOGGER logger, LSN *fsynced_lsn)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
toku_logger_make_space_in_inbuf (TOKULOGGER logger, int n_bytes_needed)
|
||||
// Entry: Holds the inlock
|
||||
// Exit: Holds the inlock
|
||||
|
@ -444,7 +429,9 @@ toku_logger_make_space_in_inbuf (TOKULOGGER logger, int n_bytes_needed)
|
|||
// Arguments: logger: the logger (side effects)
|
||||
// n_bytes_needed: how many bytes to make space for.
|
||||
{
|
||||
if (logger->inbuf.n_in_buf + n_bytes_needed <= LOGGER_MIN_BUF_SIZE) return 0;
|
||||
if (logger->inbuf.n_in_buf + n_bytes_needed <= LOGGER_MIN_BUF_SIZE) {
|
||||
return;
|
||||
}
|
||||
logger->input_lock_ctr++;
|
||||
ml_unlock(&logger->input_lock);
|
||||
LSN fsynced_lsn;
|
||||
|
@ -455,7 +442,7 @@ toku_logger_make_space_in_inbuf (TOKULOGGER logger, int n_bytes_needed)
|
|||
// Some other thread may have written the log out while we didn't have the lock. If we have space now, then be happy.
|
||||
if (logger->inbuf.n_in_buf + n_bytes_needed <= LOGGER_MIN_BUF_SIZE) {
|
||||
release_output(logger, fsynced_lsn);
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
if (logger->inbuf.n_in_buf > 0) {
|
||||
// There isn't enough space, and there is something in the buffer, so write the inbuf.
|
||||
|
@ -473,7 +460,6 @@ toku_logger_make_space_in_inbuf (TOKULOGGER logger, int n_bytes_needed)
|
|||
logger->inbuf.buf_size = new_size;
|
||||
}
|
||||
release_output(logger, fsynced_lsn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int toku_logger_fsync (TOKULOGGER logger)
|
||||
|
@ -482,42 +468,25 @@ int toku_logger_fsync (TOKULOGGER logger)
|
|||
// Exit: Holds no locks
|
||||
// Implementation note: Acquire the output condition lock, then the output permission, then release the output condition lock, then get the input lock.
|
||||
// Then release everything.
|
||||
//
|
||||
// TODO: can't fail
|
||||
{
|
||||
int r;
|
||||
if (logger->is_panicked) return EINVAL;
|
||||
ml_lock(&logger->input_lock);
|
||||
logger->input_lock_ctr++;
|
||||
r = toku_logger_maybe_fsync(logger, logger->inbuf.max_lsn_in_buf, true);
|
||||
if (r!=0) {
|
||||
toku_logger_panic(logger, r);
|
||||
}
|
||||
return r;
|
||||
toku_logger_maybe_fsync(logger, logger->inbuf.max_lsn_in_buf, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: can't fail
|
||||
int
|
||||
toku_logger_fsync_if_lsn_not_fsynced (TOKULOGGER logger, LSN lsn) {
|
||||
int r = 0;
|
||||
if (logger->is_panicked) r = EINVAL;
|
||||
else if (logger->write_log_files) {
|
||||
if (logger->write_log_files) {
|
||||
ml_lock(&logger->input_lock);
|
||||
logger->input_lock_ctr++;
|
||||
r = toku_logger_maybe_fsync(logger, lsn, true);
|
||||
if (r!=0) {
|
||||
toku_logger_panic(logger, r);
|
||||
}
|
||||
toku_logger_maybe_fsync(logger, lsn, true);
|
||||
}
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void toku_logger_panic (TOKULOGGER logger, int err) {
|
||||
logger->panic_errno=err;
|
||||
logger->is_panicked=true;
|
||||
}
|
||||
int toku_logger_panicked(TOKULOGGER logger) {
|
||||
if (logger==0) return 0;
|
||||
return logger->is_panicked;
|
||||
}
|
||||
int toku_logger_is_open(TOKULOGGER logger) {
|
||||
if (logger==0) return 0;
|
||||
return logger->is_open;
|
||||
|
@ -529,7 +498,6 @@ void toku_logger_set_cachetable (TOKULOGGER logger, CACHETABLE ct) {
|
|||
|
||||
int toku_logger_set_lg_max(TOKULOGGER logger, uint32_t lg_max) {
|
||||
if (logger==0) return EINVAL; // no logger
|
||||
if (logger->is_panicked) return EINVAL;
|
||||
if (logger->is_open) return EINVAL;
|
||||
if (lg_max>(1<<30)) return EINVAL; // too big
|
||||
logger->lg_max = lg_max;
|
||||
|
@ -537,14 +505,12 @@ int toku_logger_set_lg_max(TOKULOGGER logger, uint32_t lg_max) {
|
|||
}
|
||||
int toku_logger_get_lg_max(TOKULOGGER logger, uint32_t *lg_maxp) {
|
||||
if (logger==0) return EINVAL; // no logger
|
||||
if (logger->is_panicked) return EINVAL;
|
||||
*lg_maxp = logger->lg_max;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int toku_logger_set_lg_bsize(TOKULOGGER logger, uint32_t bsize) {
|
||||
if (logger==0) return EINVAL; // no logger
|
||||
if (logger->is_panicked) return EINVAL;
|
||||
if (logger->is_open) return EINVAL;
|
||||
if (bsize<=0 || bsize>(1<<30)) return EINVAL;
|
||||
logger->write_block_size = bsize;
|
||||
|
@ -657,21 +623,22 @@ static int open_logfile (TOKULOGGER logger)
|
|||
long long index = logger->next_log_file_number;
|
||||
if (logger->write_log_files) {
|
||||
logger->fd = open(fname, O_CREAT+O_WRONLY+O_TRUNC+O_EXCL+O_BINARY, S_IRWXU);
|
||||
if (logger->fd==-1) return get_error_errno();
|
||||
int r = fsync_logdir(logger); if (r!=0) return r; // t:2445
|
||||
if (logger->fd==-1) {
|
||||
return get_error_errno();
|
||||
}
|
||||
fsync_logdir(logger);
|
||||
logger->next_log_file_number++;
|
||||
} else {
|
||||
logger->fd = open(DEV_NULL_FILE, O_WRONLY+O_BINARY);
|
||||
// printf("%s: %s %d\n", __FUNCTION__, DEV_NULL_FILE, logger->fd); fflush(stdout);
|
||||
if (logger->fd==-1) return get_error_errno();
|
||||
if (logger->fd==-1) {
|
||||
return get_error_errno();
|
||||
}
|
||||
}
|
||||
toku_os_full_write(logger->fd, "tokulogg", 8);
|
||||
int version_l = toku_htonl(log_format_version); //version MUST be in network byte order regardless of disk order
|
||||
toku_os_full_write(logger->fd, &version_l, 4);
|
||||
if ( logger->write_log_files ) {
|
||||
TOKULOGFILEINFO MALLOC(lf_info);
|
||||
if (lf_info == NULL)
|
||||
return ENOMEM;
|
||||
TOKULOGFILEINFO XMALLOC(lf_info);
|
||||
lf_info->index = index;
|
||||
lf_info->maxlsn = logger->written_lsn;
|
||||
lf_info->version = TOKU_LOG_VERSION;
|
||||
|
@ -739,20 +706,21 @@ void toku_logger_trim_log_files (TOKULOGGER logger, bool trim_log_files)
|
|||
logger->trim_log_files = trim_log_files;
|
||||
}
|
||||
|
||||
int toku_logger_maybe_fsync (TOKULOGGER logger, LSN lsn, int do_fsync)
|
||||
void toku_logger_maybe_fsync(TOKULOGGER logger, LSN lsn, int do_fsync)
|
||||
// Effect: If fsync is nonzero, then make sure that the log is flushed and synced at least up to lsn.
|
||||
// Entry: Holds input lock. The log entry has already been written to the input buffer.
|
||||
// Exit: Holds no locks.
|
||||
// The input lock may be released and then reacquired. Thus this function does not run atomically with respect to other threads.
|
||||
{
|
||||
int r;
|
||||
if (do_fsync) {
|
||||
// reacquire the locks (acquire output permission first)
|
||||
logger->input_lock_ctr++;
|
||||
ml_unlock(&logger->input_lock);
|
||||
LSN fsynced_lsn;
|
||||
bool already_done = wait_till_output_already_written_or_output_buffer_available(logger, lsn, &fsynced_lsn);
|
||||
if (already_done) return 0;
|
||||
if (already_done) {
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise we now own the output permission, and our lsn isn't outputed.
|
||||
|
||||
|
@ -767,27 +735,23 @@ int toku_logger_maybe_fsync (TOKULOGGER logger, LSN lsn, int do_fsync)
|
|||
write_outbuf_to_logfile(logger, &fsynced_lsn);
|
||||
if (fsynced_lsn.lsn < lsn.lsn) {
|
||||
// it may have gotten fsynced by the write_outbuf_to_logfile.
|
||||
r = toku_file_fsync_without_accounting(logger->fd);
|
||||
if (r!=0) {
|
||||
toku_logger_panic(logger, r);
|
||||
return r;
|
||||
}
|
||||
toku_file_fsync_without_accounting(logger->fd);
|
||||
assert(fsynced_lsn.lsn <= logger->written_lsn.lsn);
|
||||
fsynced_lsn = logger->written_lsn;
|
||||
}
|
||||
// the last lsn is only accessed while holding output permission or else when the log file is old.
|
||||
if ( logger->write_log_files )
|
||||
if (logger->write_log_files) {
|
||||
toku_logfilemgr_update_last_lsn(logger->logfilemgr, logger->written_lsn);
|
||||
}
|
||||
release_output(logger, fsynced_lsn);
|
||||
} else {
|
||||
logger->input_lock_ctr++;
|
||||
ml_unlock(&logger->input_lock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
toku_logger_write_buffer (TOKULOGGER logger, LSN *fsynced_lsn)
|
||||
static void
|
||||
logger_write_buffer(TOKULOGGER logger, LSN *fsynced_lsn)
|
||||
// Entry: Holds the input lock and permission to modify output.
|
||||
// Exit: Holds only the permission to modify output.
|
||||
// Effect: Write the buffers to the output. If DO_FSYNC is true, then fsync.
|
||||
|
@ -798,14 +762,9 @@ toku_logger_write_buffer (TOKULOGGER logger, LSN *fsynced_lsn)
|
|||
ml_unlock(&logger->input_lock);
|
||||
write_outbuf_to_logfile(logger, fsynced_lsn);
|
||||
if (logger->write_log_files) {
|
||||
int r = toku_file_fsync_without_accounting(logger->fd);
|
||||
if (r!=0) {
|
||||
toku_logger_panic(logger, r);
|
||||
return r;
|
||||
}
|
||||
toku_file_fsync_without_accounting(logger->fd);
|
||||
toku_logfilemgr_update_last_lsn(logger->logfilemgr, logger->written_lsn); // t:2294
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int toku_logger_restart(TOKULOGGER logger, LSN lastlsn)
|
||||
|
@ -818,15 +777,11 @@ int toku_logger_restart(TOKULOGGER logger, LSN lastlsn)
|
|||
grab_output(logger, &fsynced_lsn);
|
||||
ml_lock(&logger->input_lock);
|
||||
logger->input_lock_ctr++;
|
||||
r = toku_logger_write_buffer(logger, &fsynced_lsn); assert(r == 0);
|
||||
logger_write_buffer(logger, &fsynced_lsn);
|
||||
|
||||
// close the log file
|
||||
if ( logger->write_log_files) { // fsyncs don't work to /dev/null
|
||||
r = toku_file_fsync_without_accounting(logger->fd);
|
||||
if ( r!=0 ) {
|
||||
toku_logger_panic(logger, r);
|
||||
return r;
|
||||
}
|
||||
toku_file_fsync_without_accounting(logger->fd);
|
||||
}
|
||||
r = close(logger->fd); assert(r == 0);
|
||||
logger->fd = -1;
|
||||
|
@ -843,35 +798,36 @@ int toku_logger_restart(TOKULOGGER logger, LSN lastlsn)
|
|||
}
|
||||
|
||||
// fname is the iname
|
||||
int toku_logger_log_fcreate (TOKUTXN txn, const char *fname, FILENUM filenum, uint32_t mode, uint32_t treeflags, uint32_t nodesize, uint32_t basementnodesize, enum toku_compression_method compression_method) {
|
||||
if (txn==0) return 0;
|
||||
if (txn->logger->is_panicked) return EINVAL;
|
||||
BYTESTRING bs_fname = { .len = (uint32_t) strlen(fname), .data = (char *) fname };
|
||||
// fsync log on fcreate
|
||||
int r = toku_log_fcreate (txn->logger, (LSN*)0, 1, txn, toku_txn_get_txnid(txn), filenum, bs_fname, mode, treeflags, nodesize, basementnodesize, compression_method);
|
||||
return r;
|
||||
void toku_logger_log_fcreate (TOKUTXN txn, const char *fname, FILENUM filenum, uint32_t mode,
|
||||
uint32_t treeflags, uint32_t nodesize, uint32_t basementnodesize,
|
||||
enum toku_compression_method compression_method) {
|
||||
if (txn) {
|
||||
BYTESTRING bs_fname = { .len = (uint32_t) strlen(fname), .data = (char *) fname };
|
||||
// fsync log on fcreate
|
||||
toku_log_fcreate (txn->logger, (LSN*)0, 1, txn, toku_txn_get_txnid(txn), filenum,
|
||||
bs_fname, mode, treeflags, nodesize, basementnodesize, compression_method);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// We only do fdelete on open ft's, so we pass the filenum here
|
||||
int toku_logger_log_fdelete (TOKUTXN txn, FILENUM filenum) {
|
||||
if (txn==0) return 0;
|
||||
if (txn->logger->is_panicked) return EINVAL;
|
||||
//No fsync.
|
||||
int r = toku_log_fdelete (txn->logger, (LSN*)0, 0, txn, toku_txn_get_txnid(txn), filenum);
|
||||
return r;
|
||||
void toku_logger_log_fdelete (TOKUTXN txn, FILENUM filenum) {
|
||||
if (txn) {
|
||||
//No fsync.
|
||||
toku_log_fdelete (txn->logger, (LSN*)0, 0, txn, toku_txn_get_txnid(txn), filenum);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* fopen isn't really an action. It's just for bookkeeping. We need to know the filename that goes with a filenum. */
|
||||
int toku_logger_log_fopen (TOKUTXN txn, const char * fname, FILENUM filenum, uint32_t treeflags) {
|
||||
if (txn==0) return 0;
|
||||
if (txn->logger->is_panicked) return EINVAL;
|
||||
BYTESTRING bs;
|
||||
bs.len = strlen(fname);
|
||||
bs.data = (char*)fname;
|
||||
return toku_log_fopen (txn->logger, (LSN*)0, 0, bs, filenum, treeflags);
|
||||
void toku_logger_log_fopen (TOKUTXN txn, const char * fname, FILENUM filenum, uint32_t treeflags) {
|
||||
if (txn) {
|
||||
BYTESTRING bs;
|
||||
bs.len = strlen(fname);
|
||||
bs.data = (char*)fname;
|
||||
toku_log_fopen (txn->logger, (LSN*)0, 0, bs, filenum, treeflags);
|
||||
}
|
||||
}
|
||||
|
||||
static int toku_fread_uint8_t_nocrclen (FILE *f, uint8_t *v) {
|
||||
|
@ -1177,15 +1133,6 @@ int toku_read_logmagic (FILE *f, uint32_t *versionp) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
TXNID toku_txn_get_root_txnid (TOKUTXN txn) {
|
||||
if (txn==0) return 0;
|
||||
TOKUTXN root = txn;
|
||||
while (root->parent) {
|
||||
root = root->parent;
|
||||
}
|
||||
return root->txnid64;
|
||||
}
|
||||
|
||||
TXNID toku_txn_get_txnid (TOKUTXN txn) {
|
||||
if (txn==0) return 0;
|
||||
else return txn->txnid64;
|
||||
|
@ -1309,11 +1256,6 @@ void toku_logger_note_checkpoint(TOKULOGGER logger, LSN lsn) {
|
|||
logger->last_completed_checkpoint_lsn = lsn;
|
||||
}
|
||||
|
||||
LSN
|
||||
toku_logger_get_next_lsn(TOKULOGGER logger) {
|
||||
return logger->lsn;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Engine status
|
||||
//
|
||||
|
@ -1336,8 +1278,6 @@ status_init(void) {
|
|||
STATUS_INIT(LOGGER_ILOCK_CTR, UINT64, "ilock count");
|
||||
STATUS_INIT(LOGGER_OLOCK_CTR, UINT64, "olock count");
|
||||
STATUS_INIT(LOGGER_SWAP_CTR, UINT64, "swap count");
|
||||
STATUS_INIT(LOGGER_PANICKED, UINT64, "panic");
|
||||
STATUS_INIT(LOGGER_PANIC_ERRNO, UINT64, "panic errno");
|
||||
logger_status.initialized = true;
|
||||
}
|
||||
#undef STATUS_INIT
|
||||
|
@ -1353,8 +1293,6 @@ toku_logger_get_status(TOKULOGGER logger, LOGGER_STATUS statp) {
|
|||
STATUS_VALUE(LOGGER_ILOCK_CTR) = logger->input_lock_ctr;
|
||||
STATUS_VALUE(LOGGER_OLOCK_CTR) = logger->output_condition_lock_ctr;
|
||||
STATUS_VALUE(LOGGER_SWAP_CTR) = logger->swap_ctr;
|
||||
STATUS_VALUE(LOGGER_PANICKED) = logger->is_panicked;
|
||||
STATUS_VALUE(LOGGER_PANIC_ERRNO) = logger->panic_errno;
|
||||
}
|
||||
*statp = logger_status;
|
||||
}
|
||||
|
|
37
ft/logger.h
37
ft/logger.h
|
@ -23,25 +23,20 @@ enum {
|
|||
int toku_logger_create (TOKULOGGER *resultp);
|
||||
int toku_logger_open (const char *directory, TOKULOGGER logger);
|
||||
int toku_logger_open_with_last_xid(const char *directory, TOKULOGGER logger, TXNID last_xid);
|
||||
int toku_logger_shutdown(TOKULOGGER logger);
|
||||
void toku_logger_shutdown(TOKULOGGER logger);
|
||||
int toku_logger_close(TOKULOGGER *loggerp);
|
||||
int toku_logger_open_rollback(TOKULOGGER logger, CACHETABLE cachetable, bool create);
|
||||
int toku_logger_close_rollback(TOKULOGGER logger, bool recovery_failed);
|
||||
int toku_logger_close_rollback(TOKULOGGER logger);
|
||||
bool toku_logger_rollback_is_open (TOKULOGGER); // return true iff the rollback is open.
|
||||
|
||||
int toku_logger_fsync (TOKULOGGER logger);
|
||||
int toku_logger_fsync_if_lsn_not_fsynced(TOKULOGGER logger, LSN lsn);
|
||||
void toku_logger_panic (TOKULOGGER logger, int err);
|
||||
int toku_logger_panicked(TOKULOGGER logger);
|
||||
int toku_logger_is_open(TOKULOGGER logger);
|
||||
void toku_logger_set_cachetable (TOKULOGGER logger, CACHETABLE ct);
|
||||
int toku_logger_set_lg_max(TOKULOGGER logger, uint32_t lg_max);
|
||||
int toku_logger_get_lg_max(TOKULOGGER logger, uint32_t *lg_maxp);
|
||||
int toku_logger_set_lg_bsize(TOKULOGGER logger, uint32_t bsize);
|
||||
|
||||
int toku_logger_lock_init(void);
|
||||
int toku_logger_lock_destroy(void);
|
||||
|
||||
void toku_logger_write_log_files (TOKULOGGER logger, bool write_log_files);
|
||||
void toku_logger_trim_log_files(TOKULOGGER logger, bool trim_log_files);
|
||||
|
||||
|
@ -58,9 +53,9 @@ int toku_logger_restart(TOKULOGGER logger, LSN lastlsn);
|
|||
// Returns: 0 if success
|
||||
int toku_logger_maybe_trim_log(TOKULOGGER logger, LSN oldest_open_lsn);
|
||||
|
||||
int toku_logger_log_fcreate (TOKUTXN txn, const char *fname, FILENUM filenum, uint32_t mode, uint32_t flags, uint32_t nodesize, uint32_t basementnodesize, enum toku_compression_method compression_method);
|
||||
int toku_logger_log_fdelete (TOKUTXN txn, FILENUM filenum);
|
||||
int toku_logger_log_fopen (TOKUTXN txn, const char * fname, FILENUM filenum, uint32_t treeflags);
|
||||
void toku_logger_log_fcreate(TOKUTXN txn, const char *fname, FILENUM filenum, uint32_t mode, uint32_t flags, uint32_t nodesize, uint32_t basementnodesize, enum toku_compression_method compression_method);
|
||||
void toku_logger_log_fdelete(TOKUTXN txn, FILENUM filenum);
|
||||
void toku_logger_log_fopen(TOKUTXN txn, const char * fname, FILENUM filenum, uint32_t treeflags);
|
||||
|
||||
int toku_fread_uint8_t (FILE *f, uint8_t *v, struct x1764 *mm, uint32_t *len);
|
||||
int toku_fread_uint32_t_nocrclen (FILE *f, uint32_t *v);
|
||||
|
@ -91,7 +86,6 @@ int toku_read_and_print_logmagic (FILE *f, uint32_t *versionp);
|
|||
int toku_read_logmagic (FILE *f, uint32_t *versionp);
|
||||
|
||||
TXNID toku_txn_get_txnid (TOKUTXN txn);
|
||||
TXNID toku_txn_get_root_txnid (TOKUTXN txn);
|
||||
LSN toku_logger_last_lsn(TOKULOGGER logger);
|
||||
TOKULOGGER toku_txn_logger (TOKUTXN txn);
|
||||
|
||||
|
@ -103,12 +97,9 @@ int toku_logger_log_archive (TOKULOGGER logger, char ***logs_p, int flags);
|
|||
TOKUTXN toku_logger_txn_parent (TOKUTXN txn);
|
||||
void toku_logger_note_checkpoint(TOKULOGGER logger, LSN lsn);
|
||||
|
||||
LSN toku_logger_get_next_lsn(TOKULOGGER logger);
|
||||
void toku_logger_make_space_in_inbuf (TOKULOGGER logger, int n_bytes_needed);
|
||||
|
||||
int toku_logger_make_space_in_inbuf (TOKULOGGER logger, int n_bytes_needed);
|
||||
|
||||
int
|
||||
toku_logger_write_inbuf (TOKULOGGER logger);
|
||||
int toku_logger_write_inbuf (TOKULOGGER logger);
|
||||
// Effect: Write the buffered data (from the inbuf) to a file. No fsync, however.
|
||||
// As a side effect, the inbuf will be made empty.
|
||||
// Return 0 on success, otherwise return an error number.
|
||||
|
@ -119,9 +110,7 @@ toku_logger_write_inbuf (TOKULOGGER logger);
|
|||
// Rationale: When the buffer becomes nearly full, call this function so that more can be put in.
|
||||
// Implementation note: Since the output lock is acquired first, we must release the input lock, and then grab both in the right order.
|
||||
|
||||
|
||||
int
|
||||
toku_logger_maybe_fsync (TOKULOGGER logger, LSN lsn, int do_fsync);
|
||||
void toku_logger_maybe_fsync (TOKULOGGER logger, LSN lsn, int do_fsync);
|
||||
// Effect: If fsync is nonzero, then make sure that the log is flushed and synced at least up to lsn.
|
||||
// Entry: Holds input lock.
|
||||
// Exit: Holds no locks.
|
||||
|
@ -163,14 +152,11 @@ toku_logger_maybe_fsync (TOKULOGGER logger, LSN lsn, int do_fsync);
|
|||
// fsync
|
||||
// release the outlock
|
||||
|
||||
|
||||
typedef enum {
|
||||
LOGGER_NEXT_LSN = 0,
|
||||
LOGGER_ILOCK_CTR,
|
||||
LOGGER_OLOCK_CTR,
|
||||
LOGGER_SWAP_CTR,
|
||||
LOGGER_PANICKED,
|
||||
LOGGER_PANIC_ERRNO,
|
||||
LOGGER_STATUS_NUM_ROWS
|
||||
} logger_status_entry;
|
||||
|
||||
|
@ -179,17 +165,12 @@ typedef struct {
|
|||
TOKU_ENGINE_STATUS_ROW_S status[LOGGER_STATUS_NUM_ROWS];
|
||||
} LOGGER_STATUS_S, *LOGGER_STATUS;
|
||||
|
||||
|
||||
void toku_logger_get_status(TOKULOGGER logger, LOGGER_STATUS s);
|
||||
|
||||
int toku_get_version_of_logs_on_disk(const char *log_dir, bool *found_any_logs, uint32_t *version_found);
|
||||
int toku_delete_all_logs_of_version(const char *log_dir, uint32_t version_to_delete);
|
||||
|
||||
TXN_MANAGER toku_logger_get_txn_manager(TOKULOGGER logger);
|
||||
|
||||
|
||||
static const TOKULOGGER NULL_logger __attribute__((__unused__)) = NULL;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* TOKU_LOGGER_H */
|
||||
|
|
|
@ -98,14 +98,13 @@ toku_minicron_setup(struct minicron *p, uint32_t period_in_seconds, int(*f)(void
|
|||
return toku_pthread_create(&p->thread, 0, minicron_do, p);
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
toku_minicron_change_period(struct minicron *p, uint32_t new_period)
|
||||
{
|
||||
toku_mutex_lock(&p->mutex);
|
||||
p->period_in_seconds = new_period;
|
||||
toku_cond_signal(&p->condvar);
|
||||
toku_mutex_unlock(&p->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
|
|
@ -37,7 +37,7 @@ struct minicron {
|
|||
};
|
||||
|
||||
int toku_minicron_setup (struct minicron *s, uint32_t period_in_seconds, int(*f)(void *), void *arg);
|
||||
int toku_minicron_change_period(struct minicron *p, uint32_t new_period);
|
||||
void toku_minicron_change_period(struct minicron *p, uint32_t new_period);
|
||||
uint32_t toku_minicron_get_period(struct minicron *p);
|
||||
uint32_t toku_minicron_get_period_unlocked(struct minicron *p);
|
||||
int toku_minicron_shutdown(struct minicron *p);
|
||||
|
|
|
@ -122,7 +122,7 @@ static uint32_t file_map_get_num_dictionaries(struct file_map *fmap) {
|
|||
return toku_omt_size(fmap->filenums);
|
||||
}
|
||||
|
||||
static void file_map_close_dictionaries(struct file_map *fmap, bool recovery_succeeded, LSN oplsn) {
|
||||
static void file_map_close_dictionaries(struct file_map *fmap, LSN oplsn) {
|
||||
int r;
|
||||
|
||||
while (1) {
|
||||
|
@ -136,16 +136,9 @@ static void file_map_close_dictionaries(struct file_map *fmap, bool recovery_suc
|
|||
assert(r == 0);
|
||||
struct file_map_tuple *CAST_FROM_VOIDP(tuple, v);
|
||||
assert(tuple->ft_handle);
|
||||
if (!recovery_succeeded) {
|
||||
// don't update the brt on close
|
||||
r = toku_ft_handle_set_panic(tuple->ft_handle, DB_RUNRECOVERY, "recovery failed");
|
||||
assert(r==0);
|
||||
}
|
||||
// Logging is on again, but we must pass the right LSN into close.
|
||||
if (tuple->ft_handle) { // it's a DB, not a rollback file
|
||||
toku_ft_handle_close_recovery(tuple->ft_handle, oplsn);
|
||||
} else {
|
||||
assert(tuple->ft_handle==NULL);
|
||||
}
|
||||
file_map_tuple_destroy(tuple);
|
||||
toku_free(tuple);
|
||||
|
@ -202,7 +195,7 @@ static int recover_env_init (RECOVER_ENV renv,
|
|||
generate_row_for_put_func generate_row_for_put,
|
||||
generate_row_for_del_func generate_row_for_del,
|
||||
size_t cachetable_size) {
|
||||
int r;
|
||||
int r = 0;
|
||||
|
||||
// If we are passed a logger use it, otherwise create one.
|
||||
renv->destroy_logger_at_end = logger==NULL;
|
||||
|
@ -213,8 +206,7 @@ static int recover_env_init (RECOVER_ENV renv,
|
|||
assert(r == 0);
|
||||
}
|
||||
toku_logger_write_log_files(renv->logger, false);
|
||||
r = toku_create_cachetable(&renv->ct, cachetable_size ? cachetable_size : 1<<25, (LSN){0}, renv->logger);
|
||||
assert(r == 0);
|
||||
toku_cachetable_create(&renv->ct, cachetable_size ? cachetable_size : 1<<25, (LSN){0}, renv->logger);
|
||||
toku_cachetable_set_env_dir(renv->ct, env_dir);
|
||||
if (keep_cachetable_callback) keep_cachetable_callback(env, renv->ct);
|
||||
toku_logger_set_cachetable(renv->logger, renv->ct);
|
||||
|
@ -233,15 +225,14 @@ static int recover_env_init (RECOVER_ENV renv,
|
|||
return r;
|
||||
}
|
||||
|
||||
static void recover_env_cleanup (RECOVER_ENV renv, bool recovery_succeeded) {
|
||||
static void recover_env_cleanup (RECOVER_ENV renv) {
|
||||
int r;
|
||||
|
||||
assert(toku_omt_size(renv->fmap.filenums)==0);
|
||||
//file_map_close_dictionaries(renv, &renv->fmap, recovery_succeeded, oplsn);
|
||||
file_map_destroy(&renv->fmap);
|
||||
|
||||
if (renv->destroy_logger_at_end) {
|
||||
r = toku_logger_close_rollback(renv->logger, !recovery_succeeded);
|
||||
r = toku_logger_close_rollback(renv->logger);
|
||||
assert(r==0);
|
||||
r = toku_logger_close(&renv->logger);
|
||||
assert(r == 0);
|
||||
|
@ -252,8 +243,7 @@ static void recover_env_cleanup (RECOVER_ENV renv, bool recovery_succeeded) {
|
|||
if (renv->keep_cachetable_callback) {
|
||||
renv->ct = NULL;
|
||||
} else {
|
||||
r = toku_cachetable_close(&renv->ct);
|
||||
assert(r == 0);
|
||||
toku_cachetable_close(&renv->ct);
|
||||
}
|
||||
|
||||
if (tokudb_recovery_trace)
|
||||
|
@ -267,13 +257,11 @@ static const char *recover_state(RECOVER_ENV renv) {
|
|||
// Open the file if it is not already open. If it is already open, then do nothing.
|
||||
static int internal_recover_fopen_or_fcreate (RECOVER_ENV renv, bool must_create, int UU(mode), BYTESTRING *bs_iname, FILENUM filenum, uint32_t treeflags,
|
||||
TOKUTXN txn, uint32_t nodesize, uint32_t basementnodesize, enum toku_compression_method compression_method, LSN max_acceptable_lsn) {
|
||||
int r;
|
||||
int r = 0;
|
||||
FT_HANDLE brt = NULL;
|
||||
char *iname = fixup_fname(bs_iname);
|
||||
|
||||
r = toku_ft_handle_create(&brt);
|
||||
assert(r == 0);
|
||||
|
||||
toku_ft_handle_create(&brt);
|
||||
toku_ft_set_flags(brt, treeflags);
|
||||
|
||||
if (nodesize != 0) {
|
||||
|
@ -290,13 +278,11 @@ static int internal_recover_fopen_or_fcreate (RECOVER_ENV renv, bool must_create
|
|||
|
||||
// set the key compare functions
|
||||
if (!(treeflags & TOKU_DB_KEYCMP_BUILTIN) && renv->bt_compare) {
|
||||
r = toku_ft_set_bt_compare(brt, renv->bt_compare);
|
||||
assert(r == 0);
|
||||
toku_ft_set_bt_compare(brt, renv->bt_compare);
|
||||
}
|
||||
|
||||
if (renv->update_function) {
|
||||
r = toku_ft_set_update(brt, renv->update_function);
|
||||
assert(r == 0);
|
||||
toku_ft_set_update(brt, renv->update_function);
|
||||
}
|
||||
|
||||
// TODO mode (FUTURE FEATURE)
|
||||
|
@ -432,8 +418,7 @@ static int toku_recover_fassociate (struct logtype_fassociate *l, RECOVER_ENV re
|
|||
if (rollback_file) {
|
||||
max_acceptable_lsn = renv->ss.checkpoint_begin_lsn;
|
||||
FT_HANDLE t;
|
||||
r = toku_ft_handle_create(&t);
|
||||
assert(r==0);
|
||||
toku_ft_handle_create(&t);
|
||||
r = toku_ft_handle_open_recovery(t, ROLLBACK_CACHEFILE_NAME, false, false, renv->ct, (TOKUTXN)NULL, l->filenum, max_acceptable_lsn);
|
||||
renv->logger->rollback_cachefile = t->ft->cf;
|
||||
} else {
|
||||
|
@ -619,7 +604,7 @@ static int toku_recover_xstillopenprepared (struct logtype_xstillopenprepared *l
|
|||
}
|
||||
switch (renv->ss.ss) {
|
||||
case FORWARD_BETWEEN_CHECKPOINT_BEGIN_END: {
|
||||
r = toku_txn_prepare_txn(txn, l->xa_xid);
|
||||
toku_txn_prepare_txn(txn, l->xa_xid);
|
||||
break;
|
||||
}
|
||||
case FORWARD_NEWER_CHECKPOINT_END: {
|
||||
|
@ -710,8 +695,7 @@ static int toku_recover_xprepare (struct logtype_xprepare *l, RECOVER_ENV renv)
|
|||
assert(txn!=NULL);
|
||||
|
||||
// Save the transaction
|
||||
r = toku_txn_prepare_txn(txn, l->xa_xid);
|
||||
assert(r == 0);
|
||||
toku_txn_prepare_txn(txn, l->xa_xid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -834,7 +818,7 @@ static int toku_recover_change_fdescriptor (struct logtype_change_fdescriptor *l
|
|||
l->new_descriptor.data,
|
||||
l->new_descriptor.len
|
||||
);
|
||||
r = toku_ft_change_descriptor(
|
||||
toku_ft_change_descriptor(
|
||||
tuple->ft_handle,
|
||||
&old_descriptor,
|
||||
&new_descriptor,
|
||||
|
@ -842,7 +826,6 @@ static int toku_recover_change_fdescriptor (struct logtype_change_fdescriptor *l
|
|||
txn,
|
||||
l->update_cmp_descriptor
|
||||
);
|
||||
assert(r==0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -889,7 +872,7 @@ static int toku_recover_fdelete (struct logtype_fdelete *l, RECOVER_ENV renv) {
|
|||
struct file_map_tuple *tuple;
|
||||
r = file_map_find(&renv->fmap, l->filenum, &tuple);
|
||||
if (r == 0) {
|
||||
r = toku_ft_unlink_on_commit(tuple->ft_handle, txn);
|
||||
toku_ft_unlink_on_commit(tuple->ft_handle, txn);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -912,8 +895,7 @@ static int toku_recover_enq_insert (struct logtype_enq_insert *l, RECOVER_ENV re
|
|||
DBT keydbt, valdbt;
|
||||
toku_fill_dbt(&keydbt, l->key.data, l->key.len);
|
||||
toku_fill_dbt(&valdbt, l->value.data, l->value.len);
|
||||
r = toku_ft_maybe_insert(tuple->ft_handle, &keydbt, &valdbt, txn, true, l->lsn, false, FT_INSERT);
|
||||
assert(r == 0);
|
||||
toku_ft_maybe_insert(tuple->ft_handle, &keydbt, &valdbt, txn, true, l->lsn, false, FT_INSERT);
|
||||
toku_txn_maybe_note_ft(txn, tuple->ft_handle->ft);
|
||||
}
|
||||
return 0;
|
||||
|
@ -937,8 +919,7 @@ static int toku_recover_enq_insert_no_overwrite (struct logtype_enq_insert_no_ov
|
|||
DBT keydbt, valdbt;
|
||||
toku_fill_dbt(&keydbt, l->key.data, l->key.len);
|
||||
toku_fill_dbt(&valdbt, l->value.data, l->value.len);
|
||||
r = toku_ft_maybe_insert(tuple->ft_handle, &keydbt, &valdbt, txn, true, l->lsn, false, FT_INSERT_NO_OVERWRITE);
|
||||
assert(r == 0);
|
||||
toku_ft_maybe_insert(tuple->ft_handle, &keydbt, &valdbt, txn, true, l->lsn, false, FT_INSERT_NO_OVERWRITE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -960,8 +941,7 @@ static int toku_recover_enq_delete_any (struct logtype_enq_delete_any *l, RECOVE
|
|||
//Maybe do the deletion if we found the cachefile.
|
||||
DBT keydbt;
|
||||
toku_fill_dbt(&keydbt, l->key.data, l->key.len);
|
||||
r = toku_ft_maybe_delete(tuple->ft_handle, &keydbt, txn, true, l->lsn, false);
|
||||
assert(r == 0);
|
||||
toku_ft_maybe_delete(tuple->ft_handle, &keydbt, txn, true, l->lsn, false);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1007,8 +987,7 @@ static int toku_recover_enq_insert_multiple (struct logtype_enq_insert_multiple
|
|||
DB *db = &tuple->fake_db;
|
||||
r = renv->generate_row_for_put(db, src_db, &dest_key, &dest_val, &src_key, &src_val);
|
||||
assert(r==0);
|
||||
r = toku_ft_maybe_insert(tuple->ft_handle, &dest_key, &dest_val, txn, true, l->lsn, false, FT_INSERT);
|
||||
assert(r == 0);
|
||||
toku_ft_maybe_insert(tuple->ft_handle, &dest_key, &dest_val, txn, true, l->lsn, false, FT_INSERT);
|
||||
|
||||
//flags==0 means generate_row_for_put callback changed it
|
||||
//(and freed any memory necessary to do so) so that values are now stored
|
||||
|
@ -1068,8 +1047,7 @@ static int toku_recover_enq_delete_multiple (struct logtype_enq_delete_multiple
|
|||
DB *db = &tuple->fake_db;
|
||||
r = renv->generate_row_for_del(db, src_db, &dest_key, &src_key, &src_val);
|
||||
assert(r==0);
|
||||
r = toku_ft_maybe_delete(tuple->ft_handle, &dest_key, txn, true, l->lsn, false);
|
||||
assert(r == 0);
|
||||
toku_ft_maybe_delete(tuple->ft_handle, &dest_key, txn, true, l->lsn, false);
|
||||
|
||||
//flags==0 indicates the return values are stored in temporary memory that does
|
||||
//not need to be freed. We need to continue using DB_DBT_REALLOC however.
|
||||
|
@ -1102,9 +1080,7 @@ static int toku_recover_enq_update(struct logtype_enq_update *l, RECOVER_ENV ren
|
|||
DBT key, extra;
|
||||
toku_fill_dbt(&key, l->key.data, l->key.len);
|
||||
toku_fill_dbt(&extra, l->extra.data, l->extra.len);
|
||||
r = toku_ft_maybe_update(tuple->ft_handle, &key, &extra, txn, true, l->lsn,
|
||||
false);
|
||||
assert(r == 0);
|
||||
toku_ft_maybe_update(tuple->ft_handle, &key, &extra, txn, true, l->lsn, false);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1121,9 +1097,8 @@ static int toku_recover_enq_updatebroadcast(struct logtype_enq_updatebroadcast *
|
|||
// Maybe do the update broadcast if we found the cachefile.
|
||||
DBT extra;
|
||||
toku_fill_dbt(&extra, l->extra.data, l->extra.len);
|
||||
r = toku_ft_maybe_update_broadcast(tuple->ft_handle, &extra, txn, true,
|
||||
toku_ft_maybe_update_broadcast(tuple->ft_handle, &extra, txn, true,
|
||||
l->lsn, false, l->is_resetting_op);
|
||||
assert(r == 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1169,15 +1144,13 @@ static int toku_recover_backward_shutdown (struct logtype_shutdown *UU(l), RECOV
|
|||
}
|
||||
|
||||
static int toku_recover_load(struct logtype_load *UU(l), RECOVER_ENV UU(renv)) {
|
||||
int r;
|
||||
TOKUTXN txn = NULL;
|
||||
r = toku_txnid2txn(renv->logger, l->xid, &txn);
|
||||
int r = toku_txnid2txn(renv->logger, l->xid, &txn);
|
||||
assert(r == 0);
|
||||
assert(txn!=NULL);
|
||||
char *new_iname = fixup_fname(&l->new_iname);
|
||||
|
||||
r = toku_ft_load_recovery(txn, l->old_filenum, new_iname, 0, 0, (LSN*)NULL);
|
||||
assert(r==0);
|
||||
toku_ft_load_recovery(txn, l->old_filenum, new_iname, 0, 0, (LSN*)NULL);
|
||||
|
||||
toku_free(new_iname);
|
||||
return 0;
|
||||
|
@ -1190,15 +1163,13 @@ static int toku_recover_backward_load(struct logtype_load *UU(l), RECOVER_ENV UU
|
|||
|
||||
// #2954
|
||||
static int toku_recover_hot_index(struct logtype_hot_index *UU(l), RECOVER_ENV UU(renv)) {
|
||||
int r;
|
||||
TOKUTXN txn = NULL;
|
||||
r = toku_txnid2txn(renv->logger, l->xid, &txn);
|
||||
int r = toku_txnid2txn(renv->logger, l->xid, &txn);
|
||||
assert(r == 0);
|
||||
assert(txn!=NULL);
|
||||
// just make an entry in the rollback log
|
||||
// - set do_log = 0 -> don't write to recovery log
|
||||
r = toku_ft_hot_index_recovery(txn, l->hot_index_filenums, 0, 0, (LSN*)NULL);
|
||||
assert(r == 0);
|
||||
toku_ft_hot_index_recovery(txn, l->hot_index_filenums, 0, 0, (LSN*)NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1499,13 +1470,12 @@ static int do_recovery(RECOVER_ENV renv, const char *env_dir, const char *log_di
|
|||
tnow = time(NULL);
|
||||
fprintf(stderr, "%.24s Tokudb recovery closing %" PRIu32 " dictionar%s\n", ctime(&tnow), n, n > 1 ? "ies" : "y");
|
||||
}
|
||||
file_map_close_dictionaries(&renv->fmap, true, lastlsn);
|
||||
file_map_close_dictionaries(&renv->fmap, lastlsn);
|
||||
|
||||
{
|
||||
// write a recovery log entry
|
||||
BYTESTRING recover_comment = { static_cast<uint32_t>(strlen("recover")), (char *) "recover" };
|
||||
r = toku_log_comment(renv->logger, NULL, true, 0, recover_comment);
|
||||
assert(r == 0);
|
||||
toku_log_comment(renv->logger, NULL, true, 0, recover_comment);
|
||||
}
|
||||
|
||||
// checkpoint
|
||||
|
@ -1594,7 +1564,7 @@ int tokudb_recover(DB_ENV *env,
|
|||
|
||||
rr = do_recovery(&renv, env_dir, log_dir);
|
||||
|
||||
recover_env_cleanup(&renv, (bool)(rr == 0));
|
||||
recover_env_cleanup(&renv);
|
||||
}
|
||||
|
||||
r = toku_recover_unlock(lockfd);
|
||||
|
|
|
@ -179,8 +179,8 @@ static int do_insertion (enum ft_msg_type type, FILENUM filenum, BYTESTRING key,
|
|||
? toku_fill_dbt(&data_dbt, data->data, data->len)
|
||||
: toku_init_dbt(&data_dbt) } } };
|
||||
|
||||
r = toku_ft_root_put_cmd(h, &ftcmd);
|
||||
if (r == 0 && reset_root_xid_that_created) {
|
||||
toku_ft_root_put_cmd(h, &ftcmd);
|
||||
if (reset_root_xid_that_created) {
|
||||
TXNID new_root_xid_that_created = xids_get_outermost_xid(xids);
|
||||
toku_reset_root_xid_that_created(h, new_root_xid_that_created);
|
||||
}
|
||||
|
|
|
@ -139,10 +139,9 @@ int toku_rollback_commit(TOKUTXN txn, LSN lsn) {
|
|||
if (txn_has_current_rollback_log(txn)) {
|
||||
num_nodes--; //Don't count the in-progress rollback log.
|
||||
}
|
||||
r = toku_logger_save_rollback_rollinclude(txn->parent, txn->txnid64, num_nodes,
|
||||
toku_logger_save_rollback_rollinclude(txn->parent, txn->txnid64, num_nodes,
|
||||
txn->roll_info.spilled_rollback_head, txn->roll_info.spilled_rollback_head_hash,
|
||||
txn->roll_info.spilled_rollback_tail, txn->roll_info.spilled_rollback_tail_hash);
|
||||
if (r!=0) return r;
|
||||
//Remove ownership from child.
|
||||
txn->roll_info.spilled_rollback_head = ROLLBACK_NONE;
|
||||
txn->roll_info.spilled_rollback_head_hash = 0;
|
||||
|
|
|
@ -27,7 +27,6 @@ rollback_log_destroy(ROLLBACK_LOG_NODE log) {
|
|||
void toku_rollback_flush_callback (CACHEFILE cachefile, int fd, BLOCKNUM logname,
|
||||
void *rollback_v, void** UU(disk_data), void *extraargs, PAIR_ATTR size, PAIR_ATTR* new_size,
|
||||
bool write_me, bool keep_me, bool for_checkpoint, bool is_clone) {
|
||||
int r;
|
||||
ROLLBACK_LOG_NODE log = nullptr;
|
||||
SERIALIZED_ROLLBACK_LOG_NODE serialized = nullptr;
|
||||
if (is_clone) {
|
||||
|
@ -40,20 +39,10 @@ void toku_rollback_flush_callback (CACHEFILE cachefile, int fd, BLOCKNUM logname
|
|||
}
|
||||
FT CAST_FROM_VOIDP(h, extraargs);
|
||||
|
||||
if (write_me && !h->panic) {
|
||||
if (write_me) {
|
||||
assert(h->cf == cachefile);
|
||||
|
||||
r = toku_serialize_rollback_log_to(fd, log, serialized, is_clone, h, for_checkpoint);
|
||||
if (r) {
|
||||
if (h->panic==0) {
|
||||
char *e = strerror(r);
|
||||
int l = 200 + strlen(e);
|
||||
char s[l];
|
||||
h->panic=r;
|
||||
snprintf(s, l-1, "While writing data to disk, error %d (%s)", r, e);
|
||||
h->panic_string = toku_strdup(s);
|
||||
}
|
||||
}
|
||||
int r = toku_serialize_rollback_log_to(fd, log, serialized, is_clone, h, for_checkpoint);
|
||||
assert(r == 0);
|
||||
}
|
||||
*new_size = size;
|
||||
if (!keep_me) {
|
||||
|
|
|
@ -74,7 +74,6 @@ static void rollback_log_create (TOKUTXN txn, BLOCKNUM previous, uint32_t previo
|
|||
ROLLBACK_LOG_NODE MALLOC(log);
|
||||
assert(log);
|
||||
|
||||
int r;
|
||||
CACHEFILE cf = txn->logger->rollback_cachefile;
|
||||
FT CAST_FROM_VOIDP(h, toku_cachefile_get_userdata(cf));
|
||||
|
||||
|
@ -94,11 +93,10 @@ static void rollback_log_create (TOKUTXN txn, BLOCKNUM previous, uint32_t previo
|
|||
log->rollentry_resident_bytecount = 0;
|
||||
|
||||
*result = log;
|
||||
r = toku_cachetable_put(cf, log->blocknum, log->hash,
|
||||
log, rollback_memory_size(log),
|
||||
get_write_callbacks_for_rollback_log(h),
|
||||
toku_rollback_node_save_ct_pair);
|
||||
assert(r == 0);
|
||||
toku_cachetable_put(cf, log->blocknum, log->hash,
|
||||
log, rollback_memory_size(log),
|
||||
get_write_callbacks_for_rollback_log(h),
|
||||
toku_rollback_node_save_ct_pair);
|
||||
txn->roll_info.current_rollback = log->blocknum;
|
||||
txn->roll_info.current_rollback_hash = log->hash;
|
||||
}
|
||||
|
|
|
@ -35,14 +35,14 @@ static FT_HANDLE t;
|
|||
static void setup (void) {
|
||||
int r;
|
||||
unlink(fname);
|
||||
r = toku_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0);
|
||||
toku_cachetable_create(&ct, 0, ZERO_LSN, NULL_LOGGER);
|
||||
r = toku_open_ft_handle(fname, 1, &t, nodesize, basementnodesize, compression_method, ct, NULL_TXN, toku_builtin_compare_fun); assert(r==0);
|
||||
}
|
||||
|
||||
static void toku_shutdown (void) {
|
||||
int r;
|
||||
r = toku_close_ft_handle_nolsn(t, 0); assert(r==0);
|
||||
r = toku_cachetable_close(&ct); assert(r==0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
static void long_long_to_array (unsigned char *a, unsigned long long l) {
|
||||
int i;
|
||||
|
@ -57,8 +57,7 @@ static void insert (long long v) {
|
|||
long_long_to_array(kc, v);
|
||||
memset(vc, 0, sizeof vc);
|
||||
long_long_to_array(vc, v);
|
||||
int r = toku_ft_insert(t, toku_fill_dbt(&kt, kc, keysize), toku_fill_dbt(&vt, vc, valsize), 0);
|
||||
CKERR(r);
|
||||
toku_ft_insert(t, toku_fill_dbt(&kt, kc, keysize), toku_fill_dbt(&vt, vc, valsize), 0);
|
||||
if (do_verify) toku_cachetable_verify(ct);
|
||||
}
|
||||
|
||||
|
|
|
@ -54,11 +54,11 @@ run_test(unsigned long eltsize, unsigned long nodesize, unsigned long repeat)
|
|||
for (unsigned int i = 0; i < repeat; ++i) {
|
||||
bnc = toku_create_empty_nl();
|
||||
for (; toku_bnc_nbytesinbuf(bnc) <= nodesize; ++cur) {
|
||||
r = toku_bnc_insert_msg(bnc,
|
||||
&keys[cur % 1024], sizeof keys[cur % 1024],
|
||||
vals[cur % 1024], eltsize - (sizeof keys[cur % 1024]),
|
||||
FT_NONE, next_dummymsn(), xids_123, true,
|
||||
NULL, long_key_cmp); assert_zero(r);
|
||||
toku_bnc_insert_msg(bnc,
|
||||
&keys[cur % 1024], sizeof keys[cur % 1024],
|
||||
vals[cur % 1024], eltsize - (sizeof keys[cur % 1024]),
|
||||
FT_NONE, next_dummymsn(), xids_123, true,
|
||||
NULL, long_key_cmp); assert_zero(r);
|
||||
}
|
||||
nbytesinserted += toku_bnc_nbytesinbuf(bnc);
|
||||
destroy_nonleaf_childinfo(bnc);
|
||||
|
|
|
@ -23,7 +23,7 @@ run_test (void) {
|
|||
const int test_limit = 20;
|
||||
int r;
|
||||
ct = NULL;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
f1 = NULL;
|
||||
|
@ -53,7 +53,7 @@ run_test (void) {
|
|||
// pin 1 and 2
|
||||
r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v2, &s2, def_write_callback(NULL), def_fetch, def_pf_req_callback, def_pf_callback, true, NULL);
|
||||
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
// mark nodes as pending a checkpoint, so that get_and_pin_nonblocking on block 1 will return TOKUDB_TRY_AGAIN
|
||||
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_DIRTY, make_pair_attr(8)); assert(r==0);
|
||||
|
||||
|
@ -80,19 +80,16 @@ run_test (void) {
|
|||
);
|
||||
assert(r==TOKUDB_TRY_AGAIN);
|
||||
|
||||
r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
assert(r==0);
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
|
||||
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -31,7 +31,7 @@ cachetable_test (void) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
|
||||
|
@ -61,10 +61,8 @@ cachetable_test (void) {
|
|||
assert_zero(r);
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
|
||||
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -26,7 +26,7 @@ static void *pin_nonblocking(void *arg) {
|
|||
}
|
||||
|
||||
static void *put_same_key(void *arg) {
|
||||
int r = toku_cachetable_put(
|
||||
toku_cachetable_put(
|
||||
f1,
|
||||
make_blocknum(1),
|
||||
toku_cachetable_hash(f1,make_blocknum(1)),
|
||||
|
@ -35,7 +35,6 @@ static void *put_same_key(void *arg) {
|
|||
def_write_callback(NULL),
|
||||
put_callback_nop
|
||||
);
|
||||
assert(r==0);
|
||||
return arg;
|
||||
}
|
||||
|
||||
|
@ -53,7 +52,7 @@ cachetable_test (void) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
|
||||
|
@ -87,10 +86,8 @@ cachetable_test (void) {
|
|||
r = toku_test_cachetable_unpin(f1, make_blocknum(1), toku_cachetable_hash(f1, make_blocknum(1)), CACHETABLE_CLEAN, make_pair_attr(2));
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
|
||||
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -84,7 +84,7 @@ cachetable_test (void) {
|
|||
check_flush = false;
|
||||
dirty_flush_called = false;
|
||||
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
evictor_test_helpers::disable_ev_thread(&ct->ev); // disable eviction thread
|
||||
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
|
@ -118,7 +118,7 @@ cachetable_test (void) {
|
|||
|
||||
usleep(2*1024*1024);
|
||||
check_flush = true;
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN);
|
||||
assert(r == 0);
|
||||
assert(dirty_flush_called);
|
||||
check_flush = false;
|
||||
|
@ -129,8 +129,8 @@ cachetable_test (void) {
|
|||
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f2, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f2, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -32,7 +32,7 @@ cachetable_test (void) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -52,8 +52,8 @@ cachetable_test (void) {
|
|||
//r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_CLEAN, 8);
|
||||
|
||||
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -105,7 +105,7 @@ static void checkpoint_pending(void) {
|
|||
if (verbose) { printf("%s:%d n=%d\n", __FUNCTION__, __LINE__, N); fflush(stdout); }
|
||||
const int test_limit = N;
|
||||
int r;
|
||||
r = toku_create_cachetable(&ct, test_limit*sizeof(int), ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit*sizeof(int), ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
r = unlink(fname1); if (r!=0) CKERR2(get_error_errno(), ENOENT);
|
||||
r = toku_cachetable_openf(&cf, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
|
||||
|
@ -119,7 +119,7 @@ static void checkpoint_pending(void) {
|
|||
values[i] = 42;
|
||||
CACHETABLE_WRITE_CALLBACK wc = def_write_callback(NULL);
|
||||
wc.flush_callback = flush;
|
||||
r = toku_cachetable_put(cf, key, hi, &values[i], make_pair_attr(sizeof(int)), wc, put_callback_nop);
|
||||
toku_cachetable_put(cf, key, hi, &values[i], make_pair_attr(sizeof(int)), wc, put_callback_nop);
|
||||
assert(r == 0);
|
||||
|
||||
r = toku_test_cachetable_unpin(cf, key, hi, CACHETABLE_DIRTY, make_pair_attr(item_size));
|
||||
|
@ -153,8 +153,8 @@ static void checkpoint_pending(void) {
|
|||
assert(r == 0);
|
||||
assert(n_flush == 0 && n_write_me == 0 && n_keep_me == 0);
|
||||
|
||||
r = toku_cachefile_close(&cf, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&cf, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -68,7 +68,7 @@ cachetable_test (void) {
|
|||
const int test_limit = 20;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -91,7 +91,7 @@ cachetable_test (void) {
|
|||
// flush will be called only for v1, because v1 is dirty
|
||||
//
|
||||
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL); assert(r == 0);
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
|
||||
|
||||
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_DIRTY, make_pair_attr(8));
|
||||
|
@ -99,7 +99,7 @@ cachetable_test (void) {
|
|||
|
||||
check_me = true;
|
||||
flush_called = false;
|
||||
r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -110,8 +110,8 @@ cachetable_test (void) {
|
|||
check_me = false;
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ cachetable_test (void) {
|
|||
const int test_limit = 20;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -93,12 +93,12 @@ cachetable_test (void) {
|
|||
// flush will be called only for v1, because v1 is dirty
|
||||
//
|
||||
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL); assert(r == 0);
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
|
||||
|
||||
check_me = true;
|
||||
flush_called = false;
|
||||
r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -111,8 +111,8 @@ cachetable_test (void) {
|
|||
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ static void cachetable_checkpoint_test(int n, enum cachetable_dirty dirty) {
|
|||
const int test_limit = n;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -74,8 +74,7 @@ static void cachetable_checkpoint_test(int n, enum cachetable_dirty dirty) {
|
|||
uint32_t hi = toku_cachetable_hash(f1, key);
|
||||
CACHETABLE_WRITE_CALLBACK wc = def_write_callback(NULL);
|
||||
wc.flush_callback = flush;
|
||||
r = toku_cachetable_put(f1, key, hi, (void *)(long)i, make_pair_attr(1), wc, put_callback_nop);
|
||||
assert(r == 0);
|
||||
toku_cachetable_put(f1, key, hi, (void *)(long)i, make_pair_attr(1), wc, put_callback_nop);
|
||||
|
||||
r = toku_test_cachetable_unpin(f1, key, hi, dirty, make_pair_attr(item_size));
|
||||
assert(r == 0);
|
||||
|
@ -132,8 +131,8 @@ static void cachetable_checkpoint_test(int n, enum cachetable_dirty dirty) {
|
|||
assert(r == 0);
|
||||
assert(n_flush == 0 && n_write_me == 0 && n_keep_me == 0);
|
||||
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0 );
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0 );
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -34,8 +34,6 @@ struct checkpointer_test {
|
|||
// Description:
|
||||
//
|
||||
void checkpointer_test::test_begin_checkpoint() {
|
||||
int r = 0;
|
||||
|
||||
cachefile_list cfl;
|
||||
cfl.init();
|
||||
|
||||
|
@ -46,8 +44,7 @@ void checkpointer_test::test_begin_checkpoint() {
|
|||
m_cp.init(&ctbl.list, NULL, &ctbl.ev, &cfl);
|
||||
|
||||
// 1. Call checkpoint with NO cachefiles.
|
||||
r = m_cp.begin_checkpoint();
|
||||
if (r) { assert(!"CHECKPOINTER: Checkpoint with no cachefiles failed!\n"); }
|
||||
m_cp.begin_checkpoint();
|
||||
|
||||
// 2. Call checkpoint with ONE cachefile.
|
||||
//cachefile cf;
|
||||
|
@ -57,8 +54,7 @@ void checkpointer_test::test_begin_checkpoint() {
|
|||
m_cp.m_cf_list->m_head = &cf;
|
||||
create_dummy_functions(&cf);
|
||||
|
||||
r = m_cp.begin_checkpoint();
|
||||
if (r) { assert(!"CHECKPOINTER: Checkpoint with one cachefile failed!\n"); }
|
||||
m_cp.begin_checkpoint();
|
||||
assert(m_cp.m_checkpoint_num_files == 1);
|
||||
assert(cf.for_checkpoint == true);
|
||||
|
||||
|
@ -76,8 +72,7 @@ void checkpointer_test::test_begin_checkpoint() {
|
|||
}
|
||||
}
|
||||
|
||||
r = m_cp.begin_checkpoint();
|
||||
if (r) { assert(!"CHECKPOINTER: Multiple checkpoint failed!\n"); }
|
||||
m_cp.begin_checkpoint();
|
||||
assert(m_cp.m_checkpoint_num_files == count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
assert(cfs[i].for_checkpoint == true);
|
||||
|
@ -171,8 +166,7 @@ void checkpointer_test::test_pending_bits() {
|
|||
m_cp.m_list->evict(pp);
|
||||
}
|
||||
|
||||
int r = ctbl.list.destroy();
|
||||
assert_zero(r);
|
||||
ctbl.list.destroy();
|
||||
m_cp.destroy();
|
||||
}
|
||||
|
||||
|
@ -307,8 +301,7 @@ void checkpointer_test::test_end_checkpoint() {
|
|||
m_cp.m_list->evict(pp);
|
||||
}
|
||||
m_cp.destroy();
|
||||
int r = ctbl.list.destroy();
|
||||
assert_zero(r);
|
||||
ctbl.list.destroy();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ cachetable_test (void) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
|
||||
|
@ -83,11 +83,11 @@ cachetable_test (void) {
|
|||
|
||||
cleaner_called = false;
|
||||
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
assert_zero(r);
|
||||
toku_cleaner_thread_for_test(ct);
|
||||
assert(cleaner_called);
|
||||
r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -96,8 +96,8 @@ cachetable_test (void) {
|
|||
assert(r==0);
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ cachetable_test (void) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
|
||||
|
@ -83,11 +83,11 @@ cachetable_test (void) {
|
|||
|
||||
cleaner_called = false;
|
||||
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
assert_zero(r);
|
||||
toku_cleaner_thread_for_test(ct);
|
||||
assert(!cleaner_called);
|
||||
r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -96,8 +96,8 @@ cachetable_test (void) {
|
|||
assert(r==0);
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ run_test (void) {
|
|||
int r;
|
||||
CACHETABLE ct;
|
||||
toku_mutex_init(&attr_mutex, NULL);
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
|
@ -126,8 +126,8 @@ run_test (void) {
|
|||
assert(STATUS_VALUE(CT_SIZE_CACHEPRESSURE) == (uint64_t) expect.cache_pressure_size);
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -15,8 +15,8 @@ cachetable_test (void) {
|
|||
const int test_limit = 1000;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
r = toku_set_cleaner_period(ct, 1); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
toku_set_cleaner_period(ct, 1);
|
||||
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
|
@ -26,8 +26,8 @@ cachetable_test (void) {
|
|||
|
||||
usleep(4000000);
|
||||
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL); assert(r == 0);
|
||||
r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -36,8 +36,8 @@ cachetable_test (void) {
|
|||
assert(r==0);
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -27,14 +27,14 @@ run_test (void) {
|
|||
const int test_limit = 1000;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
r = toku_set_cleaner_period(ct, 1); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
toku_set_cleaner_period(ct, 1);
|
||||
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
|
||||
r = toku_set_cleaner_period(ct, 1);
|
||||
toku_set_cleaner_period(ct, 1);
|
||||
assert(r==0);
|
||||
|
||||
void* vs[8];
|
||||
|
@ -62,8 +62,8 @@ run_test (void) {
|
|||
}
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -27,8 +27,8 @@ run_test (void) {
|
|||
const int test_limit = 1000;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
r = toku_set_cleaner_period(ct, 1); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
toku_set_cleaner_period(ct, 1);
|
||||
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
|
@ -60,8 +60,8 @@ run_test (void) {
|
|||
usleep(4000000);
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -35,8 +35,8 @@ run_test (void) {
|
|||
const int test_limit = 1000;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
r = toku_set_cleaner_period(ct, 1); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
toku_set_cleaner_period(ct, 1);
|
||||
my_cleaner_callback_called = false;
|
||||
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
|
@ -80,8 +80,8 @@ run_test (void) {
|
|||
assert(my_cleaner_callback_called);
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0 );
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0 );
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -12,7 +12,7 @@ cachetable_test (void) {
|
|||
int test_limit = 6;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -20,14 +20,13 @@ cachetable_test (void) {
|
|||
|
||||
// test that putting something too big in the cachetable works fine
|
||||
CACHETABLE_WRITE_CALLBACK wc = def_write_callback(NULL);
|
||||
r = toku_cachetable_put(f1, make_blocknum(num_entries+1), num_entries+1, NULL, make_pair_attr(test_limit*2), wc, put_callback_nop);
|
||||
assert(r==0);
|
||||
toku_cachetable_put(f1, make_blocknum(num_entries+1), num_entries+1, NULL, make_pair_attr(test_limit*2), wc, put_callback_nop);
|
||||
r = toku_test_cachetable_unpin(f1, make_blocknum(num_entries+1), num_entries+1, CACHETABLE_DIRTY, make_pair_attr(test_limit*2));
|
||||
assert(r==0);
|
||||
|
||||
|
||||
for (int64_t i = 0; i < num_entries; i++) {
|
||||
r = toku_cachetable_put(f1, make_blocknum(i), i, NULL, make_pair_attr(1), wc, put_callback_nop);
|
||||
toku_cachetable_put(f1, make_blocknum(i), i, NULL, make_pair_attr(1), wc, put_callback_nop);
|
||||
assert(toku_cachefile_count_pinned(f1, 0) == (i+1));
|
||||
}
|
||||
for (int64_t i = 0; i < num_entries; i++) {
|
||||
|
@ -35,8 +34,8 @@ cachetable_test (void) {
|
|||
}
|
||||
|
||||
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0 );
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0 );
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -58,7 +58,7 @@ cachetable_test (void) {
|
|||
num_entries = 0;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -89,7 +89,7 @@ cachetable_test (void) {
|
|||
}
|
||||
flush_may_occur = true;
|
||||
expected_flushed_key = 4;
|
||||
r = toku_cachetable_put(f1, make_blocknum(5), 5, NULL, make_pair_attr(4), wc, put_callback_nop);
|
||||
toku_cachetable_put(f1, make_blocknum(5), 5, NULL, make_pair_attr(4), wc, put_callback_nop);
|
||||
ct->ev.signal_eviction_thread();
|
||||
usleep(1*1024*1024);
|
||||
|
||||
|
@ -100,8 +100,8 @@ cachetable_test (void) {
|
|||
usleep(1*1024*1024);
|
||||
|
||||
check_flush = false;
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0 );
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0 );
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -99,7 +99,7 @@ cachetable_test (void) {
|
|||
const int test_limit = 16;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -142,7 +142,7 @@ cachetable_test (void) {
|
|||
CACHETABLE_WRITE_CALLBACK wc = def_write_callback(NULL);
|
||||
wc.flush_callback = other_flush;
|
||||
wc.pe_callback = other_pe_callback;
|
||||
r = toku_cachetable_put(f1, make_blocknum(5), 5, NULL, make_pair_attr(4), wc, put_callback_nop);
|
||||
toku_cachetable_put(f1, make_blocknum(5), 5, NULL, make_pair_attr(4), wc, put_callback_nop);
|
||||
ct->ev.signal_eviction_thread();
|
||||
usleep(1*1024*1024);
|
||||
flush_may_occur = true;
|
||||
|
@ -152,8 +152,8 @@ cachetable_test (void) {
|
|||
assert(expected_bytes_to_free == 0);
|
||||
|
||||
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -115,7 +115,7 @@ cachetable_test (void) {
|
|||
const int test_limit = 20;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
evictor_test_helpers::set_hysteresis_limits(&ct->ev, test_limit, 100*test_limit);
|
||||
evictor_test_helpers::disable_ev_thread(&ct->ev);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
|
@ -165,7 +165,7 @@ cachetable_test (void) {
|
|||
wc.flush_callback = other_flush;
|
||||
wc.pe_est_callback = pe_est_callback;
|
||||
wc.pe_callback = other_pe_callback;
|
||||
r = toku_cachetable_put(f1, make_blocknum(5), 5, NULL, make_pair_attr(4), wc, put_callback_nop);
|
||||
toku_cachetable_put(f1, make_blocknum(5), 5, NULL, make_pair_attr(4), wc, put_callback_nop);
|
||||
flush_may_occur = true;
|
||||
r = toku_test_cachetable_unpin(f1, make_blocknum(5), 5, CACHETABLE_CLEAN, make_pair_attr(8));
|
||||
ct->ev.signal_eviction_thread();
|
||||
|
@ -180,8 +180,8 @@ cachetable_test (void) {
|
|||
assert(expected_bytes_to_free == 3);
|
||||
|
||||
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -95,7 +95,7 @@ cachetable_test (void) {
|
|||
num_entries = 0;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -128,14 +128,14 @@ cachetable_test (void) {
|
|||
}
|
||||
flush_may_occur = true;
|
||||
expected_flushed_key = 4;
|
||||
r = toku_cachetable_put(f1, make_blocknum(5), 5, NULL, make_pair_attr(4), wc, put_callback_nop);
|
||||
toku_cachetable_put(f1, make_blocknum(5), 5, NULL, make_pair_attr(4), wc, put_callback_nop);
|
||||
flush_may_occur = true;
|
||||
expected_flushed_key = 5;
|
||||
r = toku_test_cachetable_unpin(f1, make_blocknum(5), 5, CACHETABLE_CLEAN, make_pair_attr(4));
|
||||
|
||||
check_flush = false;
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0 );
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0 );
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -42,13 +42,12 @@ flush (
|
|||
|
||||
static void *run_end_checkpoint(void *arg) {
|
||||
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
|
||||
int r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
assert_zero(r);
|
||||
return arg;
|
||||
}
|
||||
|
||||
|
@ -60,7 +59,7 @@ cachetable_test (void) {
|
|||
const int test_limit = 200;
|
||||
int r;
|
||||
ct = NULL;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -77,7 +76,7 @@ cachetable_test (void) {
|
|||
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_DIRTY, make_pair_attr(8));
|
||||
assert_zero(r);
|
||||
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
|
||||
|
||||
clone_flush_started = false;
|
||||
|
@ -100,8 +99,8 @@ cachetable_test (void) {
|
|||
assert(clone_flush_started && clone_flush_completed);
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -53,7 +53,7 @@ cachetable_test (void) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -73,7 +73,7 @@ cachetable_test (void) {
|
|||
|
||||
flush_completed = false;
|
||||
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL); assert_zero(r);
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
assert_zero(r);
|
||||
r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, &s1, wc, def_fetch, def_pf_req_callback, def_pf_callback, true, NULL);
|
||||
assert_zero(r);
|
||||
|
@ -91,7 +91,7 @@ cachetable_test (void) {
|
|||
assert_zero(r);
|
||||
assert(pf_called);
|
||||
|
||||
r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -101,8 +101,8 @@ cachetable_test (void) {
|
|||
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ cachetable_test (void) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -78,7 +78,7 @@ cachetable_test (void) {
|
|||
|
||||
flush_completed = false;
|
||||
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL); assert_zero(r);
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
assert_zero(r);
|
||||
r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, &s1, wc, def_fetch, def_pf_req_callback, def_pf_callback, true, NULL);
|
||||
assert_zero(r);
|
||||
|
@ -92,7 +92,7 @@ cachetable_test (void) {
|
|||
assert_zero(r);
|
||||
assert(pf_called);
|
||||
|
||||
r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -102,8 +102,8 @@ cachetable_test (void) {
|
|||
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ cachetable_test (enum cachetable_dirty dirty, bool cloneable) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -58,7 +58,7 @@ cachetable_test (enum cachetable_dirty dirty, bool cloneable) {
|
|||
|
||||
// test that having a pin that passes false for may_modify_value does not stall behind checkpoint
|
||||
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL); assert_zero(r);
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
r = toku_cachetable_get_and_pin_nonblocking(f1, make_blocknum(1), 1, &v1, &s1, wc, def_fetch, def_pf_req_callback, def_pf_callback, PL_READ, NULL, NULL);
|
||||
assert(r == 0);
|
||||
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_CLEAN, make_pair_attr(8));
|
||||
|
@ -73,20 +73,16 @@ cachetable_test (enum cachetable_dirty dirty, bool cloneable) {
|
|||
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_CLEAN, make_pair_attr(8));
|
||||
}
|
||||
|
||||
r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
assert_zero(r);
|
||||
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
|
||||
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -51,7 +51,7 @@ cachetable_test (void) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -72,7 +72,7 @@ cachetable_test (void) {
|
|||
flush_completed = false;
|
||||
evict_called = false;
|
||||
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL); assert_zero(r);
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
assert_zero(r);
|
||||
r = toku_cachetable_get_and_pin(f1, make_blocknum(1), toku_cachetable_hash(f1, make_blocknum(1)), &v1, &s1, wc, def_fetch, def_pf_req_callback, def_pf_callback, true, NULL);
|
||||
assert_zero(r);
|
||||
|
@ -80,7 +80,7 @@ cachetable_test (void) {
|
|||
assert_zero(r);
|
||||
|
||||
|
||||
r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -90,8 +90,8 @@ cachetable_test (void) {
|
|||
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ cachetable_count_pinned_test (int n) {
|
|||
const int test_limit = 2*n;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -23,8 +23,7 @@ cachetable_count_pinned_test (int n) {
|
|||
uint32_t hi;
|
||||
hi = toku_cachetable_hash(f1, make_blocknum(i));
|
||||
CACHETABLE_WRITE_CALLBACK wc = def_write_callback(NULL);
|
||||
r = toku_cachetable_put(f1, make_blocknum(i), hi, (void *)(long)i, make_pair_attr(1), wc, put_callback_nop);
|
||||
assert(r == 0);
|
||||
toku_cachetable_put(f1, make_blocknum(i), hi, (void *)(long)i, make_pair_attr(1), wc, put_callback_nop);
|
||||
assert(toku_cachefile_count_pinned(f1, 0) == i);
|
||||
|
||||
void *v;
|
||||
|
@ -48,8 +47,8 @@ cachetable_count_pinned_test (int n) {
|
|||
assert(toku_cachefile_count_pinned(f1, 1) == 0);
|
||||
toku_cachetable_verify(ct);
|
||||
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -11,7 +11,7 @@ cachetable_debug_test (int n) {
|
|||
const int test_limit = n;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -30,8 +30,7 @@ cachetable_debug_test (int n) {
|
|||
uint32_t hi;
|
||||
hi = toku_cachetable_hash(f1, make_blocknum(i));
|
||||
CACHETABLE_WRITE_CALLBACK wc = def_write_callback(NULL);
|
||||
r = toku_cachetable_put(f1, make_blocknum(i), hi, (void *)(long)i, make_pair_attr(item_size), wc, put_callback_nop);
|
||||
assert(r == 0);
|
||||
toku_cachetable_put(f1, make_blocknum(i), hi, (void *)(long)i, make_pair_attr(item_size), wc, put_callback_nop);
|
||||
|
||||
void *v; int dirty; long long pinned; long pair_size;
|
||||
r = toku_cachetable_get_key_state(ct, make_blocknum(i), f1, &v, &dirty, &pinned, &pair_size);
|
||||
|
@ -53,8 +52,8 @@ cachetable_debug_test (int n) {
|
|||
}
|
||||
toku_cachetable_verify(ct);
|
||||
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -70,7 +70,7 @@ static void cachetable_eviction_full_test (void) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -132,8 +132,8 @@ static void cachetable_eviction_full_test (void) {
|
|||
|
||||
// close with the eviction in progress. the close should block until
|
||||
// all of the reads and writes are complete.
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -82,7 +82,7 @@ static void cachetable_eviction_full_test (void) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -146,8 +146,8 @@ static void cachetable_eviction_full_test (void) {
|
|||
|
||||
// close with the eviction in progress. the close should block until
|
||||
// all of the reads and writes are complete.
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -38,7 +38,7 @@ static void cachetable_predef_fetch_maybegetandpin_test (void) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
evictor_test_helpers::disable_ev_thread(&ct->ev);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
|
@ -119,8 +119,8 @@ static void cachetable_predef_fetch_maybegetandpin_test (void) {
|
|||
assert(r == 0);
|
||||
toku_cachetable_verify(ct);
|
||||
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -44,7 +44,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
evictor_test_helpers::disable_ev_thread(&ct->ev);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
|
@ -148,8 +148,8 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
|
|||
assert(r == 0);
|
||||
toku_cachetable_verify(ct);
|
||||
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -12,7 +12,7 @@ cachetable_fd_test (void) {
|
|||
const int test_limit = 1;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE cf;
|
||||
|
@ -44,8 +44,8 @@ cachetable_fd_test (void) {
|
|||
r = toku_cachefile_of_filenum(ct, fn, &newcf);
|
||||
assert(r == ENOENT);
|
||||
|
||||
r = toku_cachefile_close(&cf, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&cf, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -28,7 +28,7 @@ cachetable_test (enum pin_evictor_test_type test_type, bool nonblocking) {
|
|||
const int test_limit = 7;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
evictor_test_helpers::set_hysteresis_limits(&ct->ev, test_limit, test_limit);
|
||||
evictor_test_helpers::disable_ev_thread(&ct->ev);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
|
@ -100,8 +100,8 @@ cachetable_test (enum pin_evictor_test_type test_type, bool nonblocking) {
|
|||
}
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -25,8 +25,8 @@ cachetable_test (void) {
|
|||
const int test_limit = 400;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
r = toku_set_cleaner_period(ct, 1); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
toku_set_cleaner_period(ct, 1);
|
||||
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
|
@ -43,12 +43,11 @@ cachetable_test (void) {
|
|||
r = toku_cachetable_get_and_pin(f1, make_blocknum(i), i, &v1, &s1, wc, def_fetch, def_pf_req_callback, def_pf_callback, true, NULL);
|
||||
r = toku_test_cachetable_unpin(f1, make_blocknum(i), i, CACHETABLE_DIRTY, make_pair_attr(8));
|
||||
}
|
||||
r = toku_cachefile_flush(f1);
|
||||
assert(r == 0);
|
||||
toku_cachefile_flush(f1);
|
||||
}
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ test_cachetable_def_flush (int n) {
|
|||
const int test_limit = 2*n;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -28,13 +28,11 @@ test_cachetable_def_flush (int n) {
|
|||
for (i=0; i<n; i++) {
|
||||
uint32_t hi;
|
||||
hi = toku_cachetable_hash(f1, make_blocknum(i));
|
||||
r = toku_cachetable_put(f1, make_blocknum(i), hi, (void *)(long)i, make_pair_attr(1), wc, put_callback_nop);
|
||||
assert(r == 0);
|
||||
toku_cachetable_put(f1, make_blocknum(i), hi, (void *)(long)i, make_pair_attr(1), wc, put_callback_nop);
|
||||
r = toku_test_cachetable_unpin(f1, make_blocknum(i), hi, CACHETABLE_CLEAN, make_pair_attr(1));
|
||||
assert(r == 0);
|
||||
hi = toku_cachetable_hash(f2, make_blocknum(i));
|
||||
r = toku_cachetable_put(f2, make_blocknum(i), hi, (void *)(long)i, make_pair_attr(1), wc, put_callback_nop);
|
||||
assert(r == 0);
|
||||
toku_cachetable_put(f2, make_blocknum(i), hi, (void *)(long)i, make_pair_attr(1), wc, put_callback_nop);
|
||||
r = toku_test_cachetable_unpin(f2, make_blocknum(i), hi, CACHETABLE_CLEAN, make_pair_attr(1));
|
||||
assert(r == 0);
|
||||
}
|
||||
|
@ -57,7 +55,7 @@ test_cachetable_def_flush (int n) {
|
|||
}
|
||||
|
||||
// def_flush
|
||||
r = toku_cachefile_flush(f1); assert(r == 0);
|
||||
toku_cachefile_flush(f1);
|
||||
toku_cachefile_verify(f1);
|
||||
|
||||
// verify keys do not exist in f1 but do exist in f2
|
||||
|
@ -74,9 +72,9 @@ test_cachetable_def_flush (int n) {
|
|||
assert(r == 0);
|
||||
}
|
||||
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachefile_close(&f2, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachefile_close(&f2, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -49,7 +49,7 @@ cachetable_getandpin_test (int n) {
|
|||
const int test_limit = 1024*1024;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test_getandpin.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -73,8 +73,8 @@ cachetable_getandpin_test (int n) {
|
|||
}
|
||||
toku_cachetable_verify(ct);
|
||||
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -29,7 +29,7 @@ run_test (void) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -43,16 +43,16 @@ run_test (void) {
|
|||
r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, &s1, wc, def_fetch, def_pf_req_callback, def_pf_callback, true, NULL);
|
||||
foo = false;
|
||||
cachefile_kibbutz_enq(f1, kibbutz_work, f1);
|
||||
r = toku_cachefile_flush(f1); assert(r == 0);
|
||||
toku_cachefile_flush(f1);
|
||||
assert(foo);
|
||||
assert(f1);
|
||||
|
||||
r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, &s1, wc, def_fetch, def_pf_req_callback, def_pf_callback, true, NULL);
|
||||
foo = false;
|
||||
cachefile_kibbutz_enq(f1, kibbutz_work, f1);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
assert(foo);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
toku_cachetable_close(&ct);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ cachetable_test (void) {
|
|||
int r;
|
||||
CACHETABLE ct;
|
||||
bool doing_prefetch = false;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -128,7 +128,7 @@ cachetable_test (void) {
|
|||
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_CLEAN, make_pair_attr(8));
|
||||
|
||||
// close and reopen cachefile so we can do some simple prefetch tests
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
|
||||
//
|
||||
// verify that a prefetch of the node will succeed
|
||||
|
@ -176,8 +176,8 @@ cachetable_test (void) {
|
|||
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -269,16 +269,14 @@ static void *checkpoints(void *arg) {
|
|||
//
|
||||
// now run a checkpoint
|
||||
//
|
||||
int r;
|
||||
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL); assert(r == 0);
|
||||
r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
assert(r==0);
|
||||
assert (sum==0);
|
||||
for (int i = 0; i < NUM_ELEMENTS; i++) {
|
||||
sum += checkpointed_data[i];
|
||||
|
@ -290,18 +288,12 @@ static void *checkpoints(void *arg) {
|
|||
return arg;
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
test_begin_checkpoint (
|
||||
LSN UU(checkpoint_lsn),
|
||||
void* UU(header_v))
|
||||
{
|
||||
memcpy(checkpointed_data, data, sizeof(int64_t)*NUM_ELEMENTS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dummy_int_checkpoint_userdata(CACHEFILE UU(cf), int UU(n), void* UU(extra)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sum_vals(void) {
|
||||
|
@ -336,7 +328,7 @@ cachetable_test (void) {
|
|||
|
||||
int r;
|
||||
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
|
||||
|
@ -344,13 +336,13 @@ cachetable_test (void) {
|
|||
toku_cachefile_set_userdata(
|
||||
f1,
|
||||
NULL,
|
||||
&dummy_log_fassociate,
|
||||
&dummy_log_rollback,
|
||||
&dummy_close_usr,
|
||||
dummy_int_checkpoint_userdata,
|
||||
test_begin_checkpoint, // called in begin_checkpoint
|
||||
dummy_int_checkpoint_userdata,
|
||||
&dummy_note_pin,
|
||||
&dummy_log_fassociate,
|
||||
&dummy_log_rollback,
|
||||
&dummy_close_usr,
|
||||
&dummy_chckpnt_usr,
|
||||
&test_begin_checkpoint,
|
||||
&dummy_end,
|
||||
&dummy_note_pin,
|
||||
&dummy_note_unpin
|
||||
);
|
||||
|
||||
|
@ -389,8 +381,8 @@ cachetable_test (void) {
|
|||
}
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
|
||||
sum_vals();
|
||||
if (verbose) printf("num_checkpoints %d\n", num_checkpoints);
|
||||
|
|
|
@ -15,7 +15,7 @@ run_test (void) {
|
|||
const int test_limit = 20;
|
||||
int r;
|
||||
ct = NULL;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
f1 = NULL;
|
||||
|
@ -37,7 +37,7 @@ run_test (void) {
|
|||
|
||||
r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v2, &s2, def_write_callback(NULL), def_fetch, def_pf_req_callback, def_pf_callback, true, NULL);
|
||||
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
// mark nodes as pending a checkpoint, so that get_and_pin_nonblocking on block 1 will return TOKUDB_TRY_AGAIN
|
||||
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_CLEAN, make_pair_attr(8)); assert(r==0);
|
||||
|
||||
|
@ -58,7 +58,7 @@ run_test (void) {
|
|||
assert(r==0);
|
||||
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_CLEAN, make_pair_attr(8)); assert(r==0);
|
||||
|
||||
r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -67,8 +67,8 @@ run_test (void) {
|
|||
assert(r==0);
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ static void cachetable_prefetch_checkpoint_test(int n, enum cachetable_dirty dir
|
|||
CACHETABLE ct;
|
||||
CACHETABLE_WRITE_CALLBACK wc = def_write_callback(NULL);
|
||||
wc.flush_callback = flush;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -88,8 +88,7 @@ static void cachetable_prefetch_checkpoint_test(int n, enum cachetable_dirty dir
|
|||
for (i=0; i<n; i++) {
|
||||
CACHEKEY key = make_blocknum(i);
|
||||
uint32_t hi = toku_cachetable_hash(f1, key);
|
||||
r = toku_cachetable_put(f1, key, hi, (void *)(long)i, make_pair_attr(1), wc, put_callback_nop);
|
||||
assert(r == 0);
|
||||
toku_cachetable_put(f1, key, hi, (void *)(long)i, make_pair_attr(1), wc, put_callback_nop);
|
||||
|
||||
r = toku_test_cachetable_unpin(f1, key, hi, dirty, make_pair_attr(item_size));
|
||||
assert(r == 0);
|
||||
|
@ -143,8 +142,8 @@ static void cachetable_prefetch_checkpoint_test(int n, enum cachetable_dirty dir
|
|||
assert(r == 0);
|
||||
assert(n_flush == 0 && n_write_me == 0 && n_keep_me == 0);
|
||||
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -54,7 +54,7 @@ static void cachetable_prefetch_close_leak_test (void) {
|
|||
const int test_limit = 1;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -70,8 +70,8 @@ static void cachetable_prefetch_close_leak_test (void) {
|
|||
|
||||
// close with the prefetch in progress. the close should block until
|
||||
// all of the reads and writes are complete.
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -56,7 +56,7 @@ static void cachetable_prefetch_full_test (bool partial_fetch) {
|
|||
expect_pf = false;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -97,8 +97,8 @@ static void cachetable_prefetch_full_test (bool partial_fetch) {
|
|||
|
||||
// close with the prefetch in progress. the close should block until
|
||||
// all of the reads and writes are complete.
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -67,7 +67,7 @@ fetch (CACHEFILE f __attribute__((__unused__)),
|
|||
static void cachetable_prefetch_flowcontrol_test (int cachetable_size_limit) {
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, cachetable_size_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, cachetable_size_limit, ZERO_LSN, NULL_LOGGER);
|
||||
evictor_test_helpers::set_hysteresis_limits(&ct->ev, cachetable_size_limit, cachetable_size_limit);
|
||||
evictor_test_helpers::disable_ev_thread(&ct->ev);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
|
@ -103,11 +103,10 @@ static void cachetable_prefetch_flowcontrol_test (int cachetable_size_limit) {
|
|||
}
|
||||
|
||||
|
||||
char *error_string;
|
||||
r = toku_cachefile_close(&f1, &error_string, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
if (verbose) printf("%s:%d 0x%x 0x%x\n", __FUNCTION__, __LINE__,
|
||||
evicted_keys, (1 << (2*cachetable_size_limit))-1);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -77,7 +77,7 @@ static void cachetable_prefetch_maybegetandpin_test (bool do_partial_fetch) {
|
|||
const int test_limit = 2;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -137,8 +137,8 @@ static void cachetable_prefetch_maybegetandpin_test (bool do_partial_fetch) {
|
|||
assert(r == 0);
|
||||
toku_cachetable_verify(ct);
|
||||
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -34,7 +34,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
|
|||
const int test_limit = 1;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -63,8 +63,8 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
|
|||
assert(r == 0);
|
||||
toku_cachetable_verify(ct);
|
||||
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -37,7 +37,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
|
|||
const int test_limit = 1;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -73,8 +73,8 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
|
|||
assert(r == 0);
|
||||
toku_cachetable_verify(ct);
|
||||
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -315,7 +315,7 @@ static void merge_and_split_child(
|
|||
CACHEKEY new_key;
|
||||
uint32_t new_fullhash;
|
||||
int64_t* XMALLOC(data_val);
|
||||
r = toku_cachetable_put_with_dep_pairs(
|
||||
toku_cachetable_put_with_dep_pairs(
|
||||
f1,
|
||||
get_data,
|
||||
data_val,
|
||||
|
@ -398,16 +398,14 @@ static void *checkpoints(void *arg) {
|
|||
//
|
||||
// now run a checkpoint
|
||||
//
|
||||
int r;
|
||||
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL); assert(r == 0);
|
||||
r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
assert(r==0);
|
||||
assert (sum==0);
|
||||
for (int i = 0; i < NUM_ELEMENTS; i++) {
|
||||
if (checkpointed_data[i] != INT64_MAX) {
|
||||
|
@ -420,13 +418,12 @@ static void *checkpoints(void *arg) {
|
|||
return arg;
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
test_begin_checkpoint (
|
||||
LSN UU(checkpoint_lsn),
|
||||
void* UU(header_v))
|
||||
{
|
||||
memcpy(checkpointed_data, data, sizeof(int64_t)*NUM_ELEMENTS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -470,7 +467,7 @@ cachetable_test (void) {
|
|||
|
||||
int r;
|
||||
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test-put-checkpoint.dat";
|
||||
unlink(fname1);
|
||||
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
|
||||
|
@ -481,9 +478,9 @@ cachetable_test (void) {
|
|||
&dummy_log_fassociate,
|
||||
&dummy_log_rollback,
|
||||
&dummy_close_usr,
|
||||
dummy_int_checkpoint_userdata,
|
||||
test_begin_checkpoint, // called in begin_checkpoint
|
||||
dummy_int_checkpoint_userdata,
|
||||
test_begin_checkpoint, // called in begin_checkpoint
|
||||
&dummy_end,
|
||||
&dummy_note_pin,
|
||||
&dummy_note_unpin
|
||||
);
|
||||
|
@ -523,8 +520,8 @@ cachetable_test (void) {
|
|||
}
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
|
||||
sum_vals();
|
||||
if (verbose) printf("num_checkpoints %d\n", num_checkpoints);
|
||||
|
|
|
@ -11,7 +11,7 @@ cachetable_put_test (int n) {
|
|||
const int test_limit = 2*n;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -22,8 +22,7 @@ cachetable_put_test (int n) {
|
|||
uint32_t hi;
|
||||
hi = toku_cachetable_hash(f1, make_blocknum(i));
|
||||
CACHETABLE_WRITE_CALLBACK wc = def_write_callback(NULL);
|
||||
r = toku_cachetable_put(f1, make_blocknum(i), hi, (void *)(long)i, make_pair_attr(1), wc, put_callback_nop);
|
||||
assert(r == 0);
|
||||
toku_cachetable_put(f1, make_blocknum(i), hi, (void *)(long)i, make_pair_attr(1), wc, put_callback_nop);
|
||||
assert(toku_cachefile_count_pinned(f1, 0) == i);
|
||||
|
||||
void *v;
|
||||
|
@ -45,8 +44,8 @@ cachetable_put_test (int n) {
|
|||
assert(toku_cachefile_count_pinned(f1, 1) == 0);
|
||||
toku_cachetable_verify(ct);
|
||||
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -59,7 +59,7 @@ CACHEFILE f;
|
|||
|
||||
static void open_file (void ) {
|
||||
int r;
|
||||
r = toku_create_cachetable(&t, KEYLIMIT, ZERO_LSN, NULL_LOGGER); assert(r==0);
|
||||
toku_cachetable_create(&t, KEYLIMIT, ZERO_LSN, NULL_LOGGER);
|
||||
r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ static void writeit (void) {
|
|||
for (j=0; j<BLOCKSIZE; j++) ((char*)buf)[j]=(char)((i+j)%256);
|
||||
CACHETABLE_WRITE_CALLBACK wc = def_write_callback(NULL);
|
||||
wc.flush_callback = f_flush;
|
||||
r = toku_cachetable_put(f, key, fullhash, buf, make_pair_attr(BLOCKSIZE), wc, put_callback_nop); assert(r==0);
|
||||
toku_cachetable_put(f, key, fullhash, buf, make_pair_attr(BLOCKSIZE), wc, put_callback_nop);
|
||||
r = toku_test_cachetable_unpin(f, key, fullhash, CACHETABLE_CLEAN, make_pair_attr(BLOCKSIZE)); assert(r==0);
|
||||
}
|
||||
gettimeofday(&end, 0);
|
||||
|
@ -101,8 +101,8 @@ static void readit (void) {
|
|||
r=toku_cachetable_get_and_pin(f, key, fullhash, &block, ¤t_size, wc, f_fetch, def_pf_req_callback, def_pf_callback, true, 0); assert(r==0);
|
||||
r=toku_test_cachetable_unpin(f, key, fullhash, CACHETABLE_CLEAN, make_pair_attr(BLOCKSIZE)); assert(r==0);
|
||||
}
|
||||
r = toku_cachefile_close(&f, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&t); assert(r == 0);
|
||||
r = toku_cachefile_close(&f, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&t);
|
||||
gettimeofday(&end, 0);
|
||||
toku_os_get_process_times(&end_usertime, &end_systime);
|
||||
double diff = toku_tdiff(&end, &start);
|
||||
|
|
|
@ -64,7 +64,7 @@ test_clean (enum cachetable_dirty dirty, bool cloneable) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -86,7 +86,7 @@ test_clean (enum cachetable_dirty dirty, bool cloneable) {
|
|||
// begin checkpoint, since pair is clean, we should not
|
||||
// have the clone called
|
||||
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
assert_zero(r);
|
||||
struct timeval tstart;
|
||||
struct timeval tend;
|
||||
|
@ -130,19 +130,18 @@ test_clean (enum cachetable_dirty dirty, bool cloneable) {
|
|||
assert(tdelta_usec(&tend, &tstart) >= 2000000);
|
||||
}
|
||||
|
||||
r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
assert_zero(r);
|
||||
|
||||
check_flush = false;
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -51,7 +51,7 @@ test_clean (enum cachetable_dirty dirty, bool cloneable) {
|
|||
const int test_limit = 200;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -70,28 +70,27 @@ test_clean (enum cachetable_dirty dirty, bool cloneable) {
|
|||
// begin checkpoint, since pair is clean, we should not
|
||||
// have the clone called
|
||||
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
assert_zero(r);
|
||||
r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, &s1, wc, def_fetch, def_pf_req_callback, def_pf_callback, true, NULL);
|
||||
|
||||
// at this point, there should be no more dirty writes
|
||||
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, dirty, make_pair_attr(8));
|
||||
usleep(2*1024*1024);
|
||||
r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
assert_zero(r);
|
||||
|
||||
check_flush = true;
|
||||
flush_expected = (dirty == CACHETABLE_DIRTY) ? true : false;
|
||||
flush_called = false;
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0 );
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0 );
|
||||
toku_cachetable_close(&ct);
|
||||
if (flush_expected) assert(flush_called);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ cachetable_test (void) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -52,26 +52,22 @@ cachetable_test (void) {
|
|||
assert(r==0);
|
||||
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_DIRTY, make_pair_attr(8));
|
||||
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL); assert(r == 0);
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
// now these should fail, because the node should be pending a checkpoint
|
||||
r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(1), 1, &v1);
|
||||
assert(r==-1);
|
||||
r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(1), 1, &v1);
|
||||
assert(r==-1);
|
||||
r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
assert(r==0);
|
||||
|
||||
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -40,7 +40,7 @@ run_test (pair_lock_type lock_type) {
|
|||
struct unlockers unlockers = {true, unlock_dummy, NULL, NULL};
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -81,9 +81,9 @@ run_test (pair_lock_type lock_type) {
|
|||
}
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN);
|
||||
assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -69,7 +69,7 @@ cachetable_test (bool write_first, bool write_second, bool start_checkpoint) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -107,7 +107,7 @@ cachetable_test (bool write_first, bool write_second, bool start_checkpoint) {
|
|||
//
|
||||
// should mark the v1 and v2 as pending
|
||||
//
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL); assert(r==0);
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
}
|
||||
//
|
||||
// This call should cause a flush for both
|
||||
|
@ -145,20 +145,17 @@ cachetable_test (bool write_first, bool write_second, bool start_checkpoint) {
|
|||
r = toku_test_cachetable_unpin(f1, make_blocknum(3), 3, CACHETABLE_CLEAN, make_pair_attr(8));
|
||||
|
||||
if (start_checkpoint) {
|
||||
r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
assert(r==0);
|
||||
}
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
|
||||
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -79,7 +79,7 @@ run_test (void) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -109,9 +109,9 @@ run_test (void) {
|
|||
run_case_that_should_fail(f1, PL_WRITE_EXPENSIVE, PL_WRITE_EXPENSIVE);
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN);
|
||||
assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -62,7 +62,7 @@ run_test (void) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -109,25 +109,20 @@ run_test (void) {
|
|||
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_DIRTY, make_pair_attr(8)); assert(r==0);
|
||||
// this should mark the PAIR as pending
|
||||
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL); assert(r == 0);
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
r = toku_cachetable_get_and_pin_nonblocking(f1, make_blocknum(1), 1, &v1, &s1, wc, def_fetch, def_pf_req_callback, def_pf_callback, PL_WRITE_EXPENSIVE, NULL, NULL);
|
||||
assert(r==TOKUDB_TRY_AGAIN);
|
||||
r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
assert(r==0);
|
||||
|
||||
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN);
|
||||
assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
|
||||
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -54,7 +54,7 @@ run_test (void) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -81,7 +81,7 @@ run_test (void) {
|
|||
|
||||
// now this should mark the pair for checkpoint
|
||||
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
|
||||
//
|
||||
// now we pin the pair again, and verify in flush callback that the pair is being checkpointed
|
||||
|
@ -94,20 +94,16 @@ run_test (void) {
|
|||
|
||||
|
||||
check_me = false;
|
||||
r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
assert(r==0);
|
||||
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
|
||||
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -76,7 +76,7 @@ cachetable_test (bool write_first, bool write_second, bool start_checkpoint) {
|
|||
const int test_limit = 12;
|
||||
int r;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
CACHEFILE f1;
|
||||
|
@ -112,7 +112,7 @@ cachetable_test (bool write_first, bool write_second, bool start_checkpoint) {
|
|||
//
|
||||
// should mark the v1 and v2 as pending
|
||||
//
|
||||
r = toku_cachetable_begin_checkpoint(cp, NULL); assert(r==0);
|
||||
toku_cachetable_begin_checkpoint(cp, NULL);
|
||||
}
|
||||
//
|
||||
// This call should cause a flush for both
|
||||
|
@ -123,7 +123,7 @@ cachetable_test (bool write_first, bool write_second, bool start_checkpoint) {
|
|||
|
||||
CACHEKEY put_key;
|
||||
uint32_t put_fullhash;
|
||||
r = toku_cachetable_put_with_dep_pairs(
|
||||
toku_cachetable_put_with_dep_pairs(
|
||||
f1,
|
||||
get_key_and_fullhash,
|
||||
&val3,
|
||||
|
@ -139,7 +139,6 @@ cachetable_test (bool write_first, bool write_second, bool start_checkpoint) {
|
|||
&put_fullhash,
|
||||
put_callback_nop
|
||||
);
|
||||
assert(r == 0);
|
||||
assert(put_key.b == 3);
|
||||
assert(put_fullhash == 3);
|
||||
|
||||
|
@ -154,18 +153,17 @@ cachetable_test (bool write_first, bool write_second, bool start_checkpoint) {
|
|||
r = toku_test_cachetable_unpin(f1, make_blocknum(3), 3, CACHETABLE_CLEAN, make_pair_attr(8));
|
||||
|
||||
if (start_checkpoint) {
|
||||
r = toku_cachetable_end_checkpoint(
|
||||
toku_cachetable_end_checkpoint(
|
||||
cp,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
assert(r==0);
|
||||
}
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ run_test (void) {
|
|||
int r;
|
||||
void *ret;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
|
||||
|
@ -112,8 +112,8 @@ run_test (void) {
|
|||
assert_zero(r);
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -73,7 +73,7 @@ run_test (void) {
|
|||
int r;
|
||||
void *ret;
|
||||
CACHETABLE ct;
|
||||
r = toku_create_cachetable(&ct, test_limit, ZERO_LSN, NULL_LOGGER); assert(r == 0);
|
||||
toku_cachetable_create(&ct, test_limit, ZERO_LSN, NULL_LOGGER);
|
||||
char fname1[] = __SRCFILE__ "test1.dat";
|
||||
unlink(fname1);
|
||||
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
|
||||
|
@ -122,8 +122,8 @@ run_test (void) {
|
|||
assert_zero(r);
|
||||
|
||||
toku_cachetable_verify(ct);
|
||||
r = toku_cachefile_close(&f1, 0, false, ZERO_LSN); assert(r == 0);
|
||||
r = toku_cachetable_close(&ct); lazy_assert_zero(r);
|
||||
r = toku_cachefile_close(&f1, false, ZERO_LSN); assert(r == 0);
|
||||
toku_cachetable_close(&ct);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue