2008-01-25 15:43:37 +00:00
|
|
|
#ifndef _TOKUDB_LIST_H
|
|
|
|
#define _TOKUDB_LIST_H
|
|
|
|
|
2008-01-24 15:10:32 +00:00
|
|
|
#ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved."
|
2007-11-29 14:18:54 +00:00
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2008-02-14 19:23:25 +00: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
|