Commit b09ce29a authored by marko's avatar marko

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.
parent fad9e987
...@@ -3275,7 +3275,7 @@ ha_innobase::write_row( ...@@ -3275,7 +3275,7 @@ ha_innobase::write_row(
being blocked by a MySQL table lock TL_WRITE_ALLOW_READ. */ being blocked by a MySQL table lock TL_WRITE_ALLOW_READ. */
dict_table_t* src_table; dict_table_t* src_table;
ulint mode; enum lock_mode mode;
num_write_row = 0; num_write_row = 0;
......
...@@ -25,6 +25,18 @@ extern ibool lock_print_waits; ...@@ -25,6 +25,18 @@ extern ibool lock_print_waits;
/* Buffer for storing information about the most recent deadlock error */ /* Buffer for storing information about the most recent deadlock error */
extern FILE* lock_latest_err_file; 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. */ Gets the size of a lock struct. */
...@@ -354,7 +366,7 @@ lock_sec_rec_read_check_and_lock( ...@@ -354,7 +366,7 @@ lock_sec_rec_read_check_and_lock(
read cursor */ read cursor */
dict_index_t* index, /* in: secondary index */ dict_index_t* index, /* in: secondary index */
const ulint* offsets,/* in: rec_get_offsets(rec, 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 the read cursor should set on
records: LOCK_S or LOCK_X; the records: LOCK_S or LOCK_X; the
latter is possible in latter is possible in
...@@ -385,7 +397,7 @@ lock_clust_rec_read_check_and_lock( ...@@ -385,7 +397,7 @@ lock_clust_rec_read_check_and_lock(
read cursor */ read cursor */
dict_index_t* index, /* in: clustered index */ dict_index_t* index, /* in: clustered index */
const ulint* offsets,/* in: rec_get_offsets(rec, 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 the read cursor should set on
records: LOCK_S or LOCK_X; the records: LOCK_S or LOCK_X; the
latter is possible in latter is possible in
...@@ -417,7 +429,7 @@ lock_clust_rec_read_check_and_lock_alt( ...@@ -417,7 +429,7 @@ lock_clust_rec_read_check_and_lock_alt(
be read or passed over by a be read or passed over by a
read cursor */ read cursor */
dict_index_t* index, /* in: clustered index */ 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 the read cursor should set on
records: LOCK_S or LOCK_X; the records: LOCK_S or LOCK_X; the
latter is possible in latter is possible in
...@@ -473,7 +485,7 @@ lock_table( ...@@ -473,7 +485,7 @@ lock_table(
ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
does nothing */ does nothing */
dict_table_t* table, /* in: database table in dictionary cache */ 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 */ que_thr_t* thr); /* in: query thread */
/************************************************************************* /*************************************************************************
Checks if there are any locks set on the table. */ Checks if there are any locks set on the table. */
...@@ -495,7 +507,7 @@ lock_rec_unlock( ...@@ -495,7 +507,7 @@ lock_rec_unlock(
set a record lock */ set a record lock */
const buf_block_t* block, /* in: buffer block containing rec */ const buf_block_t* block, /* in: buffer block containing rec */
const rec_t* rec, /* in: record */ 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 a table lock.
Releases possible other transactions waiting for this lock. */ Releases possible other transactions waiting for this lock. */
...@@ -571,7 +583,7 @@ lock_get_src_table( ...@@ -571,7 +583,7 @@ lock_get_src_table(
two tables or an inconsistency is found */ two tables or an inconsistency is found */
trx_t* trx, /* in: transaction */ trx_t* trx, /* in: transaction */
dict_table_t* dest, /* in: destination of ALTER TABLE */ 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 Determine if the given table is exclusively "owned" by the given
transaction, i.e., transaction holds LOCK_IX and possibly LOCK_AUTO_INC transaction, i.e., transaction holds LOCK_IX and possibly LOCK_AUTO_INC
...@@ -641,15 +653,6 @@ lock_number_of_rows_locked( ...@@ -641,15 +653,6 @@ lock_number_of_rows_locked(
extern lock_sys_t* lock_sys; extern lock_sys_t* lock_sys;
/* Lock modes and types */ /* 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 #define LOCK_MODE_MASK 0xFUL /* mask used to extract mode from the
type_mode field in a lock */ type_mode field in a lock */
/* Lock types */ /* Lock types */
...@@ -700,7 +703,7 @@ extern lock_sys_t* lock_sys; ...@@ -700,7 +703,7 @@ extern lock_sys_t* lock_sys;
typedef struct lock_op_struct lock_op_t; typedef struct lock_op_struct lock_op_t;
struct lock_op_struct{ struct lock_op_struct{
dict_table_t* table; /* table to be locked */ dict_table_t* table; /* table to be locked */
ulint mode; /* lock mode */ enum lock_mode mode; /* lock mode */
}; };
#define LOCK_OP_START 1 #define LOCK_OP_START 1
......
...@@ -311,6 +311,39 @@ locks on the inserted record. */ ...@@ -311,6 +311,39 @@ locks on the inserted record. */
* statement-level MySQL binlog. * statement-level MySQL binlog.
* See also lock_mode_compatible(). * 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 #ifdef UNIV_DEBUG
ibool lock_print_waits = FALSE; ibool lock_print_waits = FALSE;
...@@ -623,7 +656,7 @@ lock_get_size(void) ...@@ -623,7 +656,7 @@ lock_get_size(void)
/************************************************************************* /*************************************************************************
Gets the mode of a lock. */ Gets the mode of a lock. */
UNIV_INLINE UNIV_INLINE
ulint enum lock_mode
lock_get_mode( lock_get_mode(
/*==========*/ /*==========*/
/* out: mode */ /* out: mode */
...@@ -667,7 +700,7 @@ lock_get_src_table( ...@@ -667,7 +700,7 @@ lock_get_src_table(
two tables or an inconsistency is found */ two tables or an inconsistency is found */
trx_t* trx, /* in: transaction */ trx_t* trx, /* in: transaction */
dict_table_t* dest, /* in: destination of ALTER TABLE */ 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; dict_table_t* src;
lock_t* lock; lock_t* lock;
...@@ -679,7 +712,7 @@ lock_get_src_table( ...@@ -679,7 +712,7 @@ lock_get_src_table(
lock; lock;
lock = UT_LIST_GET_NEXT(trx_locks, lock)) { lock = UT_LIST_GET_NEXT(trx_locks, lock)) {
lock_table_t* tab_lock; lock_table_t* tab_lock;
ulint lock_mode; enum lock_mode lock_mode;
if (!(lock_get_type(lock) & LOCK_TABLE)) { if (!(lock_get_type(lock) & LOCK_TABLE)) {
/* We are only interested in table locks. */ /* We are only interested in table locks. */
continue; continue;
...@@ -706,15 +739,12 @@ lock_get_src_table( ...@@ -706,15 +739,12 @@ lock_get_src_table(
/* Check that the source table is locked by /* Check that the source table is locked by
LOCK_IX or LOCK_IS. */ LOCK_IX or LOCK_IS. */
lock_mode = lock_get_mode(lock); lock_mode = lock_get_mode(lock);
switch (lock_mode) { if (lock_mode == LOCK_IX || lock_mode == LOCK_IS) {
case LOCK_IX:
case LOCK_IS:
if (*mode != LOCK_NONE && *mode != lock_mode) { if (*mode != LOCK_NONE && *mode != lock_mode) {
/* There are multiple locks on src. */ /* There are multiple locks on src. */
return(NULL); return(NULL);
} }
*mode = lock_mode; *mode = lock_mode;
break;
} }
} }
...@@ -872,81 +902,38 @@ lock_rec_get_insert_intention( ...@@ -872,81 +902,38 @@ lock_rec_get_insert_intention(
/************************************************************************* /*************************************************************************
Calculates if lock mode 1 is stronger or equal to lock mode 2. */ Calculates if lock mode 1 is stronger or equal to lock mode 2. */
UNIV_INLINE UNIV_INLINE
ibool ulint
lock_mode_stronger_or_eq( lock_mode_stronger_or_eq(
/*=====================*/ /*=====================*/
/* out: TRUE if mode1 stronger or equal to mode2 */ /* out: nonzero
ulint mode1, /* in: lock mode */ if mode1 stronger or equal to mode2 */
ulint mode2) /* in: lock mode */ 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 ut_ad(mode1 == LOCK_X || mode1 == LOCK_S || mode1 == LOCK_IX
|| mode1 == LOCK_IS || mode1 == LOCK_AUTO_INC); || mode1 == LOCK_IS || mode1 == LOCK_AUTO_INC);
ut_ad(mode2 == LOCK_X || mode2 == LOCK_S || mode2 == LOCK_IX ut_ad(mode2 == LOCK_X || mode2 == LOCK_S || mode2 == LOCK_IX
|| mode2 == LOCK_IS || mode2 == LOCK_AUTO_INC); || 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. */ Calculates if lock mode 1 is compatible with lock mode 2. */
UNIV_INLINE UNIV_INLINE
ibool ulint
lock_mode_compatible( lock_mode_compatible(
/*=================*/ /*=================*/
/* out: TRUE if mode1 compatible with mode2 */ /* out: nonzero if mode1 compatible with mode2 */
ulint mode1, /* in: lock mode */ enum lock_mode mode1, /* in: lock mode */
ulint mode2) /* in: lock mode */ enum lock_mode mode2) /* in: lock mode */
{ {
ut_ad(mode1 == LOCK_X || mode1 == LOCK_S || mode1 == LOCK_IX ut_ad(mode1 == LOCK_X || mode1 == LOCK_S || mode1 == LOCK_IX
|| mode1 == LOCK_IS || mode1 == LOCK_AUTO_INC); || mode1 == LOCK_IS || mode1 == LOCK_AUTO_INC);
ut_ad(mode2 == LOCK_X || mode2 == LOCK_S || mode2 == LOCK_IX ut_ad(mode2 == LOCK_X || mode2 == LOCK_S || mode2 == LOCK_IX
|| mode2 == LOCK_IS || mode2 == LOCK_AUTO_INC); || mode2 == LOCK_IS || mode2 == LOCK_AUTO_INC);
if (mode1 == LOCK_S && (mode2 == LOCK_IS || mode2 == LOCK_S)) { return((LOCK_MODE_COMPATIBILITY) & LK(mode1, mode2));
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);
} }
/************************************************************************* /*************************************************************************
...@@ -1422,7 +1409,7 @@ lock_table_has( ...@@ -1422,7 +1409,7 @@ lock_table_has(
/* out: lock or NULL */ /* out: lock or NULL */
trx_t* trx, /* in: transaction */ trx_t* trx, /* in: transaction */
dict_table_t* table, /* in: table */ dict_table_t* table, /* in: table */
ulint mode) /* in: lock mode */ enum lock_mode mode) /* in: lock mode */
{ {
lock_t* lock; lock_t* lock;
...@@ -1511,7 +1498,7 @@ lock_t* ...@@ -1511,7 +1498,7 @@ lock_t*
lock_rec_other_has_expl_req( lock_rec_other_has_expl_req(
/*========================*/ /*========================*/
/* out: lock or NULL */ /* 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 ulint gap, /* in: LOCK_GAP if also gap
locks are taken into account, locks are taken into account,
or 0 if not */ or 0 if not */
...@@ -1560,7 +1547,7 @@ lock_t* ...@@ -1560,7 +1547,7 @@ lock_t*
lock_rec_other_has_conflicting( lock_rec_other_has_conflicting(
/*===========================*/ /*===========================*/
/* out: lock or NULL */ /* 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 possibly ORed to LOCK_GAP or
LOC_REC_NOT_GAP, LOC_REC_NOT_GAP,
LOCK_INSERT_INTENTION */ LOCK_INSERT_INTENTION */
...@@ -3734,7 +3721,7 @@ lock_table_other_has_incompatible( ...@@ -3734,7 +3721,7 @@ lock_table_other_has_incompatible(
ulint wait, /* in: LOCK_WAIT if also waiting locks are ulint wait, /* in: LOCK_WAIT if also waiting locks are
taken into account, or 0 if not */ taken into account, or 0 if not */
dict_table_t* table, /* in: table */ dict_table_t* table, /* in: table */
ulint mode) /* in: lock mode */ enum lock_mode mode) /* in: lock mode */
{ {
lock_t* lock; lock_t* lock;
...@@ -3769,7 +3756,7 @@ lock_table( ...@@ -3769,7 +3756,7 @@ lock_table(
ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
does nothing */ does nothing */
dict_table_t* table, /* in: database table in dictionary cache */ 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 */ que_thr_t* thr) /* in: query thread */
{ {
trx_t* trx; trx_t* trx;
...@@ -3929,7 +3916,7 @@ lock_rec_unlock( ...@@ -3929,7 +3916,7 @@ lock_rec_unlock(
set a record lock */ set a record lock */
const buf_block_t* block, /* in: buffer block containing rec */ const buf_block_t* block, /* in: buffer block containing rec */
const rec_t* rec, /* in: record */ 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* lock;
lock_t* release_lock = NULL; lock_t* release_lock = NULL;
...@@ -4720,7 +4707,7 @@ lock_rec_queue_validate( ...@@ -4720,7 +4707,7 @@ lock_rec_queue_validate(
if (!lock_rec_get_gap(lock) && !lock_get_wait(lock)) { if (!lock_rec_get_gap(lock) && !lock_get_wait(lock)) {
ulint mode; enum lock_mode mode;
if (lock_get_mode(lock) == LOCK_S) { if (lock_get_mode(lock) == LOCK_S) {
mode = LOCK_X; mode = LOCK_X;
...@@ -5233,7 +5220,7 @@ lock_sec_rec_read_check_and_lock( ...@@ -5233,7 +5220,7 @@ lock_sec_rec_read_check_and_lock(
read cursor */ read cursor */
dict_index_t* index, /* in: secondary index */ dict_index_t* index, /* in: secondary index */
const ulint* offsets,/* in: rec_get_offsets(rec, 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 the read cursor should set on
records: LOCK_S or LOCK_X; the records: LOCK_S or LOCK_X; the
latter is possible in latter is possible in
...@@ -5309,7 +5296,7 @@ lock_clust_rec_read_check_and_lock( ...@@ -5309,7 +5296,7 @@ lock_clust_rec_read_check_and_lock(
read cursor */ read cursor */
dict_index_t* index, /* in: clustered index */ dict_index_t* index, /* in: clustered index */
const ulint* offsets,/* in: rec_get_offsets(rec, 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 the read cursor should set on
records: LOCK_S or LOCK_X; the records: LOCK_S or LOCK_X; the
latter is possible in latter is possible in
...@@ -5380,7 +5367,7 @@ lock_clust_rec_read_check_and_lock_alt( ...@@ -5380,7 +5367,7 @@ lock_clust_rec_read_check_and_lock_alt(
be read or passed over by a be read or passed over by a
read cursor */ read cursor */
dict_index_t* index, /* in: clustered index */ 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 the read cursor should set on
records: LOCK_S or LOCK_X; the records: LOCK_S or LOCK_X; the
latter is possible in latter is possible in
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment