From c5025f7adc194de3c4730bfbc0e3cfe01de0900f Mon Sep 17 00:00:00 2001 From: vasil Date: Tue, 17 Jul 2007 15:08:04 +0000 Subject: [PATCH] Introduce a lock queue iterator for easy (and opaque) traversing of lock queues. Supports table and record lock queues via the same interface. There is only "get previous" method because currently there is no need for "get next" - it would be unused. Feel free to add one if needed. Approved by: Heikki --- Makefile.am | 4 +- include/lock0iter.h | 52 ++++++++++++++++++++++++++ lock/lock0iter.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 include/lock0iter.h create mode 100644 lock/lock0iter.c 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); +}