Drizzled Public API Documentation

ut0lst.h

Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003 Copyright (C) 1995, 2010, Innobase Oy. All Rights Reserved.
00004 
00005 This program is free software; you can redistribute it and/or modify it under
00006 the terms of the GNU General Public License as published by the Free Software
00007 Foundation; version 2 of the License.
00008 
00009 This program is distributed in the hope that it will be useful, but WITHOUT
00010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00011 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
00012 
00013 You should have received a copy of the GNU General Public License along with
00014 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
00015 St, Fifth Floor, Boston, MA 02110-1301 USA
00016 
00017 *****************************************************************************/
00018 
00019 /******************************************************************/
00026 #pragma once
00027 #ifndef ut0lst_h
00028 #define ut0lst_h
00029 
00030 #include "univ.i"
00031 
00032 /* This module implements the two-way linear list which should be used
00033 if a list is used in the database. Note that a single struct may belong
00034 to two or more lists, provided that the list are given different names.
00035 An example of the usage of the lists can be found in fil0fil.c. */
00036 
00037 /*******************************************************************/
00043 #ifdef __cplusplus
00044 template<class T>
00045 class ut_list_base_node
00046 {
00047 public:
00048   size_t count; \
00049   T * start;  \
00050   T * end;  \
00051 };
00052 #define UT_LIST_BASE_NODE_T(TYPE) ut_list_base_node<TYPE>
00053 #else
00054 #define UT_LIST_BASE_NODE_T(TYPE) int
00055 #endif
00056 
00057 /*******************************************************************/
00064 /* Example:
00065 typedef struct LRU_node_struct  LRU_node_t;
00066 struct LRU_node_struct {
00067   UT_LIST_NODE_T(LRU_node_t)  LRU_list;
00068   ...
00069 }
00070 The example implements an LRU list of name LRU_list. Its nodes are of type
00071 LRU_node_t. */
00072 
00073 #define UT_LIST_NODE_T(TYPE)\
00074 struct {\
00075   TYPE *  prev; \
00077   TYPE *  next; \
00078 }\
00079 
00080 /*******************************************************************/
00084 #define UT_LIST_INIT(BASE)\
00085 {\
00086   (BASE).count = 0;\
00087   (BASE).start = NULL;\
00088   (BASE).end   = NULL;\
00089 }\
00090 
00091 /*******************************************************************/
00097 #define UT_LIST_ADD_FIRST(NAME, BASE, N)\
00098 {\
00099   ut_ad(N);\
00100   ((BASE).count)++;\
00101   ((N)->NAME).next = (BASE).start;\
00102   ((N)->NAME).prev = NULL;\
00103   if (UNIV_LIKELY((BASE).start != NULL)) {\
00104     ut_ad((BASE).start != (N));\
00105     (((BASE).start)->NAME).prev = (N);\
00106   }\
00107   (BASE).start = (N);\
00108   if (UNIV_UNLIKELY((BASE).end == NULL)) {\
00109     (BASE).end = (N);\
00110   }\
00111 }\
00112 
00113 /*******************************************************************/
00119 #define UT_LIST_ADD_LAST(NAME, BASE, N)\
00120 {\
00121   ut_ad(N != NULL);\
00122   ((BASE).count)++;\
00123   ((N)->NAME).prev = (BASE).end;\
00124   ((N)->NAME).next = NULL;\
00125   if ((BASE).end != NULL) {\
00126     ut_ad((BASE).end != (N));\
00127     (((BASE).end)->NAME).next = (N);\
00128   }\
00129   (BASE).end = (N);\
00130   if ((BASE).start == NULL) {\
00131     (BASE).start = (N);\
00132   }\
00133 }\
00134 
00135 /*******************************************************************/
00142 #define UT_LIST_INSERT_AFTER(NAME, BASE, NODE1, NODE2)\
00143 {\
00144   ut_ad(NODE1);\
00145   ut_ad(NODE2);\
00146   ut_ad((NODE1) != (NODE2));\
00147   ((BASE).count)++;\
00148   ((NODE2)->NAME).prev = (NODE1);\
00149   ((NODE2)->NAME).next = ((NODE1)->NAME).next;\
00150   if (((NODE1)->NAME).next != NULL) {\
00151     ((((NODE1)->NAME).next)->NAME).prev = (NODE2);\
00152   }\
00153   ((NODE1)->NAME).next = (NODE2);\
00154   if ((BASE).end == (NODE1)) {\
00155     (BASE).end = (NODE2);\
00156   }\
00157 }\
00158 
00159 #ifdef UNIV_LIST_DEBUG
00160 
00163 # define UT_LIST_REMOVE_CLEAR(NAME, N)    \
00164 ((N)->NAME.prev = (N)->NAME.next = (void*) -1)
00165 #else
00166 
00169 # define UT_LIST_REMOVE_CLEAR(NAME, N)
00170 #endif
00171 
00172 /*******************************************************************/
00178 #define UT_LIST_REMOVE(NAME, BASE, N)         \
00179 do {                  \
00180   ut_ad(N);             \
00181   ut_a((BASE).count > 0);           \
00182   ((BASE).count)--;           \
00183   if (((N)->NAME).next != NULL) {         \
00184     ((((N)->NAME).next)->NAME).prev = ((N)->NAME).prev; \
00185   } else {              \
00186     (BASE).end = ((N)->NAME).prev;        \
00187   }               \
00188   if (((N)->NAME).prev != NULL) {         \
00189     ((((N)->NAME).prev)->NAME).next = ((N)->NAME).next; \
00190   } else {              \
00191     (BASE).start = ((N)->NAME).next;      \
00192   }               \
00193   UT_LIST_REMOVE_CLEAR(NAME, N);          \
00194 } while (0)
00195 
00196 /********************************************************************/
00201 #define UT_LIST_GET_NEXT(NAME, N)\
00202   (((N)->NAME).next)
00203 
00204 /********************************************************************/
00209 #define UT_LIST_GET_PREV(NAME, N)\
00210   (((N)->NAME).prev)
00211 
00212 /********************************************************************/
00217 #define UT_LIST_GET_LEN(BASE)\
00218   (BASE).count
00219 
00220 /********************************************************************/
00224 #define UT_LIST_GET_FIRST(BASE)\
00225   (BASE).start
00226 
00227 /********************************************************************/
00231 #ifdef __cplusplus
00232 #define UT_LIST_GET_LAST(BASE)\
00233   (BASE).end
00234 #else
00235 #define UT_LIST_GET_LAST(BASE) (BASE= NULL)
00236 #endif
00237 
00238 /********************************************************************/
00244 #define UT_LIST_VALIDATE(NAME, TYPE, BASE, ASSERTION)     \
00245 do {                  \
00246   ulint ut_list_i_313;            \
00247   TYPE* ut_list_node_313;         \
00248                   \
00249   ut_list_node_313 = (BASE).start;        \
00250                   \
00251   for (ut_list_i_313 = (BASE).count; ut_list_i_313--; ) {   \
00252     ut_a(ut_list_node_313);         \
00253     ASSERTION;            \
00254     ut_ad((ut_list_node_313->NAME).next || !ut_list_i_313); \
00255     ut_list_node_313 = (ut_list_node_313->NAME).next; \
00256   }               \
00257                   \
00258   ut_a(ut_list_node_313 == NULL);         \
00259                   \
00260   ut_list_node_313 = (BASE).end;          \
00261                   \
00262   for (ut_list_i_313 = (BASE).count; ut_list_i_313--; ) {   \
00263     ut_a(ut_list_node_313);         \
00264     ASSERTION;            \
00265     ut_ad((ut_list_node_313->NAME).prev || !ut_list_i_313); \
00266     ut_list_node_313 = (ut_list_node_313->NAME).prev; \
00267   }               \
00268                   \
00269   ut_a(ut_list_node_313 == NULL);         \
00270 } while (0)
00271 
00272 #endif
00273