diff --git a/buildheader/make_tdb.c b/buildheader/make_tdb.c index 036093a3ab1..cd3eb5b0c53 100644 --- a/buildheader/make_tdb.c +++ b/buildheader/make_tdb.c @@ -430,8 +430,11 @@ static void print_db_struct (void) { "int (*optimize)(DB*) /* Run garbage collecion and promote all transactions older than oldest. Amortized (happens during flattening) */", "int (*hot_optimize)(DB*, int (*progress_callback)(void *progress_extra, float progress), void *progress_extra)", "int (*get_fragmentation)(DB*,TOKU_DB_FRAGMENTATION)", + "int (*change_pagesize)(DB*,u_int32_t)", + "int (*change_readpagesize)(DB*,u_int32_t)", "int (*get_readpagesize)(DB*,u_int32_t*)", "int (*set_readpagesize)(DB*,u_int32_t)", + "int (*change_compression_method)(DB*,TOKU_COMPRESSION_METHOD)", "int (*get_compression_method)(DB*,TOKU_COMPRESSION_METHOD*)", "int (*set_compression_method)(DB*,TOKU_COMPRESSION_METHOD)", "int (*set_indexer)(DB*, DB_INDEXER*)", diff --git a/ft/ft-internal.h b/ft/ft-internal.h index 0cff575bb82..2637b8cf14e 100644 --- a/ft/ft-internal.h +++ b/ft/ft-internal.h @@ -374,9 +374,11 @@ struct ft_header { BLOCKNUM root_blocknum; const unsigned int flags; - const unsigned int nodesize; - const unsigned int basementnodesize; - const enum toku_compression_method compression_method; + + //protected by toku_ft_lock + unsigned int nodesize; + unsigned int basementnodesize; + enum toku_compression_method compression_method; // Current Minimum MSN to be used when upgrading pre-MSN BRT's. // This is decremented from our currnt MIN_MSN so as not to clash diff --git a/ft/ft-ops.c b/ft/ft-ops.c index 59b520c3edd..874854ad6d2 100644 --- a/ft/ft-ops.c +++ b/ft/ft-ops.c @@ -2988,9 +2988,9 @@ int toku_open_ft_handle (const char *fname, int is_create, FT_HANDLE *ft_handle_ r = toku_ft_handle_create(&brt); if (r != 0) return r; - r = toku_ft_set_nodesize(brt, nodesize); assert_zero(r); - r = toku_ft_set_basementnodesize(brt, basementnodesize); assert_zero(r); - r = toku_ft_set_compression_method(brt, compression_method); assert_zero(r); + 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); r = toku_ft_handle_open(brt, fname, is_create, only_create, cachetable, txn); @@ -3042,18 +3042,26 @@ static int ft_open_file(const char *fname, int *fdp) { return 0; } -int -toku_ft_set_compression_method(FT_HANDLE t, enum toku_compression_method method) +void +toku_ft_handle_set_compression_method(FT_HANDLE t, enum toku_compression_method method) { - t->options.compression_method = method; - return 0; + if (t->ft) { + toku_ft_set_compression_method(t->ft, method); + } + else { + t->options.compression_method = method; + } } -int -toku_ft_get_compression_method(FT_HANDLE t, enum toku_compression_method *methodp) +void +toku_ft_handle_get_compression_method(FT_HANDLE t, enum toku_compression_method *methodp) { - *methodp = t->options.compression_method; - return 0; + if (t->ft) { + toku_ft_get_compression_method(t->ft, methodp); + } + else { + *methodp = t->options.compression_method; + } } static int @@ -3389,17 +3397,6 @@ int toku_ft_get_flags(FT_HANDLE brt, unsigned int *flags) { return 0; } - -int toku_ft_set_nodesize(FT_HANDLE brt, unsigned int nodesize) { - brt->options.nodesize = nodesize; - return 0; -} - -int toku_ft_get_nodesize(FT_HANDLE brt, unsigned int *nodesize) { - *nodesize = brt->options.nodesize; - return 0; -} - void toku_ft_get_maximum_advised_key_value_lengths (unsigned int *max_key_len, unsigned int *max_val_len) // return the maximum advisable key value lengths. The brt doesn't enforce these. { @@ -3407,14 +3404,41 @@ void toku_ft_get_maximum_advised_key_value_lengths (unsigned int *max_key_len, u *max_val_len = 32*1024*1024; } -int toku_ft_set_basementnodesize(FT_HANDLE brt, unsigned int basementnodesize) { - brt->options.basementnodesize = basementnodesize; - return 0; + +void toku_ft_handle_set_nodesize(FT_HANDLE ft_handle, unsigned int nodesize) { + if (ft_handle->ft) { + toku_ft_set_nodesize(ft_handle->ft, nodesize); + } + else { + ft_handle->options.nodesize = nodesize; + } } -int toku_ft_get_basementnodesize(FT_HANDLE brt, unsigned int *basementnodesize) { - *basementnodesize = brt->options.basementnodesize; - return 0; +void toku_ft_handle_get_nodesize(FT_HANDLE ft_handle, unsigned int *nodesize) { + if (ft_handle->ft) { + toku_ft_get_nodesize(ft_handle->ft, nodesize); + } + else { + *nodesize = ft_handle->options.nodesize; + } +} + +void toku_ft_handle_set_basementnodesize(FT_HANDLE ft_handle, unsigned int basementnodesize) { + if (ft_handle->ft) { + toku_ft_set_basementnodesize(ft_handle->ft, basementnodesize); + } + else { + ft_handle->options.basementnodesize = basementnodesize; + } +} + +void toku_ft_handle_get_basementnodesize(FT_HANDLE ft_handle, unsigned int *basementnodesize) { + if (ft_handle->ft) { + toku_ft_get_basementnodesize(ft_handle->ft, basementnodesize); + } + else { + *basementnodesize = ft_handle->options.basementnodesize; + } } int toku_ft_set_bt_compare(FT_HANDLE brt, int (*bt_compare)(DB*, const DBT*, const DBT*)) { diff --git a/ft/ft-ops.h b/ft/ft-ops.h index 5d3d450f277..8f85798f33a 100644 --- a/ft/ft-ops.h +++ b/ft/ft-ops.h @@ -43,13 +43,13 @@ u_int32_t toku_serialize_descriptor_size(const DESCRIPTOR desc); int toku_ft_handle_create(FT_HANDLE *) __attribute__ ((warn_unused_result)); int toku_ft_set_flags(FT_HANDLE, unsigned int flags) __attribute__ ((warn_unused_result)); int toku_ft_get_flags(FT_HANDLE, unsigned int *flags) __attribute__ ((warn_unused_result)); -int toku_ft_set_nodesize(FT_HANDLE, unsigned int nodesize) __attribute__ ((warn_unused_result)); -int toku_ft_get_nodesize(FT_HANDLE, unsigned int *nodesize) __attribute__ ((warn_unused_result)); +void toku_ft_handle_set_nodesize(FT_HANDLE, unsigned int nodesize); +void toku_ft_handle_get_nodesize(FT_HANDLE, unsigned int *nodesize); void toku_ft_get_maximum_advised_key_value_lengths(unsigned int *klimit, unsigned int *vlimit); -int toku_ft_set_basementnodesize(FT_HANDLE, unsigned int basementnodesize) __attribute__ ((warn_unused_result)); -int toku_ft_get_basementnodesize(FT_HANDLE, unsigned int *basementnodesize) __attribute__ ((warn_unused_result)); -int toku_ft_set_compression_method(FT_HANDLE, enum toku_compression_method) __attribute__ ((warn_unused_result)); -int toku_ft_get_compression_method(FT_HANDLE, enum toku_compression_method *) __attribute__((warn_unused_result)); +void toku_ft_handle_set_basementnodesize(FT_HANDLE, unsigned int basementnodesize); +void toku_ft_handle_get_basementnodesize(FT_HANDLE, unsigned int *basementnodesize); +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)); ft_compare_func toku_ft_get_bt_compare (FT_HANDLE brt); diff --git a/ft/ft.c b/ft/ft.c index 39f1966be87..846ba98cee1 100644 --- a/ft/ft.c +++ b/ft/ft.c @@ -665,12 +665,9 @@ ft_handle_open_for_redirect(FT_HANDLE *new_ftp, const char *fname_in_env, TOKUTX assert_zero(r); r = toku_ft_set_update(t, old_h->update_fun); assert_zero(r); - r = toku_ft_set_nodesize(t, old_h->h->nodesize); - assert_zero(r); - r = toku_ft_set_basementnodesize(t, old_h->h->basementnodesize); - assert_zero(r); - r = toku_ft_set_compression_method(t, old_h->h->compression_method); - assert_zero(r); + 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); assert_zero(r); @@ -1014,3 +1011,43 @@ toku_ft_remove_reference(FT ft, bool oplsn_valid, LSN oplsn, remove_ft_ref_callb } } +void toku_ft_set_nodesize(FT ft, unsigned int nodesize) { + toku_ft_lock(ft); + ft->h->nodesize = nodesize; + ft->h->dirty = 1; + toku_ft_unlock(ft); +} + +void toku_ft_get_nodesize(FT ft, unsigned int *nodesize) { + toku_ft_lock(ft); + *nodesize = ft->h->nodesize; + toku_ft_unlock(ft); +} + +void toku_ft_set_basementnodesize(FT ft, unsigned int basementnodesize) { + toku_ft_lock(ft); + ft->h->basementnodesize = basementnodesize; + ft->h->dirty = 1; + toku_ft_unlock(ft); +} + +void toku_ft_get_basementnodesize(FT ft, unsigned int *basementnodesize) { + toku_ft_lock(ft); + *basementnodesize = ft->h->basementnodesize; + toku_ft_unlock(ft); +} + +void toku_ft_set_compression_method(FT ft, enum toku_compression_method method) { + toku_ft_lock(ft); + ft->h->compression_method = method; + ft->h->dirty = 1; + toku_ft_unlock(ft); +} + +void toku_ft_get_compression_method(FT ft, enum toku_compression_method *methodp) { + toku_ft_lock(ft); + *methodp = ft->h->compression_method; + toku_ft_unlock(ft); +} + + diff --git a/ft/ft.h b/ft/ft.h index 7f6914b77dc..761fef42524 100644 --- a/ft/ft.h +++ b/ft/ft.h @@ -102,4 +102,12 @@ void toku_ft_remove_reference(FT ft, bool oplsn_valid, LSN oplsn, remove_ft_ref_callback remove_ref, void *extra); +void toku_ft_set_nodesize(FT ft, unsigned int nodesize); +void toku_ft_get_nodesize(FT ft, unsigned int *nodesize); +void toku_ft_set_basementnodesize(FT ft, unsigned int basementnodesize); +void toku_ft_get_basementnodesize(FT ft, unsigned int *basementnodesize); +void toku_ft_set_compression_method(FT ft, enum toku_compression_method method); +void toku_ft_get_compression_method(FT ft, enum toku_compression_method *methodp); + + #endif diff --git a/ft/recover.c b/ft/recover.c index fb5ed0bfcfb..bd7cabadf24 100644 --- a/ft/recover.c +++ b/ft/recover.c @@ -276,18 +276,15 @@ static int internal_recover_fopen_or_fcreate (RECOVER_ENV renv, BOOL must_create assert(r == 0); if (nodesize != 0) { - r = toku_ft_set_nodesize(brt, nodesize); - assert(r == 0); + toku_ft_handle_set_nodesize(brt, nodesize); } if (basementnodesize != 0) { - r = toku_ft_set_basementnodesize(brt, basementnodesize); - assert(r == 0); + toku_ft_handle_set_basementnodesize(brt, basementnodesize); } if (compression_method != TOKU_DEFAULT_COMPRESSION_METHOD) { - r = toku_ft_set_compression_method(brt, compression_method); - assert(r == 0); + toku_ft_handle_set_compression_method(brt, compression_method); } // set the key compare functions diff --git a/ft/tests/ft-test.c b/ft/tests/ft-test.c index 6ecbff62c3d..d986a801736 100644 --- a/ft/tests/ft-test.c +++ b/ft/tests/ft-test.c @@ -829,7 +829,7 @@ static void test_new_ft_cursor_first(int n) { r = toku_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0); unlink(fname); r = toku_ft_handle_create(&t); assert(r == 0); - r = toku_ft_set_nodesize(t, 4096); assert(r == 0); + toku_ft_handle_set_nodesize(t, 4096); r = toku_ft_handle_open(t, fname, 1, 1, ct, null_txn); assert(r==0); DBT key, val; @@ -881,7 +881,7 @@ static void test_new_ft_cursor_last(int n) { r = toku_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0); unlink(fname); r = toku_ft_handle_create(&t); assert(r == 0); - r = toku_ft_set_nodesize(t, 4096); assert(r == 0); + toku_ft_handle_set_nodesize(t, 4096); r = toku_ft_handle_open(t, fname, 1, 1, ct, null_txn); assert(r==0); DBT key, val; @@ -934,7 +934,7 @@ static void test_new_ft_cursor_next(int n) { r = toku_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0); unlink(fname); r = toku_ft_handle_create(&t); assert(r == 0); - r = toku_ft_set_nodesize(t, 4096); assert(r == 0); + toku_ft_handle_set_nodesize(t, 4096); r = toku_ft_handle_open(t, fname, 1, 1, ct, null_txn); assert(r==0); for (i=0; i +#include +#include +#include + + +int +test_main (int UU(argc), char UU(*const argv[])) { + int r; + DB_ENV *env; + DB *db; + r = system("rm -rf " ENVDIR); + CKERR(r); + r=toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); assert(r==0); + r=db_env_create(&env, 0); assert(r==0); + r=env->open(env, ENVDIR, DB_PRIVATE|DB_CREATE, S_IRWXU+S_IRWXG+S_IRWXO); assert(r==0); + + u_int32_t ret_val = 0; + r = db_create(&db, env, 0); + CKERR(r); + r = db->set_pagesize(db, 112024); + CKERR(r); + r = db->change_pagesize(db, 202433); + CKERR2(r, EINVAL); + r = db->get_pagesize(db, &ret_val); + CKERR(r); + assert(ret_val == 112024); + r = db->set_readpagesize(db, 33024); + CKERR(r); + r = db->change_readpagesize(db, 202433); + CKERR2(r, EINVAL); + r = db->get_readpagesize(db, &ret_val); + CKERR(r); + assert(ret_val == 33024); + + enum toku_compression_method method = TOKU_ZLIB_METHOD; + enum toku_compression_method ret_method = TOKU_NO_COMPRESSION; + r = db->set_compression_method(db, method); + CKERR(r); + r = db->change_compression_method(db, method); + CKERR2(r, EINVAL); + r = db->get_compression_method(db, &ret_method); + CKERR(r); + assert(ret_method == TOKU_ZLIB_METHOD); + + // now do the open + const char * const fname = "test.change_xxx"; + r = db->open(db, NULL, fname, "main", DB_BTREE, DB_CREATE, 0666); + CKERR(r); + + r = db->get_pagesize(db, &ret_val); + CKERR(r); + assert(ret_val == 112024); + r = db->get_readpagesize(db, &ret_val); + CKERR(r); + assert(ret_val == 33024); + ret_method = TOKU_NO_COMPRESSION; + r = db->get_compression_method(db, &ret_method); + CKERR(r); + assert(ret_method == TOKU_ZLIB_METHOD); + + r = db->set_pagesize(db, 2024); + CKERR2(r, EINVAL); + r = db->set_readpagesize(db, 1111); + CKERR2(r, EINVAL); + r = db->set_compression_method(db, TOKU_NO_COMPRESSION); + CKERR2(r, EINVAL); + + r = db->change_pagesize(db, 100000); + CKERR(r); + r = db->change_readpagesize(db, 10000); + CKERR(r); + r = db->change_compression_method(db, TOKU_LZMA_METHOD); + CKERR(r); + + r = db->get_pagesize(db, &ret_val); + CKERR(r); + assert(ret_val == 100000); + r = db->get_readpagesize(db, &ret_val); + CKERR(r); + assert(ret_val == 10000); + ret_method = TOKU_NO_COMPRESSION; + r = db->get_compression_method(db, &ret_method); + CKERR(r); + assert(ret_method == TOKU_LZMA_METHOD); + + r = db->close(db, 0); + + r = db_create(&db, env, 0); + CKERR(r); + r = db->open(db, NULL, fname, "main", DB_BTREE, DB_AUTO_COMMIT, 0666); + CKERR(r); + + r = db->get_pagesize(db, &ret_val); + CKERR(r); + assert(ret_val == 100000); + r = db->get_readpagesize(db, &ret_val); + CKERR(r); + assert(ret_val == 10000); + ret_method = TOKU_NO_COMPRESSION; + r = db->get_compression_method(db, &ret_method); + CKERR(r); + assert(ret_method == TOKU_LZMA_METHOD); + + r = db->close(db, 0); + + r=env->close(env, 0); assert(r==0); + return 0; +} diff --git a/src/ydb_db.c b/src/ydb_db.c index 12004aa404b..28097df21bf 100644 --- a/src/ydb_db.c +++ b/src/ydb_db.c @@ -542,46 +542,73 @@ toku_db_get_flags(DB *db, u_int32_t *pflags) { return 0; } +static int +toku_db_change_pagesize(DB *db, u_int32_t pagesize) { + HANDLE_PANICKED_DB(db); + if (!db_opened(db)) return EINVAL; + toku_ft_handle_set_nodesize(db->i->ft_handle, pagesize); + return 0; +} + static int toku_db_set_pagesize(DB *db, u_int32_t pagesize) { HANDLE_PANICKED_DB(db); - int r = toku_ft_set_nodesize(db->i->ft_handle, pagesize); - return r; + if (db_opened(db)) return EINVAL; + toku_ft_handle_set_nodesize(db->i->ft_handle, pagesize); + return 0; } static int toku_db_get_pagesize(DB *db, u_int32_t *pagesize_ptr) { HANDLE_PANICKED_DB(db); - int r = toku_ft_get_nodesize(db->i->ft_handle, pagesize_ptr); - return r; + toku_ft_handle_get_nodesize(db->i->ft_handle, pagesize_ptr); + return 0; +} + +static int +toku_db_change_readpagesize(DB *db, u_int32_t readpagesize) { + HANDLE_PANICKED_DB(db); + if (!db_opened(db)) return EINVAL; + toku_ft_handle_set_basementnodesize(db->i->ft_handle, readpagesize); + return 0; } static int toku_db_set_readpagesize(DB *db, u_int32_t readpagesize) { HANDLE_PANICKED_DB(db); - int r = toku_ft_set_basementnodesize(db->i->ft_handle, readpagesize); - return r; + if (db_opened(db)) return EINVAL; + toku_ft_handle_set_basementnodesize(db->i->ft_handle, readpagesize); + return 0; } static int toku_db_get_readpagesize(DB *db, u_int32_t *readpagesize_ptr) { HANDLE_PANICKED_DB(db); - int r = toku_ft_get_basementnodesize(db->i->ft_handle, readpagesize_ptr); - return r; + toku_ft_handle_get_basementnodesize(db->i->ft_handle, readpagesize_ptr); + return 0; +} + +static int +toku_db_change_compression_method(DB *db, enum toku_compression_method compression_method) { + HANDLE_PANICKED_DB(db); + if (!db_opened(db)) return EINVAL; + toku_ft_handle_set_compression_method(db->i->ft_handle, compression_method); + return 0; } static int toku_db_set_compression_method(DB *db, enum toku_compression_method compression_method) { HANDLE_PANICKED_DB(db); - int r = toku_ft_set_compression_method(db->i->ft_handle, compression_method); - return r; + if (db_opened(db)) return EINVAL; + toku_ft_handle_set_compression_method(db->i->ft_handle, compression_method); + return 0; } static int toku_db_get_compression_method(DB *db, enum toku_compression_method *compression_method_ptr) { HANDLE_PANICKED_DB(db); - int r = toku_ft_get_compression_method(db->i->ft_handle, compression_method_ptr); - return r; + toku_ft_handle_get_compression_method(db->i->ft_handle, compression_method_ptr); + return 0; } static int @@ -866,10 +893,13 @@ toku_db_create(DB ** db, DB_ENV * env, u_int32_t flags) { USDB(set_errfile); USDB(set_pagesize); USDB(get_pagesize); + USDB(change_pagesize); USDB(set_readpagesize); USDB(get_readpagesize); + USDB(change_readpagesize); USDB(set_compression_method); USDB(get_compression_method); + USDB(change_compression_method); USDB(set_flags); USDB(get_flags); USDB(fd);