2008-01-25 15:43:37 +00:00
# ifndef _TOKUDB_LIST_H
# define _TOKUDB_LIST_H
2013-04-16 23:57:48 -04:00
# ident "$Id$"
2013-04-16 23:57:48 -04:00
# ident "Copyright (c) 2007, 2008, 2009 Tokutek Inc. All rights reserved."
# ident "The technology is licensed by the Massachusetts Institute of Technology, Rutgers State University of New Jersey, and the Research Foundation of State University of New York at Stony Brook under United States of America Serial No. 11 / 760379 and to the patents and / or patent applications resulting from it."
2007-11-29 14:18:54 +00:00
2013-04-16 23:57:41 -04:00
//TODO: #1378 This is not threadsafe. Make sure when splitting locks
//that we protect these calls.
2007-11-14 17:58:38 +00:00
// This list is intended to be embedded in other data structures.
2007-08-06 19:43:27 +00:00
struct list {
struct list * next , * prev ;
} ;
static inline void list_init ( struct list * head ) {
head - > next = head - > prev = head ;
}
static inline int list_empty ( struct list * head ) {
return head - > next = = head ;
}
static inline struct list * list_head ( struct list * head ) {
return head - > next ;
}
static inline struct list * list_tail ( struct list * head ) {
return head - > prev ;
}
static inline void list_insert_between ( struct list * a , struct list * list , struct list * b ) {
list - > next = a - > next ;
list - > prev = b - > prev ;
a - > next = b - > prev = list ;
}
static inline void list_push ( struct list * head , struct list * list ) {
list_insert_between ( head - > prev , list , head ) ;
}
static inline void list_push_head ( struct list * head , struct list * list ) {
list_insert_between ( head , list , head - > next ) ;
}
static inline void list_remove ( struct list * list ) {
2007-12-07 14:56:54 +00:00
struct list * prev = list - > prev ;
struct list * next = list - > next ;
next - > prev = prev ;
prev - > next = next ;
list_init ( list ) ; // Set the list element to be empty
2007-08-06 19:43:27 +00:00
}
static inline struct list * list_pop ( struct list * head ) {
struct list * list = head - > prev ;
list_remove ( list ) ;
return list ;
}
static inline struct list * list_pop_head ( struct list * head ) {
struct list * list = head - > next ;
list_remove ( list ) ;
return list ;
}
static inline void list_move ( struct list * newhead , struct list * oldhead ) {
struct list * first = oldhead - > next ;
struct list * last = oldhead - > prev ;
2008-01-25 15:43:37 +00:00
// assert(!list_empty(oldhead));
2007-08-06 19:43:27 +00:00
newhead - > next = first ;
newhead - > prev = last ;
last - > next = first - > prev = newhead ;
list_init ( oldhead ) ;
}
2013-04-16 23:57:41 -04:00
// Note: Need the extra level of parens in these macros so that
2007-11-30 06:27:49 +00:00
// list_struct(h, foo, b)->zot
// will work right. Otherwise the type cast will try to include ->zot, and it will be all messed up.
2007-08-09 13:00:24 +00:00
# if defined(__GNUC__) && __GNUC__ >= 4
2007-11-30 06:27:49 +00:00
# define list_struct(p, t, f) ((t*)((char*)(p) - __builtin_offsetof(t, f)))
2007-08-09 13:00:24 +00:00
# else
2007-11-30 06:27:49 +00:00
# define list_struct(p, t, f) ((t*)((char*)(p) - ((char*)&((t*)0)->f)))
2007-08-09 13:00:24 +00:00
# endif
2007-08-06 19:43:27 +00:00
2008-01-25 15:43:37 +00:00
# endif