/****************************************************** Mini-transaction buffer (c) 1995 Innobase Oy Created 11/26/1995 Heikki Tuuri *******************************************************/ #include "sync0sync.h" #include "sync0rw.h" #include "mach0data.h" /******************************************************************* Starts a mini-transaction and creates a mini-transaction handle and a buffer in the memory buffer given by the caller. */ UNIV_INLINE mtr_t* mtr_start( /*======*/ /* out: mtr buffer which also acts as the mtr handle */ mtr_t* mtr) /* in: memory buffer for the mtr buffer */ { dyn_array_create(&(mtr->memo)); dyn_array_create(&(mtr->log)); mtr->log_mode = MTR_LOG_ALL; mtr->modifications = FALSE; mtr->n_log_recs = 0; #ifdef UNIV_DEBUG mtr->state = MTR_ACTIVE; mtr->magic_n = MTR_MAGIC_N; #endif return(mtr); } /******************************************************* Pushes an object to an mtr memo stack. */ UNIV_INLINE void mtr_memo_push( /*==========*/ mtr_t* mtr, /* in: mtr */ void* object, /* in: object */ ulint type) /* in: object type: MTR_MEMO_S_LOCK, ... */ { dyn_array_t* memo; mtr_memo_slot_t* slot; ut_ad(object); ut_ad(type >= MTR_MEMO_PAGE_S_FIX); ut_ad(type <= MTR_MEMO_X_LOCK); ut_ad(mtr); ut_ad(mtr->magic_n == MTR_MAGIC_N); memo = &(mtr->memo); slot = dyn_array_push(memo, sizeof(mtr_memo_slot_t)); slot->object = object; slot->type = type; } /************************************************************** Sets and returns a savepoint in mtr. */ UNIV_INLINE ulint mtr_set_savepoint( /*==============*/ /* out: savepoint */ mtr_t* mtr) /* in: mtr */ { dyn_array_t* memo; ut_ad(mtr); ut_ad(mtr->magic_n == MTR_MAGIC_N); memo = &(mtr->memo); return(dyn_array_get_data_size(memo)); } /************************************************************** Releases the (index tree) s-latch stored in an mtr memo after a savepoint. */ UNIV_INLINE void mtr_release_s_latch_at_savepoint( /*=============================*/ mtr_t* mtr, /* in: mtr */ ulint savepoint, /* in: savepoint */ rw_lock_t* lock) /* in: latch to release */ { mtr_memo_slot_t* slot; dyn_array_t* memo; ut_ad(mtr); ut_ad(mtr->magic_n == MTR_MAGIC_N); ut_ad(mtr->state == MTR_ACTIVE); memo = &(mtr->memo); ut_ad(dyn_array_get_data_size(memo) > savepoint); slot = dyn_array_get_element(memo, savepoint); ut_ad(slot->object == lock); ut_ad(slot->type == MTR_MEMO_S_LOCK); rw_lock_s_unlock(lock); slot->object = NULL; } /************************************************************** Checks if memo contains the given item. */ UNIV_INLINE ibool mtr_memo_contains( /*==============*/ /* out: TRUE if contains */ mtr_t* mtr, /* in: mtr */ void* object, /* in: object to search */ ulint type) /* in: type of object */ { mtr_memo_slot_t* slot; dyn_array_t* memo; ulint offset; ut_ad(mtr); ut_ad(mtr->magic_n == MTR_MAGIC_N); memo = &(mtr->memo); offset = dyn_array_get_data_size(memo); while (offset > 0) { offset -= sizeof(mtr_memo_slot_t); slot = dyn_array_get_element(memo, offset); if ((object == slot->object) && (type == slot->type)) { return(TRUE); } } return(FALSE); } /******************************************************************* Returns the log object of a mini-transaction buffer. */ UNIV_INLINE dyn_array_t* mtr_get_log( /*========*/ /* out: log */ mtr_t* mtr) /* in: mini-transaction */ { ut_ad(mtr); ut_ad(mtr->magic_n == MTR_MAGIC_N); return(&(mtr->log)); } /******************************************************************* Gets the logging mode of a mini-transaction. */ UNIV_INLINE ulint mtr_get_log_mode( /*=============*/ /* out: logging mode: MTR_LOG_NONE, ... */ mtr_t* mtr) /* in: mtr */ { ut_ad(mtr); ut_ad(mtr->log_mode >= MTR_LOG_ALL); ut_ad(mtr->log_mode <= MTR_LOG_SHORT_INSERTS); return(mtr->log_mode); } /******************************************************************* Changes the logging mode of a mini-transaction. */ UNIV_INLINE ulint mtr_set_log_mode( /*=============*/ /* out: old mode */ mtr_t* mtr, /* in: mtr */ ulint mode) /* in: logging mode: MTR_LOG_NONE, ... */ { ulint old_mode; ut_ad(mtr); ut_ad(mode >= MTR_LOG_ALL); ut_ad(mode <= MTR_LOG_SHORT_INSERTS); old_mode = mtr->log_mode; if ((mode == MTR_LOG_SHORT_INSERTS) && (old_mode == MTR_LOG_NONE)) { /* Do nothing */ } else { mtr->log_mode = mode; } ut_ad(old_mode >= MTR_LOG_ALL); ut_ad(old_mode <= MTR_LOG_SHORT_INSERTS); return(old_mode); } /************************************************************************* Locks a lock in s-mode. */ UNIV_INLINE void mtr_s_lock_func( /*============*/ rw_lock_t* lock, /* in: rw-lock */ const char* file, /* in: file name */ ulint line, /* in: line number */ mtr_t* mtr) /* in: mtr */ { ut_ad(mtr); ut_ad(lock); rw_lock_s_lock_func(lock, 0, file, line); mtr_memo_push(mtr, lock, MTR_MEMO_S_LOCK); } /************************************************************************* Locks a lock in x-mode. */ UNIV_INLINE void mtr_x_lock_func( /*============*/ rw_lock_t* lock, /* in: rw-lock */ const char* file, /* in: file name */ ulint line, /* in: line number */ mtr_t* mtr) /* in: mtr */ { ut_ad(mtr); ut_ad(lock); rw_lock_x_lock_func(lock, 0, file, line); mtr_memo_push(mtr, lock, MTR_MEMO_X_LOCK); }