mirror of
https://github.com/MariaDB/server.git
synced 2025-01-22 06:44:16 +01:00
Merge 2948 changes to main: Start putting upsert into brt layer (Refs #2948). Also add unused attributes (Closes #2950). [t:2948] close[t:2950]
{{{ svn merge -c 24081 https://svn.tokutek.com/tokudb/toku/tokudb.2948 }}} . git-svn-id: file:///svn/toku/tokudb@24083 c7de825b-a66e-492c-adef-691d508d4ae1
This commit is contained in:
parent
db868fb31d
commit
bb5579a145
17 changed files with 162 additions and 106 deletions
|
@ -201,6 +201,24 @@ struct brt {
|
|||
BOOL did_set_descriptor;
|
||||
DESCRIPTOR_S temp_descriptor;
|
||||
int (*compare_fun)(DB*,const DBT*,const DBT*);
|
||||
|
||||
// When an upsert message arrives it contains a key, a value (upserted_val), and an extra DBT (upserted_extra).
|
||||
// If there is no such key in the database, then the upserted value is inserted.
|
||||
// If there is such a key in the database, then there is associated with that key another value (prev_val).
|
||||
// The system calls upsert_fun(DB, upserted_value, upserted_extra, prev_val, set_val, set_extra)
|
||||
// where set_val and set_extra are provided by the system.
|
||||
// The upsert_fun can look at the DBTs and the DB (to get the db descriptor) and perform one of the following actions:
|
||||
// a) It can return DB_DELETE_UPSERT (which is defined in db.h). In this case, the system deletes the key-value pair.
|
||||
// b) OR it can return call set_val(new_val, set_extra),
|
||||
// where new_val is the dbt that was passed in. The set_val function will copy anything it needs out of new_val, so the memory pointed
|
||||
// to by new_val may be stack allocated by upsert_fun (or it may be malloced, in which case upsert_fun should free that memory).
|
||||
// Notes:
|
||||
// 1) The DBTs passed to upsert_fun may point to memory that will be freed after the upsert_fun returns.
|
||||
// 2) Furtheremore, there is likely to be some sort of lock held when upsert_fun is called.
|
||||
// Those notes should not matter, since the upsert_fun should essentially be a pure function of the DBTs and DB descriptor passed in.
|
||||
int (*upsert_fun)(DB*, const DBT*key, const DBT *upserted_val, const DBT *upserted_extra, const DBT *prev_val,
|
||||
void (*set_val)(const DBT *new_val, void*set_extra), void *set_extra);
|
||||
|
||||
DB *db; // To pass to the compare fun, and close once transactions are done.
|
||||
|
||||
OMT txns; // transactions that are using this OMT (note that the transaction checks the cf also)
|
||||
|
|
13
newbrt/brt.c
13
newbrt/brt.c
|
@ -516,7 +516,6 @@ toku_cmd_leafval_heaviside (OMTVALUE lev, void *extra) {
|
|||
be);
|
||||
}
|
||||
|
||||
// If you pass in data==0 then it only compares the key, not the data (even if is a DUPSORT database)
|
||||
static int
|
||||
brt_compare_pivot(BRT brt, DBT *key, bytevec ck)
|
||||
{
|
||||
|
@ -2844,8 +2843,8 @@ int toku_open_brt (const char *fname, int is_create, BRT *newbrt, int nodesize,
|
|||
r = toku_brt_create(&brt);
|
||||
if (r != 0)
|
||||
return r;
|
||||
toku_brt_set_nodesize(brt, nodesize);
|
||||
toku_brt_set_bt_compare(brt, compare_fun);
|
||||
r = toku_brt_set_nodesize(brt, nodesize); assert(r==0);
|
||||
r = toku_brt_set_bt_compare(brt, compare_fun); assert(r==0);
|
||||
|
||||
r = toku_brt_open(brt, fname, is_create, only_create, cachetable, txn, db);
|
||||
if (r != 0) {
|
||||
|
@ -3619,7 +3618,7 @@ int toku_brt_set_flags(BRT brt, unsigned int flags) {
|
|||
|
||||
int toku_brt_get_flags(BRT brt, unsigned int *flags) {
|
||||
*flags = brt->flags;
|
||||
assert(brt->flags==(brt->flags&TOKU_DB_KEYCMP_BUILTIN)); // make sure there are no extranious flags
|
||||
assert(brt->flags==(brt->flags&TOKU_DB_KEYCMP_BUILTIN)); // make sure there are no extraneous flags
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3639,6 +3638,12 @@ int toku_brt_set_bt_compare(BRT brt, int (*bt_compare)(DB *, const DBT*, const D
|
|||
return 0;
|
||||
}
|
||||
|
||||
int toku_brt_set_upsert(BRT brt, int (*upsert)(DB *, const DBT *key, const DBT *upserted_val, const DBT *upserted_extra, const DBT *prev_val,
|
||||
void (*set_val)(const DBT *new_val, void *set_extra), void *set_extra)) {
|
||||
brt->upsert_fun = upsert;
|
||||
return 0;
|
||||
}
|
||||
|
||||
brt_compare_func toku_brt_get_bt_compare (BRT brt) {
|
||||
return brt->compare_fun;
|
||||
}
|
||||
|
|
153
newbrt/brt.h
153
newbrt/brt.h
|
@ -28,133 +28,136 @@ C_BEGIN
|
|||
//-infinity depending on direction)
|
||||
typedef int(*BRT_GET_CALLBACK_FUNCTION)(ITEMLEN, bytevec, ITEMLEN, bytevec, void*);
|
||||
|
||||
int toku_open_brt (const char *fname, int is_create, BRT *, int nodesize, CACHETABLE, TOKUTXN, int(*)(DB*,const DBT*,const DBT*), DB*);
|
||||
int toku_maybe_upgrade_descriptor(BRT t, DESCRIPTOR d, BOOL do_log, TOKUTXN txn);
|
||||
int toku_open_brt (const char *fname, int is_create, BRT *, int nodesize, CACHETABLE, TOKUTXN, int(*)(DB*,const DBT*,const DBT*), DB*) __attribute__ ((warn_unused_result));
|
||||
int toku_maybe_upgrade_descriptor(BRT t, DESCRIPTOR d, BOOL do_log, TOKUTXN txn) __attribute__ ((warn_unused_result));
|
||||
|
||||
int toku_dictionary_redirect (const char *dst_fname_in_env, BRT old_brt, TOKUTXN txn);
|
||||
int toku_dictionary_redirect (const char *dst_fname_in_env, BRT old_brt, TOKUTXN txn) __attribute__ ((warn_unused_result));
|
||||
// See the brt.c file for what this toku_redirect_brt does
|
||||
|
||||
int toku_dictionary_redirect_abort(struct brt_header *old_h, struct brt_header *new_h, TOKUTXN txn);
|
||||
int toku_dictionary_redirect_abort(struct brt_header *old_h, struct brt_header *new_h, TOKUTXN txn) __attribute__ ((warn_unused_result));
|
||||
|
||||
u_int32_t toku_serialize_descriptor_size(const DESCRIPTOR desc);
|
||||
int toku_brt_create(BRT *);
|
||||
int toku_brt_set_flags(BRT, unsigned int flags);
|
||||
int toku_brt_get_flags(BRT, unsigned int *flags);
|
||||
int toku_brt_set_descriptor (BRT t, u_int32_t version, const DBT* descriptor);
|
||||
int toku_brt_set_nodesize(BRT, unsigned int nodesize);
|
||||
int toku_brt_get_nodesize(BRT, unsigned int *nodesize);
|
||||
int toku_brt_create(BRT *) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_set_flags(BRT, unsigned int flags) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_get_flags(BRT, unsigned int *flags) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_set_descriptor (BRT t, u_int32_t version, const DBT* descriptor) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_set_nodesize(BRT, unsigned int nodesize) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_get_nodesize(BRT, unsigned int *nodesize) __attribute__ ((warn_unused_result));
|
||||
|
||||
int toku_brt_set_bt_compare(BRT, brt_compare_func);
|
||||
int toku_brt_set_bt_compare(BRT, brt_compare_func) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_set_upsert(BRT brt, int (*upsert)(DB *, const DBT *key, const DBT *upserted_val, const DBT *upserted_extra, const DBT *prev_val,
|
||||
void (*set_val)(const DBT *new_val, void *set_extra), void *set_extra))
|
||||
__attribute__ ((warn_unused_result));
|
||||
|
||||
brt_compare_func toku_brt_get_bt_compare (BRT brt);
|
||||
|
||||
int brt_set_cachetable(BRT, CACHETABLE);
|
||||
int toku_brt_open(BRT, const char *fname_in_env,
|
||||
int is_create, int only_create, CACHETABLE ct, TOKUTXN txn, DB *db);
|
||||
int is_create, int only_create, CACHETABLE ct, TOKUTXN txn, DB *db) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_open_recovery(BRT, const char *fname_in_env,
|
||||
int is_create, int only_create, CACHETABLE ct, TOKUTXN txn, DB *db, FILENUM use_filenum);
|
||||
int is_create, int only_create, CACHETABLE ct, TOKUTXN txn, DB *db, FILENUM use_filenum) __attribute__ ((warn_unused_result));
|
||||
|
||||
int toku_brt_remove_subdb(BRT brt, const char *dbname, u_int32_t flags);
|
||||
int toku_brt_remove_subdb(BRT brt, const char *dbname, u_int32_t flags) __attribute__ ((warn_unused_result));
|
||||
|
||||
int toku_brt_broadcast_commit_all (BRT brt);
|
||||
int toku_brt_lookup (BRT brt, DBT *k, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v);
|
||||
int toku_brt_broadcast_commit_all (BRT brt) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_lookup (BRT brt, DBT *k, BRT_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_brt_insert (BRT brt, DBT *k, DBT *v, TOKUTXN txn);
|
||||
int toku_brt_insert (BRT brt, DBT *k, DBT *v, TOKUTXN txn) __attribute__ ((warn_unused_result));
|
||||
|
||||
int toku_brt_optimize (BRT brt);
|
||||
int toku_brt_optimize (BRT brt) __attribute__ ((warn_unused_result));
|
||||
|
||||
// Effect: Insert a key and data pair into a brt if the oplsn is newer than the brt lsn. This function is called during recovery.
|
||||
// Returns 0 if successful
|
||||
int toku_brt_maybe_insert (BRT brt, DBT *k, DBT *v, TOKUTXN txn, BOOL oplsn_valid, LSN oplsn, int do_logging, enum brt_msg_type type);
|
||||
int toku_brt_load_recovery(TOKUTXN txn, char const * old_iname, char const * new_iname, int do_fsync, int do_log, LSN *load_lsn);
|
||||
int toku_brt_load(BRT brt, TOKUTXN txn, char const * new_iname, int do_fsync, LSN *get_lsn);
|
||||
int toku_brt_log_put_multiple (TOKUTXN txn, BRT src_brt, BRT *brts, int num_brts, const DBT *key, const DBT *val);
|
||||
int toku_brt_log_del_multiple (TOKUTXN txn, BRT src_brt, BRT *brts, int num_brts, const DBT *key, const DBT *val);
|
||||
int toku_brt_maybe_insert (BRT brt, DBT *k, DBT *v, TOKUTXN txn, BOOL oplsn_valid, LSN oplsn, int do_logging, enum brt_msg_type type) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_load_recovery(TOKUTXN txn, char const * old_iname, char const * new_iname, int do_fsync, int do_log, LSN *load_lsn) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_load(BRT brt, TOKUTXN txn, char const * new_iname, int do_fsync, LSN *get_lsn) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_log_put_multiple (TOKUTXN txn, BRT src_brt, BRT *brts, int num_brts, const DBT *key, const DBT *val) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_log_del_multiple (TOKUTXN txn, BRT src_brt, BRT *brts, int num_brts, const DBT *key, const DBT *val) __attribute__ ((warn_unused_result));
|
||||
|
||||
// Effect: Delete a key from a brt
|
||||
// Returns 0 if successful
|
||||
int toku_brt_delete (BRT brt, DBT *k, TOKUTXN txn);
|
||||
int toku_brt_delete (BRT brt, DBT *k, TOKUTXN txn) __attribute__ ((warn_unused_result));
|
||||
|
||||
// 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_brt_maybe_delete (BRT brt, DBT *k, TOKUTXN txn, BOOL oplsn_valid, LSN oplsn, int do_logging);
|
||||
int toku_brt_maybe_delete (BRT brt, DBT *k, TOKUTXN txn, BOOL oplsn_valid, LSN oplsn, int do_logging) __attribute__ ((warn_unused_result));
|
||||
|
||||
// Effect: Delete a pair only if both k and v are equal according to the comparison function.
|
||||
// Returns 0 if successful
|
||||
int toku_brt_delete_both (BRT brt, DBT *k, DBT *v, TOKUTXN txn);
|
||||
int toku_brt_delete_both (BRT brt, DBT *k, DBT *v, TOKUTXN txn) __attribute__ ((warn_unused_result));
|
||||
|
||||
// Effect: Delete a pair only if both k and v are equal according to the comparison function and the
|
||||
// oplsn is newer than the brt lsn. This function is called by recovery.
|
||||
// Returns 0 if successful
|
||||
int toku_brt_maybe_delete_both (BRT brt, DBT *k, DBT *v, TOKUTXN txn, BOOL oplsn_valid, LSN oplsn);
|
||||
int toku_brt_maybe_delete_both (BRT brt, DBT *k, DBT *v, TOKUTXN txn, BOOL oplsn_valid, LSN oplsn) __attribute__ ((warn_unused_result));
|
||||
|
||||
int toku_brt_db_delay_closed (BRT brt, DB* db, int (*close_db)(DB*, u_int32_t), u_int32_t close_flags);
|
||||
int toku_close_brt (BRT, char **error_string);
|
||||
int toku_close_brt_lsn (BRT brt, char **error_string, BOOL oplsn_valid, LSN oplsn);
|
||||
int toku_brt_db_delay_closed (BRT brt, DB* db, int (*close_db)(DB*, u_int32_t), u_int32_t close_flags) __attribute__ ((warn_unused_result));
|
||||
int toku_close_brt (BRT, char **error_string) __attribute__ ((warn_unused_result));
|
||||
int toku_close_brt_lsn (BRT brt, char **error_string, BOOL oplsn_valid, LSN oplsn) __attribute__ ((warn_unused_result));
|
||||
|
||||
int toku_brt_set_panic(BRT brt, int panic, char *panic_string);
|
||||
int toku_brt_set_panic(BRT brt, int panic, char *panic_string) __attribute__ ((warn_unused_result));
|
||||
|
||||
int toku_dump_brt (FILE *,BRT brt);
|
||||
int toku_dump_brt (FILE *,BRT brt) __attribute__ ((warn_unused_result));
|
||||
|
||||
void brt_fsync (BRT); /* fsync, but don't clear the caches. */
|
||||
void brt_flush (BRT); /* fsync and clear the caches. */
|
||||
|
||||
int toku_brt_get_cursor_count (BRT brt);
|
||||
int toku_brt_get_cursor_count (BRT brt) __attribute__ ((warn_unused_result));
|
||||
// get the number of cursors in the tree
|
||||
// returns: the number of cursors.
|
||||
// asserts: the number of cursors >= 0.
|
||||
|
||||
int toku_brt_flush (BRT brt);
|
||||
int toku_brt_flush (BRT brt) __attribute__ ((warn_unused_result));
|
||||
// effect: the tree's cachefile is flushed
|
||||
// returns: 0 if success
|
||||
|
||||
int toku_brt_truncate (BRT brt);
|
||||
int toku_brt_truncate (BRT brt) __attribute__ ((warn_unused_result));
|
||||
// effect: remove everything from the tree
|
||||
// returns: 0 if success
|
||||
|
||||
LSN toku_brt_checkpoint_lsn(BRT brt);
|
||||
LSN toku_brt_checkpoint_lsn(BRT brt) __attribute__ ((warn_unused_result));
|
||||
|
||||
// create and initialize a cache table
|
||||
// cachesize 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_brt_create_cachetable(CACHETABLE *t, long cachesize, LSN initial_lsn, TOKULOGGER);
|
||||
int toku_brt_create_cachetable(CACHETABLE *t, long cachesize, LSN initial_lsn, TOKULOGGER) __attribute__ ((warn_unused_result));
|
||||
|
||||
extern int toku_brt_debug_mode;
|
||||
int toku_verify_brt (BRT brt);
|
||||
int toku_verify_brt (BRT brt) __attribute__ ((warn_unused_result));
|
||||
|
||||
//int show_brt_blocknumbers(BRT);
|
||||
|
||||
typedef struct brt_cursor *BRT_CURSOR;
|
||||
int toku_brt_cursor (BRT, BRT_CURSOR*, TOKUTXN, BOOL);
|
||||
int toku_brt_cursor (BRT, BRT_CURSOR*, TOKUTXN, BOOL) __attribute__ ((warn_unused_result));
|
||||
|
||||
// get is deprecated in favor of the individual functions below
|
||||
int toku_brt_cursor_get (BRT_CURSOR cursor, DBT *key, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v, int get_flags);
|
||||
int toku_brt_cursor_get (BRT_CURSOR cursor, DBT *key, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v, int get_flags) __attribute__ ((warn_unused_result));
|
||||
|
||||
int toku_brt_flatten(BRT, TOKUTXN ttxn);
|
||||
int toku_brt_cursor_first(BRT_CURSOR cursor, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v);
|
||||
int toku_brt_cursor_last(BRT_CURSOR cursor, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v);
|
||||
int toku_brt_cursor_next(BRT_CURSOR cursor, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v);
|
||||
int toku_brt_cursor_next_nodup(BRT_CURSOR cursor, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v);
|
||||
int toku_brt_cursor_prev(BRT_CURSOR cursor, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v);
|
||||
int toku_brt_cursor_prev_nodup(BRT_CURSOR cursor, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v);
|
||||
int toku_brt_cursor_current(BRT_CURSOR cursor, int op, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v);
|
||||
int toku_brt_cursor_set(BRT_CURSOR cursor, DBT *key, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v);
|
||||
int toku_brt_cursor_set_range(BRT_CURSOR cursor, DBT *key, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v);
|
||||
int toku_brt_cursor_set_range_reverse(BRT_CURSOR cursor, DBT *key, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v);
|
||||
int toku_brt_cursor_get_both_range(BRT_CURSOR cursor, DBT *key, DBT *val, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v);
|
||||
int toku_brt_cursor_get_both_range_reverse(BRT_CURSOR cursor, DBT *key, DBT *val, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v);
|
||||
int toku_brt_flatten(BRT, TOKUTXN ttxn) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_cursor_first(BRT_CURSOR cursor, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_cursor_last(BRT_CURSOR cursor, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_cursor_next(BRT_CURSOR cursor, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_cursor_next_nodup(BRT_CURSOR cursor, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_cursor_prev(BRT_CURSOR cursor, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_cursor_prev_nodup(BRT_CURSOR cursor, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_cursor_current(BRT_CURSOR cursor, int op, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_cursor_set(BRT_CURSOR cursor, DBT *key, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_cursor_set_range(BRT_CURSOR cursor, DBT *key, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_cursor_set_range_reverse(BRT_CURSOR cursor, DBT *key, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_cursor_get_both_range(BRT_CURSOR cursor, DBT *key, DBT *val, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_cursor_get_both_range_reverse(BRT_CURSOR cursor, DBT *key, DBT *val, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v) __attribute__ ((warn_unused_result));
|
||||
|
||||
|
||||
int toku_brt_cursor_delete(BRT_CURSOR cursor, int flags, TOKUTXN);
|
||||
int toku_brt_cursor_close (BRT_CURSOR curs);
|
||||
BOOL toku_brt_cursor_uninitialized(BRT_CURSOR c);
|
||||
int toku_brt_cursor_delete(BRT_CURSOR cursor, int flags, TOKUTXN) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_cursor_close (BRT_CURSOR curs) __attribute__ ((warn_unused_result));
|
||||
BOOL toku_brt_cursor_uninitialized(BRT_CURSOR c) __attribute__ ((warn_unused_result));
|
||||
|
||||
void toku_brt_cursor_peek(BRT_CURSOR cursor, const DBT **pkey, const DBT **pval);
|
||||
|
||||
typedef struct brtenv *BRTENV;
|
||||
int brtenv_checkpoint (BRTENV env);
|
||||
int brtenv_checkpoint (BRTENV env) __attribute__ ((warn_unused_result));
|
||||
|
||||
extern int toku_brt_do_push_cmd; // control whether push occurs eagerly.
|
||||
|
||||
|
@ -163,7 +166,7 @@ int toku_brt_dbt_set(DBT* key, DBT* key_source);
|
|||
|
||||
DICTIONARY_ID toku_brt_get_dictionary_id(BRT);
|
||||
|
||||
int toku_brt_height_of_root(BRT, int *height); // for an open brt, return the current height.
|
||||
int toku_brt_height_of_root(BRT, int *height) __attribute__ ((warn_unused_result)); // for an open brt, return the current height.
|
||||
|
||||
enum brt_header_flags {
|
||||
//TOKU_DB_DUP = (1<<0), //Obsolete #2862
|
||||
|
@ -172,7 +175,7 @@ enum brt_header_flags {
|
|||
//TOKU_DB_VALCMP_BUILTIN = (1<<3),
|
||||
};
|
||||
|
||||
int toku_brt_keyrange (BRT brt, DBT *key, u_int64_t *less, u_int64_t *equal, u_int64_t *greater);
|
||||
int toku_brt_keyrange (BRT brt, DBT *key, u_int64_t *less, u_int64_t *equal, u_int64_t *greater) __attribute__ ((warn_unused_result));
|
||||
struct brtstat64_s {
|
||||
u_int64_t nkeys; /* estimate how many unique keys (even when flattened this may be an estimate) */
|
||||
u_int64_t ndata; /* estimate the number of pairs (exact when flattened and committed) */
|
||||
|
@ -182,21 +185,23 @@ struct brtstat64_s {
|
|||
};
|
||||
int toku_brt_stat64 (BRT, TOKUTXN,
|
||||
struct brtstat64_s *stat
|
||||
);
|
||||
)
|
||||
__attribute__ ((warn_unused_result));
|
||||
|
||||
int toku_brt_init(void (*ydb_lock_callback)(void),
|
||||
void (*ydb_unlock_callback)(void),
|
||||
void (*db_set_brt)(DB*,BRT));
|
||||
int toku_brt_destroy(void);
|
||||
int toku_pwrite_lock_init(void);
|
||||
int toku_pwrite_lock_destroy(void);
|
||||
int toku_brt_serialize_init(void);
|
||||
int toku_brt_serialize_destroy(void);
|
||||
void (*db_set_brt)(DB*,BRT))
|
||||
__attribute__ ((warn_unused_result));
|
||||
int toku_brt_destroy(void) __attribute__ ((warn_unused_result));
|
||||
int toku_pwrite_lock_init(void) __attribute__ ((warn_unused_result));
|
||||
int toku_pwrite_lock_destroy(void) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_serialize_init(void) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_serialize_destroy(void) __attribute__ ((warn_unused_result));
|
||||
|
||||
void toku_maybe_truncate_cachefile (CACHEFILE cf, int fd, u_int64_t size_used);
|
||||
// Effect: truncate file if overallocated by at least 32MiB
|
||||
|
||||
int maybe_preallocate_in_file (int fd, u_int64_t size);
|
||||
int maybe_preallocate_in_file (int fd, u_int64_t size) __attribute__ ((warn_unused_result));
|
||||
// Effect: If file size is less than SIZE, make it bigger by either doubling it or growing by 16MB whichever is less.
|
||||
|
||||
void toku_brt_header_suppress_rollbacks(struct brt_header *h, TOKUTXN txn);
|
||||
|
@ -208,22 +213,22 @@ void toku_brt_suppress_recovery_logs (BRT brt, TOKUTXN txn);
|
|||
// implies: txnid_that_created_or_locked_when_empty matches txn
|
||||
// implies: toku_txn_note_brt(brt, txn) has been called
|
||||
|
||||
int toku_brt_zombie_needed (BRT brt);
|
||||
int toku_brt_zombie_needed (BRT brt) __attribute__ ((warn_unused_result));
|
||||
|
||||
int toku_brt_get_fragmentation(BRT brt, TOKU_DB_FRAGMENTATION report);
|
||||
int toku_brt_header_set_panic(struct brt_header *h, int panic, char *panic_string);
|
||||
int toku_brt_get_fragmentation(BRT brt, TOKU_DB_FRAGMENTATION report) __attribute__ ((warn_unused_result));
|
||||
int toku_brt_header_set_panic(struct brt_header *h, int panic, char *panic_string) __attribute__ ((warn_unused_result));
|
||||
|
||||
BOOL toku_brt_is_empty (BRT brt, BOOL *try_again);
|
||||
BOOL toku_brt_is_empty (BRT brt, BOOL *try_again) __attribute__ ((warn_unused_result));
|
||||
// Effect: Return TRUE iff the tree is empty. (However if *try_again is set to TRUE by toku_brt_is_empty, then the answer is inconclusive, and the function should
|
||||
// be tried again. It's a good idea to release the big ydb lock in this case.
|
||||
|
||||
BOOL toku_brt_is_empty_fast (BRT brt);
|
||||
BOOL toku_brt_is_empty_fast (BRT brt) __attribute__ ((warn_unused_result));
|
||||
// Effect: Return TRUE if there are no messages or leaf entries in the tree. If so, it's empty. If there are messages or leaf entries, we say it's not empty
|
||||
// even though if we were to optimize the tree it might turn out that they are empty.
|
||||
|
||||
double get_tdiff(void) __attribute__((__visibility__("default")));
|
||||
double get_tdiff(void) __attribute__((__visibility__("default"))) __attribute__ ((warn_unused_result));
|
||||
|
||||
BOOL toku_brt_is_recovery_logging_suppressed (BRT);
|
||||
BOOL toku_brt_is_recovery_logging_suppressed (BRT) __attribute__ ((warn_unused_result));
|
||||
//TODO: #1485 once we have multiple main threads, restore this code, analyze performance.
|
||||
#ifndef TOKU_MULTIPLE_MAIN_THREADS
|
||||
#define TOKU_MULTIPLE_MAIN_THREADS 0
|
||||
|
|
|
@ -201,7 +201,8 @@ toku_logger_close_rollback(TOKULOGGER logger, BOOL recovery_failed) {
|
|||
struct brt_header *h = toku_cachefile_get_userdata(cf);
|
||||
toku_brtheader_lock(h);
|
||||
if (!h->panic && recovery_failed) {
|
||||
toku_brt_header_set_panic(h, EINVAL, "Recovery failed");
|
||||
r = toku_brt_header_set_panic(h, EINVAL, "Recovery failed");
|
||||
assert(r==0);
|
||||
}
|
||||
//Verify it is safe to close it.
|
||||
if (!h->panic) { //If paniced, it is safe to close.
|
||||
|
|
|
@ -107,7 +107,8 @@ static void file_map_close_dictionaries(struct file_map *fmap, BOOL recovery_suc
|
|||
assert(tuple->brt);
|
||||
if (!recovery_succeeded) {
|
||||
// don't update the brt on close
|
||||
toku_brt_set_panic(tuple->brt, DB_RUNRECOVERY, "recovery failed");
|
||||
r = toku_brt_set_panic(tuple->brt, DB_RUNRECOVERY, "recovery failed");
|
||||
assert(r==0);
|
||||
}
|
||||
//Logging is already back on. No need to pass LSN into close.
|
||||
char *error_string = NULL;
|
||||
|
@ -245,11 +246,14 @@ static int internal_recover_fopen_or_fcreate (RECOVER_ENV renv, BOOL must_create
|
|||
r = toku_brt_create(&brt);
|
||||
assert(r == 0);
|
||||
|
||||
toku_brt_set_flags(brt, treeflags);
|
||||
r = toku_brt_set_flags(brt, treeflags);
|
||||
assert(r==0);
|
||||
|
||||
// set the key compare functions
|
||||
if (!(treeflags & TOKU_DB_KEYCMP_BUILTIN) && renv->bt_compare)
|
||||
toku_brt_set_bt_compare(brt, renv->bt_compare);
|
||||
if (!(treeflags & TOKU_DB_KEYCMP_BUILTIN) && renv->bt_compare) {
|
||||
r = toku_brt_set_bt_compare(brt, renv->bt_compare);
|
||||
assert(r==0);
|
||||
}
|
||||
|
||||
// TODO mode (FUTURE FEATURE)
|
||||
mode = mode;
|
||||
|
|
|
@ -18,9 +18,15 @@ static void dummy_set_brt(DB *db UU(), BRT brt UU()) {}
|
|||
|
||||
int
|
||||
main(int argc, const char *const argv[]) {
|
||||
toku_brt_init(dummy, dummy, dummy_set_brt);
|
||||
{
|
||||
int rr = toku_brt_init(dummy, dummy, dummy_set_brt);
|
||||
assert(rr==0);
|
||||
}
|
||||
int r = recovery_main(argc, argv);
|
||||
toku_brt_destroy();
|
||||
{
|
||||
int rr = toku_brt_destroy();
|
||||
assert(rr=0);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ static void test_dump_empty_db (void) {
|
|||
unlink(fname);
|
||||
r = toku_open_brt(fname, 1, &t, 1024, ct, null_txn, toku_builtin_compare_fun, null_db);
|
||||
assert(r==0);
|
||||
if (verbose) toku_dump_brt(stdout, t);
|
||||
if (verbose) { r=toku_dump_brt(stdout, t); assert(r==0); }
|
||||
r = toku_close_brt(t, 0); assert(r==0);
|
||||
r = toku_cachetable_close(&ct); assert(r==0);
|
||||
|
||||
|
@ -44,15 +44,15 @@ static void test_multiple_files_of_size (int size) {
|
|||
DBT k,v;
|
||||
snprintf(key, 100, "key%d", i);
|
||||
snprintf(val, 100, "val%d", i);
|
||||
toku_brt_insert(t0, toku_fill_dbt(&k, key, 1+strlen(key)), toku_fill_dbt(&v, val, 1+strlen(val)), null_txn);
|
||||
r = toku_brt_insert(t0, toku_fill_dbt(&k, key, 1+strlen(key)), toku_fill_dbt(&v, val, 1+strlen(val)), null_txn); assert(r==0);
|
||||
snprintf(val, 100, "Val%d", i);
|
||||
toku_brt_insert(t1, toku_fill_dbt(&k, key, 1+strlen(key)), toku_fill_dbt(&v, val, 1+strlen(val)), null_txn);
|
||||
r = toku_brt_insert(t1, toku_fill_dbt(&k, key, 1+strlen(key)), toku_fill_dbt(&v, val, 1+strlen(val)), null_txn); assert(r==0);
|
||||
}
|
||||
//toku_verify_brt(t0);
|
||||
//dump_brt(t0);
|
||||
//dump_brt(t1);
|
||||
toku_verify_brt(t0);
|
||||
toku_verify_brt(t1);
|
||||
r = toku_verify_brt(t0); assert(r==0);
|
||||
r = toku_verify_brt(t1); assert(r==0);
|
||||
|
||||
r = toku_close_brt(t0, 0); assert(r==0);
|
||||
r = toku_close_brt(t1, 0); assert(r==0);
|
||||
|
@ -105,7 +105,8 @@ static void test_multiple_brts_one_db_one_file (void) {
|
|||
DBT kb, vb;
|
||||
snprintf(k, 20, "key%d", i);
|
||||
snprintf(v, 20, "val%d", i);
|
||||
toku_brt_insert(trees[i], toku_fill_dbt(&kb, k, strlen(k)+1), toku_fill_dbt(&vb, v, strlen(v)+1), null_txn);
|
||||
r = toku_brt_insert(trees[i], toku_fill_dbt(&kb, k, strlen(k)+1), toku_fill_dbt(&vb, v, strlen(v)+1), null_txn);
|
||||
assert(r==0);
|
||||
}
|
||||
for (i=0; i<MANYN; i++) {
|
||||
char k[20],vexpect[20];
|
||||
|
@ -148,7 +149,8 @@ static void test_read_what_was_written (void) {
|
|||
/* See if we can put something in it. */
|
||||
{
|
||||
DBT k,v;
|
||||
toku_brt_insert(brt, toku_fill_dbt(&k, "hello", 6), toku_fill_dbt(&v, "there", 6), null_txn);
|
||||
r = toku_brt_insert(brt, toku_fill_dbt(&k, "hello", 6), toku_fill_dbt(&v, "there", 6), null_txn);
|
||||
assert(r==0);
|
||||
}
|
||||
|
||||
r = toku_close_brt(brt, 0); assert(r==0);
|
||||
|
@ -176,11 +178,13 @@ static void test_read_what_was_written (void) {
|
|||
int verify_result=toku_verify_brt(brt);;
|
||||
assert(verify_result==0);
|
||||
}
|
||||
toku_brt_insert(brt, toku_fill_dbt(&k, key, strlen(key)+1), toku_fill_dbt(&v, val, strlen(val)+1), null_txn);
|
||||
r = toku_brt_insert(brt, toku_fill_dbt(&k, key, strlen(key)+1), toku_fill_dbt(&v, val, strlen(val)+1), null_txn);
|
||||
assert(r==0);
|
||||
if (i<600) {
|
||||
int verify_result=toku_verify_brt(brt);
|
||||
if (verify_result) {
|
||||
toku_dump_brt(stdout, brt);
|
||||
r = toku_dump_brt(stdout, brt);
|
||||
assert(r==0);
|
||||
assert(0);
|
||||
}
|
||||
{
|
||||
|
@ -198,7 +202,8 @@ static void test_read_what_was_written (void) {
|
|||
if (verbose) printf("Now read them out\n");
|
||||
|
||||
//show_brt_blocknumbers(brt);
|
||||
toku_verify_brt(brt);
|
||||
r = toku_verify_brt(brt);
|
||||
assert(r==0);
|
||||
//dump_brt(brt);
|
||||
|
||||
/* See if we can read them all out again. */
|
||||
|
|
|
@ -20,7 +20,8 @@ static void test1 (void) {
|
|||
unlink(fname);
|
||||
r = toku_open_brt(fname, 1, &t, 1024, ct, null_txn, toku_builtin_compare_fun, null_db);
|
||||
assert(r==0);
|
||||
toku_brt_insert(t, toku_fill_dbt(&k, "hello", 6), toku_fill_dbt(&v, "there", 6), null_txn);
|
||||
r = toku_brt_insert(t, toku_fill_dbt(&k, "hello", 6), toku_fill_dbt(&v, "there", 6), null_txn);
|
||||
assert(r==0);
|
||||
{
|
||||
struct check_pair pair = {6, "hello", 6, "there", 0};
|
||||
r = toku_brt_lookup(t, toku_fill_dbt(&k, "hello", 6), lookup_checkf, &pair);
|
||||
|
|
|
@ -26,11 +26,13 @@ static void test2 (int memcheck, int limit) {
|
|||
char key[100],val[100];
|
||||
snprintf(key,100,"hello%d",i);
|
||||
snprintf(val,100,"there%d",i);
|
||||
toku_brt_insert(t, toku_fill_dbt(&k, key, 1+strlen(key)), toku_fill_dbt(&v, val, 1+strlen(val)), null_txn);
|
||||
r = toku_brt_insert(t, toku_fill_dbt(&k, key, 1+strlen(key)), toku_fill_dbt(&v, val, 1+strlen(val)), null_txn);
|
||||
assert(r==0);
|
||||
r = toku_verify_brt(t); assert(r==0);
|
||||
//printf("%s:%d did insert %d\n", __FILE__, __LINE__, i);
|
||||
if (0) {
|
||||
toku_brt_flush(t);
|
||||
r = toku_brt_flush(t);
|
||||
assert(r==0);
|
||||
{
|
||||
int n = toku_get_n_items_malloced();
|
||||
if (verbose) printf("%s:%d i=%d n_items_malloced=%d\n", __FILE__, __LINE__, i, n);
|
||||
|
|
|
@ -28,7 +28,8 @@ static void test3 (int nodesize, int count, int memcheck) {
|
|||
DBT k,v;
|
||||
snprintf(key,100,"hello%d",i);
|
||||
snprintf(val,100,"there%d",i);
|
||||
toku_brt_insert(t, toku_fill_dbt(&k, key, 1+strlen(key)), toku_fill_dbt(&v, val, 1+strlen(val)), null_txn);
|
||||
r = toku_brt_insert(t, toku_fill_dbt(&k, key, 1+strlen(key)), toku_fill_dbt(&v, val, 1+strlen(val)), null_txn);
|
||||
assert(r==0);
|
||||
}
|
||||
r = toku_verify_brt(t); assert(r==0);
|
||||
r = toku_close_brt(t, 0); assert(r==0);
|
||||
|
|
|
@ -28,7 +28,8 @@ static void test4 (int nodesize, int count, int memcheck) {
|
|||
DBT k,v;
|
||||
snprintf(key,100,"hello%d",rv);
|
||||
snprintf(val,100,"there%d",i);
|
||||
toku_brt_insert(t, toku_fill_dbt(&k, key, 1+strlen(key)), toku_fill_dbt(&v, val, 1+strlen(val)), null_txn);
|
||||
r = toku_brt_insert(t, toku_fill_dbt(&k, key, 1+strlen(key)), toku_fill_dbt(&v, val, 1+strlen(val)), null_txn);
|
||||
assert(r==0);
|
||||
}
|
||||
r = toku_verify_brt(t); assert(r==0);
|
||||
r = toku_close_brt(t, 0); assert(r==0);
|
||||
|
|
|
@ -30,7 +30,8 @@ static void test5 (void) {
|
|||
snprintf(key, 100, "key%d", rk);
|
||||
snprintf(val, 100, "val%d", rv);
|
||||
DBT k,v;
|
||||
toku_brt_insert(t, toku_fill_dbt(&k, key, 1+strlen(key)), toku_fill_dbt(&v, val, 1+strlen(val)), null_txn);
|
||||
r = toku_brt_insert(t, toku_fill_dbt(&k, key, 1+strlen(key)), toku_fill_dbt(&v, val, 1+strlen(val)), null_txn);
|
||||
assert(r==0);
|
||||
}
|
||||
if (verbose) printf("\n");
|
||||
for (i=0; i<limit/2; i++) {
|
||||
|
|
|
@ -51,7 +51,8 @@ static void verify_dbfile(int n, const char *name) {
|
|||
TOKUTXN const null_txn = NULL;
|
||||
BRT t = NULL;
|
||||
r = toku_brt_create(&t); assert(r == 0);
|
||||
r = toku_brt_set_bt_compare(t, compare_ints); assert(r == 0);
|
||||
r = toku_brt_set_bt_compare(t, compare_ints);
|
||||
assert(r==0);
|
||||
r = toku_brt_open(t, name, 0, 0, ct, null_txn, 0); assert(r==0);
|
||||
|
||||
BRT_CURSOR cursor = NULL;
|
||||
|
|
|
@ -250,7 +250,7 @@ static void verify_dbfile(int n, int sorted_keys[], const char *sorted_vals[], c
|
|||
TOKUTXN const null_txn = NULL;
|
||||
BRT t = NULL;
|
||||
r = toku_brt_create(&t); assert(r == 0);
|
||||
r = toku_brt_set_bt_compare(t, compare_ints); assert(r == 0);
|
||||
r = toku_brt_set_bt_compare(t, compare_ints); assert(r==0);
|
||||
r = toku_brt_open(t, name, 0, 0, ct, null_txn, 0); assert(r==0);
|
||||
|
||||
BRT_CURSOR cursor = NULL;
|
||||
|
|
|
@ -28,7 +28,8 @@ test_overflow (void) {
|
|||
int i;
|
||||
for (i=0; i<8; i++) {
|
||||
char key[]={(char)('a'+i), 0};
|
||||
toku_brt_insert(t, toku_fill_dbt(&k, key, 2), toku_fill_dbt(&v,buf,sizeof(buf)), null_txn);
|
||||
r = toku_brt_insert(t, toku_fill_dbt(&k, key, 2), toku_fill_dbt(&v,buf,sizeof(buf)), null_txn);
|
||||
assert(r=0);
|
||||
}
|
||||
r = toku_close_brt(t, 0); assert(r==0);
|
||||
r = toku_cachetable_close(&ct); assert(r==0);
|
||||
|
|
|
@ -24,7 +24,8 @@ test_main(int argc, const char *argv[]) {
|
|||
DBT k,v;
|
||||
snprintf(key, 100, "key%d", i);
|
||||
snprintf(val, 100, "val%d", i);
|
||||
toku_brt_insert(t, toku_fill_dbt(&k, key, 1+strlen(key)), toku_fill_dbt(&v, val, 1+strlen(val)), null_txn);
|
||||
r = toku_brt_insert(t, toku_fill_dbt(&k, key, 1+strlen(key)), toku_fill_dbt(&v, val, 1+strlen(val)), null_txn);
|
||||
assert(r==0);
|
||||
}
|
||||
r = toku_dump_brt(f, t); assert(r==0);
|
||||
r = toku_close_brt(t, 0); assert(r==0);
|
||||
|
|
|
@ -35,7 +35,10 @@ test_main (int argc __attribute__((__unused__)), const char *argv[] __attribute_
|
|||
int r = toku_os_get_file_size(fd, &file_size);
|
||||
assert(r==0);
|
||||
}
|
||||
maybe_preallocate_in_file(fd, 1000);
|
||||
{
|
||||
int r = maybe_preallocate_in_file(fd, 1000);
|
||||
assert(r==0);
|
||||
}
|
||||
int64_t file_size2;
|
||||
{
|
||||
int r = toku_os_get_file_size(fd, &file_size2);
|
||||
|
|
Loading…
Add table
Reference in a new issue