diff --git a/Makefile.am b/Makefile.am index 1ac3c365983..5c15b60f10d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -55,6 +55,7 @@ noinst_HEADERS = include/btr0btr.h include/btr0btr.ic \ include/ha0ha.ic include/hash0hash.h \ include/hash0hash.ic include/ibuf0ibuf.h \ include/ibuf0ibuf.ic include/ibuf0types.h \ + include/lock0iter.h \ include/lock0lock.h include/lock0lock.ic \ include/lock0priv.h include/lock0priv.ic \ include/lock0types.h include/log0log.h \ @@ -130,7 +131,8 @@ libinnobase_a_SOURCES = btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \ eval/eval0eval.c eval/eval0proc.c \ fil/fil0fil.c fsp/fsp0fsp.c fut/fut0fut.c \ fut/fut0lst.c ha/ha0ha.c ha/hash0hash.c \ - ibuf/ibuf0ibuf.c lock/lock0lock.c \ + ibuf/ibuf0ibuf.c lock/lock0iter.c \ + lock/lock0lock.c \ log/log0log.c log/log0recv.c mach/mach0data.c \ mem/mem0mem.c mem/mem0pool.c mtr/mtr0log.c \ mtr/mtr0mtr.c os/os0file.c os/os0proc.c \ diff --git a/include/lock0iter.h b/include/lock0iter.h new file mode 100644 index 00000000000..d063a360c1f --- /dev/null +++ b/include/lock0iter.h @@ -0,0 +1,52 @@ +/****************************************************** +Lock queue iterator type and function prototypes. + +(c) 2007 Innobase Oy + +Created July 16, 2007 Vasil Dimov +*******************************************************/ + +#ifndef lock0iter_h +#define lock0iter_h + +#include "univ.i" +#include "lock0types.h" + +typedef struct lock_queue_iterator_struct { + lock_t* current_lock; + /* In case this is a record lock queue (not table lock queue) + then bit_no is the record number within the heap in which the + record is stored. */ + ulint bit_no; +} lock_queue_iterator_t; + +/*********************************************************************** +Initialize lock queue iterator so that it starts to iterate from +"lock". bit_no specifies the record number within the heap where the +record is stored. It can be undefined (ULINT_UNDEFINED) in two cases: +1. If the lock is a table lock, thus we have a table lock queue; +2. If the lock is a record lock and it is a wait lock. In this case + bit_no is calculated in this function by using + lock_rec_find_set_bit(). There is exactly one bit set in the bitmap + of a wait lock. */ + +void +lock_queue_iterator_reset( +/*======================*/ + lock_queue_iterator_t* iter, /* out: iterator */ + lock_t* lock, /* in: lock to start from */ + ulint bit_no);/* in: record number in the + heap */ + +/*********************************************************************** +Gets the previous lock in the lock queue, returns NULL if there are no +more locks (i.e. the current lock is the first one). The iterator is +receded (if not-NULL is returned). */ + +lock_t* +lock_queue_iterator_get_prev( +/*=========================*/ + /* out: previous lock or NULL */ + lock_queue_iterator_t* iter); /* in/out: iterator */ + +#endif /* lock0iter_h */ diff --git a/lock/lock0iter.c b/lock/lock0iter.c new file mode 100644 index 00000000000..cad227e3f8e --- /dev/null +++ b/lock/lock0iter.c @@ -0,0 +1,91 @@ +/****************************************************** +Lock queue iterator. Can iterate over table and record +lock queues. + +(c) 2007 Innobase Oy + +Created July 16, 2007 Vasil Dimov +*******************************************************/ + +#define LOCK_MODULE_IMPLEMENTATION + +#include "univ.i" +#include "lock0iter.h" +#include "lock0lock.h" +#include "lock0priv.h" +#include "ut0dbg.h" +#include "ut0lst.h" + +/*********************************************************************** +Initialize lock queue iterator so that it starts to iterate from +"lock". bit_no specifies the record number within the heap where the +record is stored. It can be undefined (ULINT_UNDEFINED) in two cases: +1. If the lock is a table lock, thus we have a table lock queue; +2. If the lock is a record lock and it is a wait lock. In this case + bit_no is calculated in this function by using + lock_rec_find_set_bit(). There is exactly one bit set in the bitmap + of a wait lock. */ + +void +lock_queue_iterator_reset( +/*======================*/ + lock_queue_iterator_t* iter, /* out: iterator */ + lock_t* lock, /* in: lock to start from */ + ulint bit_no) /* in: record number in the + heap */ +{ + iter->current_lock = lock; + + if (bit_no != ULINT_UNDEFINED) { + + iter->bit_no = bit_no; + } else { + + switch (lock_get_type(lock)) { + case LOCK_TABLE: + iter->bit_no = ULINT_UNDEFINED; + break; + case LOCK_REC: + iter->bit_no = lock_rec_find_set_bit(lock); + ut_a(iter->bit_no != ULINT_UNDEFINED); + break; + default: + ut_error; + } + } +} + +/*********************************************************************** +Gets the previous lock in the lock queue, returns NULL if there are no +more locks (i.e. the current lock is the first one). The iterator is +receded (if not-NULL is returned). */ + +lock_t* +lock_queue_iterator_get_prev( +/*=========================*/ + /* out: previous lock or NULL */ + lock_queue_iterator_t* iter) /* in/out: iterator */ +{ + ulint bit_no; + lock_t* prev_lock; + + switch (lock_get_type(iter->current_lock)) { + case LOCK_REC: + prev_lock = lock_rec_get_prev( + iter->current_lock, iter->bit_no); + break; + case LOCK_TABLE: + prev_lock = UT_LIST_GET_PREV( + un_member.tab_lock.locks, iter->current_lock); + break; + default: + ut_error; + } + + if (prev_lock != NULL) { + + iter->current_lock = prev_lock; + } + + return(prev_lock); +}