mirror of
https://github.com/MariaDB/server.git
synced 2025-01-20 14:02:32 +01:00
branches/zip: Simplify lock_mode_stronger_or_eq() and lock_mode_compatible()
and introduce enum lock_mode. lock_mode_stronger_or_eq(), lock_mode_compatible(): Replace if-then-else chain with a bitwise and against a constant.
This commit is contained in:
parent
f05b0766d9
commit
35f83441a0
3 changed files with 78 additions and 88 deletions
|
@ -3275,7 +3275,7 @@ ha_innobase::write_row(
|
|||
being blocked by a MySQL table lock TL_WRITE_ALLOW_READ. */
|
||||
|
||||
dict_table_t* src_table;
|
||||
ulint mode;
|
||||
enum lock_mode mode;
|
||||
|
||||
num_write_row = 0;
|
||||
|
||||
|
|
|
@ -25,6 +25,18 @@ extern ibool lock_print_waits;
|
|||
/* Buffer for storing information about the most recent deadlock error */
|
||||
extern FILE* lock_latest_err_file;
|
||||
|
||||
/* Basic lock modes */
|
||||
enum lock_mode {
|
||||
LOCK_IS = 0, /* intention shared */
|
||||
LOCK_IX, /* intention exclusive */
|
||||
LOCK_S, /* shared */
|
||||
LOCK_X, /* exclusive */
|
||||
LOCK_AUTO_INC, /* locks the auto-inc counter of a table
|
||||
in an exclusive mode */
|
||||
LOCK_NONE, /* this is used elsewhere to note consistent read */
|
||||
LOCK_NUM = LOCK_NONE/* number of lock modes */
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
Gets the size of a lock struct. */
|
||||
|
||||
|
@ -354,7 +366,7 @@ lock_sec_rec_read_check_and_lock(
|
|||
read cursor */
|
||||
dict_index_t* index, /* in: secondary index */
|
||||
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
|
||||
ulint mode, /* in: mode of the lock which
|
||||
enum lock_mode mode, /* in: mode of the lock which
|
||||
the read cursor should set on
|
||||
records: LOCK_S or LOCK_X; the
|
||||
latter is possible in
|
||||
|
@ -385,7 +397,7 @@ lock_clust_rec_read_check_and_lock(
|
|||
read cursor */
|
||||
dict_index_t* index, /* in: clustered index */
|
||||
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
|
||||
ulint mode, /* in: mode of the lock which
|
||||
enum lock_mode mode, /* in: mode of the lock which
|
||||
the read cursor should set on
|
||||
records: LOCK_S or LOCK_X; the
|
||||
latter is possible in
|
||||
|
@ -417,7 +429,7 @@ lock_clust_rec_read_check_and_lock_alt(
|
|||
be read or passed over by a
|
||||
read cursor */
|
||||
dict_index_t* index, /* in: clustered index */
|
||||
ulint mode, /* in: mode of the lock which
|
||||
enum lock_mode mode, /* in: mode of the lock which
|
||||
the read cursor should set on
|
||||
records: LOCK_S or LOCK_X; the
|
||||
latter is possible in
|
||||
|
@ -473,7 +485,7 @@ lock_table(
|
|||
ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
|
||||
does nothing */
|
||||
dict_table_t* table, /* in: database table in dictionary cache */
|
||||
ulint mode, /* in: lock mode */
|
||||
enum lock_mode mode, /* in: lock mode */
|
||||
que_thr_t* thr); /* in: query thread */
|
||||
/*************************************************************************
|
||||
Checks if there are any locks set on the table. */
|
||||
|
@ -495,7 +507,7 @@ lock_rec_unlock(
|
|||
set a record lock */
|
||||
const buf_block_t* block, /* in: buffer block containing rec */
|
||||
const rec_t* rec, /* in: record */
|
||||
ulint lock_mode);/* in: LOCK_S or LOCK_X */
|
||||
enum lock_mode lock_mode);/* in: LOCK_S or LOCK_X */
|
||||
/*************************************************************************
|
||||
Releases a table lock.
|
||||
Releases possible other transactions waiting for this lock. */
|
||||
|
@ -571,7 +583,7 @@ lock_get_src_table(
|
|||
two tables or an inconsistency is found */
|
||||
trx_t* trx, /* in: transaction */
|
||||
dict_table_t* dest, /* in: destination of ALTER TABLE */
|
||||
ulint* mode); /* out: lock mode of the source table */
|
||||
enum lock_mode* mode); /* out: lock mode of the source table */
|
||||
/*************************************************************************
|
||||
Determine if the given table is exclusively "owned" by the given
|
||||
transaction, i.e., transaction holds LOCK_IX and possibly LOCK_AUTO_INC
|
||||
|
@ -641,15 +653,6 @@ lock_number_of_rows_locked(
|
|||
extern lock_sys_t* lock_sys;
|
||||
|
||||
/* Lock modes and types */
|
||||
/* Basic modes */
|
||||
#define LOCK_NONE 0 /* this flag is used elsewhere to note
|
||||
consistent read */
|
||||
#define LOCK_IS 2 /* intention shared */
|
||||
#define LOCK_IX 3 /* intention exclusive */
|
||||
#define LOCK_S 4 /* shared */
|
||||
#define LOCK_X 5 /* exclusive */
|
||||
#define LOCK_AUTO_INC 6 /* locks the auto-inc counter of a table
|
||||
in an exclusive mode */
|
||||
#define LOCK_MODE_MASK 0xFUL /* mask used to extract mode from the
|
||||
type_mode field in a lock */
|
||||
/* Lock types */
|
||||
|
@ -700,7 +703,7 @@ extern lock_sys_t* lock_sys;
|
|||
typedef struct lock_op_struct lock_op_t;
|
||||
struct lock_op_struct{
|
||||
dict_table_t* table; /* table to be locked */
|
||||
ulint mode; /* lock mode */
|
||||
enum lock_mode mode; /* lock mode */
|
||||
};
|
||||
|
||||
#define LOCK_OP_START 1
|
||||
|
|
129
lock/lock0lock.c
129
lock/lock0lock.c
|
@ -311,6 +311,39 @@ locks on the inserted record. */
|
|||
* statement-level MySQL binlog.
|
||||
* See also lock_mode_compatible().
|
||||
*/
|
||||
#define LK(a,b) (1 << ((a) * LOCK_NUM + (b)))
|
||||
#define LKS(a,b) LK(a,b) | LK(b,a)
|
||||
|
||||
/* Define the lock compatibility matrix in a ulint. The first line below
|
||||
defines the diagonal entries. The following lines define the compatibility
|
||||
for LOCK_IX, LOCK_S, and LOCK_AUTO_INC using LKS(), since the matrix
|
||||
is symmetric. */
|
||||
#define LOCK_MODE_COMPATIBILITY 0 \
|
||||
| LK(LOCK_IS, LOCK_IS) | LK(LOCK_IX, LOCK_IX) | LK(LOCK_S, LOCK_S) \
|
||||
| LKS(LOCK_IX, LOCK_IS) | LKS(LOCK_IS, LOCK_AUTO_INC) \
|
||||
| LKS(LOCK_S, LOCK_IS) \
|
||||
| LKS(LOCK_AUTO_INC, LOCK_IS) | LKS(LOCK_AUTO_INC, LOCK_IX)
|
||||
|
||||
/* STRONGER-OR-EQUAL RELATION (mode1=row, mode2=column)
|
||||
* IS IX S X AI
|
||||
* IS + - - - -
|
||||
* IX + + - - -
|
||||
* S + - + - -
|
||||
* X + + + + +
|
||||
* AI - - - - +
|
||||
* See lock_mode_stronger_or_eq().
|
||||
*/
|
||||
|
||||
/* Define the stronger-or-equal lock relation in a ulint. This relation
|
||||
contains all pairs LK(mode1, mode2) where mode1 is stronger than or
|
||||
equal to mode2. */
|
||||
#define LOCK_MODE_STRONGER_OR_EQ 0 \
|
||||
| LK(LOCK_IS, LOCK_IS) \
|
||||
| LK(LOCK_IX, LOCK_IS) | LK(LOCK_IX, LOCK_IX) \
|
||||
| LK(LOCK_S, LOCK_IS) | LK(LOCK_S, LOCK_S) \
|
||||
| LK(LOCK_AUTO_INC, LOCK_AUTO_INC) \
|
||||
| LK(LOCK_X, LOCK_IS) | LK(LOCK_X, LOCK_IX) | LK(LOCK_X, LOCK_S) \
|
||||
| LK(LOCK_X, LOCK_AUTO_INC) | LK(LOCK_X, LOCK_X)
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
ibool lock_print_waits = FALSE;
|
||||
|
@ -623,7 +656,7 @@ lock_get_size(void)
|
|||
/*************************************************************************
|
||||
Gets the mode of a lock. */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
enum lock_mode
|
||||
lock_get_mode(
|
||||
/*==========*/
|
||||
/* out: mode */
|
||||
|
@ -667,7 +700,7 @@ lock_get_src_table(
|
|||
two tables or an inconsistency is found */
|
||||
trx_t* trx, /* in: transaction */
|
||||
dict_table_t* dest, /* in: destination of ALTER TABLE */
|
||||
ulint* mode) /* out: lock mode of the source table */
|
||||
enum lock_mode* mode) /* out: lock mode of the source table */
|
||||
{
|
||||
dict_table_t* src;
|
||||
lock_t* lock;
|
||||
|
@ -679,7 +712,7 @@ lock_get_src_table(
|
|||
lock;
|
||||
lock = UT_LIST_GET_NEXT(trx_locks, lock)) {
|
||||
lock_table_t* tab_lock;
|
||||
ulint lock_mode;
|
||||
enum lock_mode lock_mode;
|
||||
if (!(lock_get_type(lock) & LOCK_TABLE)) {
|
||||
/* We are only interested in table locks. */
|
||||
continue;
|
||||
|
@ -706,15 +739,12 @@ lock_get_src_table(
|
|||
/* Check that the source table is locked by
|
||||
LOCK_IX or LOCK_IS. */
|
||||
lock_mode = lock_get_mode(lock);
|
||||
switch (lock_mode) {
|
||||
case LOCK_IX:
|
||||
case LOCK_IS:
|
||||
if (lock_mode == LOCK_IX || lock_mode == LOCK_IS) {
|
||||
if (*mode != LOCK_NONE && *mode != lock_mode) {
|
||||
/* There are multiple locks on src. */
|
||||
return(NULL);
|
||||
}
|
||||
*mode = lock_mode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -872,81 +902,38 @@ lock_rec_get_insert_intention(
|
|||
/*************************************************************************
|
||||
Calculates if lock mode 1 is stronger or equal to lock mode 2. */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
ulint
|
||||
lock_mode_stronger_or_eq(
|
||||
/*=====================*/
|
||||
/* out: TRUE if mode1 stronger or equal to mode2 */
|
||||
ulint mode1, /* in: lock mode */
|
||||
ulint mode2) /* in: lock mode */
|
||||
/* out: nonzero
|
||||
if mode1 stronger or equal to mode2 */
|
||||
enum lock_mode mode1, /* in: lock mode */
|
||||
enum lock_mode mode2) /* in: lock mode */
|
||||
{
|
||||
ut_ad(mode1 == LOCK_X || mode1 == LOCK_S || mode1 == LOCK_IX
|
||||
|| mode1 == LOCK_IS || mode1 == LOCK_AUTO_INC);
|
||||
ut_ad(mode2 == LOCK_X || mode2 == LOCK_S || mode2 == LOCK_IX
|
||||
|| mode2 == LOCK_IS || mode2 == LOCK_AUTO_INC);
|
||||
if (mode1 == LOCK_X) {
|
||||
|
||||
return(TRUE);
|
||||
|
||||
} else if (mode1 == LOCK_AUTO_INC && mode2 == LOCK_AUTO_INC) {
|
||||
|
||||
return(TRUE);
|
||||
|
||||
} else if (mode1 == LOCK_S
|
||||
&& (mode2 == LOCK_S || mode2 == LOCK_IS)) {
|
||||
return(TRUE);
|
||||
|
||||
} else if (mode1 == LOCK_IS && mode2 == LOCK_IS) {
|
||||
|
||||
return(TRUE);
|
||||
|
||||
} else if (mode1 == LOCK_IX && (mode2 == LOCK_IX
|
||||
|| mode2 == LOCK_IS)) {
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
return((LOCK_MODE_STRONGER_OR_EQ) & LK(mode1, mode2));
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Calculates if lock mode 1 is compatible with lock mode 2. */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
ulint
|
||||
lock_mode_compatible(
|
||||
/*=================*/
|
||||
/* out: TRUE if mode1 compatible with mode2 */
|
||||
ulint mode1, /* in: lock mode */
|
||||
ulint mode2) /* in: lock mode */
|
||||
/* out: nonzero if mode1 compatible with mode2 */
|
||||
enum lock_mode mode1, /* in: lock mode */
|
||||
enum lock_mode mode2) /* in: lock mode */
|
||||
{
|
||||
ut_ad(mode1 == LOCK_X || mode1 == LOCK_S || mode1 == LOCK_IX
|
||||
|| mode1 == LOCK_IS || mode1 == LOCK_AUTO_INC);
|
||||
ut_ad(mode2 == LOCK_X || mode2 == LOCK_S || mode2 == LOCK_IX
|
||||
|| mode2 == LOCK_IS || mode2 == LOCK_AUTO_INC);
|
||||
|
||||
if (mode1 == LOCK_S && (mode2 == LOCK_IS || mode2 == LOCK_S)) {
|
||||
|
||||
return(TRUE);
|
||||
|
||||
} else if (mode1 == LOCK_X) {
|
||||
|
||||
return(FALSE);
|
||||
|
||||
} else if (mode1 == LOCK_AUTO_INC && (mode2 == LOCK_IS
|
||||
|| mode2 == LOCK_IX)) {
|
||||
return(TRUE);
|
||||
|
||||
} else if (mode1 == LOCK_IS && (mode2 == LOCK_IS
|
||||
|| mode2 == LOCK_IX
|
||||
|| mode2 == LOCK_AUTO_INC
|
||||
|| mode2 == LOCK_S)) {
|
||||
return(TRUE);
|
||||
|
||||
} else if (mode1 == LOCK_IX && (mode2 == LOCK_IS
|
||||
|| mode2 == LOCK_AUTO_INC
|
||||
|| mode2 == LOCK_IX)) {
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
return((LOCK_MODE_COMPATIBILITY) & LK(mode1, mode2));
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -1422,7 +1409,7 @@ lock_table_has(
|
|||
/* out: lock or NULL */
|
||||
trx_t* trx, /* in: transaction */
|
||||
dict_table_t* table, /* in: table */
|
||||
ulint mode) /* in: lock mode */
|
||||
enum lock_mode mode) /* in: lock mode */
|
||||
{
|
||||
lock_t* lock;
|
||||
|
||||
|
@ -1511,7 +1498,7 @@ lock_t*
|
|||
lock_rec_other_has_expl_req(
|
||||
/*========================*/
|
||||
/* out: lock or NULL */
|
||||
ulint mode, /* in: LOCK_S or LOCK_X */
|
||||
enum lock_mode mode, /* in: LOCK_S or LOCK_X */
|
||||
ulint gap, /* in: LOCK_GAP if also gap
|
||||
locks are taken into account,
|
||||
or 0 if not */
|
||||
|
@ -1560,7 +1547,7 @@ lock_t*
|
|||
lock_rec_other_has_conflicting(
|
||||
/*===========================*/
|
||||
/* out: lock or NULL */
|
||||
ulint mode, /* in: LOCK_S or LOCK_X,
|
||||
enum lock_mode mode, /* in: LOCK_S or LOCK_X,
|
||||
possibly ORed to LOCK_GAP or
|
||||
LOC_REC_NOT_GAP,
|
||||
LOCK_INSERT_INTENTION */
|
||||
|
@ -3734,7 +3721,7 @@ lock_table_other_has_incompatible(
|
|||
ulint wait, /* in: LOCK_WAIT if also waiting locks are
|
||||
taken into account, or 0 if not */
|
||||
dict_table_t* table, /* in: table */
|
||||
ulint mode) /* in: lock mode */
|
||||
enum lock_mode mode) /* in: lock mode */
|
||||
{
|
||||
lock_t* lock;
|
||||
|
||||
|
@ -3769,7 +3756,7 @@ lock_table(
|
|||
ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
|
||||
does nothing */
|
||||
dict_table_t* table, /* in: database table in dictionary cache */
|
||||
ulint mode, /* in: lock mode */
|
||||
enum lock_mode mode, /* in: lock mode */
|
||||
que_thr_t* thr) /* in: query thread */
|
||||
{
|
||||
trx_t* trx;
|
||||
|
@ -3929,7 +3916,7 @@ lock_rec_unlock(
|
|||
set a record lock */
|
||||
const buf_block_t* block, /* in: buffer block containing rec */
|
||||
const rec_t* rec, /* in: record */
|
||||
ulint lock_mode)/* in: LOCK_S or LOCK_X */
|
||||
enum lock_mode lock_mode)/* in: LOCK_S or LOCK_X */
|
||||
{
|
||||
lock_t* lock;
|
||||
lock_t* release_lock = NULL;
|
||||
|
@ -4720,7 +4707,7 @@ lock_rec_queue_validate(
|
|||
|
||||
if (!lock_rec_get_gap(lock) && !lock_get_wait(lock)) {
|
||||
|
||||
ulint mode;
|
||||
enum lock_mode mode;
|
||||
|
||||
if (lock_get_mode(lock) == LOCK_S) {
|
||||
mode = LOCK_X;
|
||||
|
@ -5233,7 +5220,7 @@ lock_sec_rec_read_check_and_lock(
|
|||
read cursor */
|
||||
dict_index_t* index, /* in: secondary index */
|
||||
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
|
||||
ulint mode, /* in: mode of the lock which
|
||||
enum lock_mode mode, /* in: mode of the lock which
|
||||
the read cursor should set on
|
||||
records: LOCK_S or LOCK_X; the
|
||||
latter is possible in
|
||||
|
@ -5309,7 +5296,7 @@ lock_clust_rec_read_check_and_lock(
|
|||
read cursor */
|
||||
dict_index_t* index, /* in: clustered index */
|
||||
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
|
||||
ulint mode, /* in: mode of the lock which
|
||||
enum lock_mode mode, /* in: mode of the lock which
|
||||
the read cursor should set on
|
||||
records: LOCK_S or LOCK_X; the
|
||||
latter is possible in
|
||||
|
@ -5380,7 +5367,7 @@ lock_clust_rec_read_check_and_lock_alt(
|
|||
be read or passed over by a
|
||||
read cursor */
|
||||
dict_index_t* index, /* in: clustered index */
|
||||
ulint mode, /* in: mode of the lock which
|
||||
enum lock_mode mode, /* in: mode of the lock which
|
||||
the read cursor should set on
|
||||
records: LOCK_S or LOCK_X; the
|
||||
latter is possible in
|
||||
|
|
Loading…
Reference in a new issue