Commit b1eff53d authored by Yoni Fogel's avatar Yoni Fogel

Closes #2128 closes[t:2128] List structure renamed to toku_list, same as header, and header moved

> to toku_include/.
> This is done to avoid poisoning namespace, and to be easily included by handlerton.

git-svn-id: file:///svn/toku/tokudb@15579 c7de825b-a66e-492c-adef-691d508d4ae1
parent 588b63bf
......@@ -3,7 +3,7 @@
#ident "Copyright (c) 2007 Tokutek Inc. All rights reserved."
#include "list.h"
#include "toku_list.h"
// Included by db.h, defines some internal structures. These structures are inlined in some versions of db.h
// the types DB_TXN and so forth have been defined.
......@@ -18,7 +18,7 @@ struct __toku_db_txn_internal {
struct __toku_lth *lth; //Hash table holding list of dictionaries this txn has touched
u_int32_t flags;
DB_TXN *child;
struct list dbs_that_must_close_before_abort;
struct toku_list dbs_that_must_close_before_abort;
};
struct __toku_dbc_internal {
......
......@@ -433,8 +433,8 @@ deserialize_brtheader_10 (int fd, struct rbuf *rb, struct brt_header **brth) {
h->dirty=0;
h->panic = 0;
h->panic_string = 0;
list_init(&h->live_brts);
list_init(&h->zombie_brts);
toku_list_init(&h->live_brts);
toku_list_init(&h->zombie_brts);
//version MUST be in network order on disk regardless of disk order
h->layout_version = rbuf_network_int(&rc);
assert(h->layout_version==BRT_LAYOUT_VERSION_10);
......
......@@ -11,7 +11,7 @@
#include "cachetable.h"
#include "fifo.h"
#include "brt.h"
#include "list.h"
#include "toku_list.h"
#include "mempool.h"
#include "kv-pair.h"
#include "omt.h"
......@@ -172,8 +172,8 @@ struct brt_header {
// If a transaction locked the BRT when it was empty, which transaction? (Only the latest one matters)
// 0 if no such transaction
TXNID txnid_that_created_or_locked_when_empty;
struct list live_brts;
struct list zombie_brts;
struct toku_list live_brts;
struct toku_list zombie_brts;
};
struct brt {
......@@ -181,7 +181,7 @@ struct brt {
// The header is shared. It is also ephemeral.
struct brt_header *h;
struct list cursors;
struct toku_list cursors;
unsigned int nodesize;
unsigned int flags;
......@@ -201,8 +201,8 @@ struct brt {
int (*close_db)(DB*, u_int32_t);
u_int32_t close_flags;
struct list live_brt_link;
struct list zombie_brt_link;
struct toku_list live_brt_link;
struct toku_list zombie_brt_link;
};
/* serialization code */
......@@ -270,7 +270,7 @@ struct brt_cursor_leaf_info {
/* a brt cursor is represented as a kv pair in a tree */
struct brt_cursor {
struct list cursors_link;
struct toku_list cursors_link;
BRT brt;
BOOL current_in_omt;
BOOL prefetching;
......
......@@ -1397,8 +1397,8 @@ deserialize_brtheader (int fd, struct rbuf *rb, struct brt_header **brth) {
h->dirty=0;
h->panic = 0;
h->panic_string = 0;
list_init(&h->live_brts);
list_init(&h->zombie_brts);
toku_list_init(&h->live_brts);
toku_list_init(&h->zombie_brts);
//version MUST be in network order on disk regardless of disk order
h->layout_version = rbuf_network_int(&rc);
//TODO: #1924
......
......@@ -2908,8 +2908,8 @@ brt_init_header (BRT t) {
toku_allocate_blocknum(t->h->blocktable, &root, t->h);
t->h->root = root;
list_init(&t->h->live_brts);
list_init(&t->h->zombie_brts);
toku_list_init(&t->h->live_brts);
toku_list_init(&t->h->zombie_brts);
int r = brt_init_header_partial(t);
if (r==0) toku_block_verify_no_free_blocknums(t->h->blocktable);
return r;
......@@ -2965,8 +2965,8 @@ brtheader_note_brt_close(BRT t) {
struct brt_header *h = t->h;
if (h) { //Might not yet have been opened.
toku_brtheader_lock(h);
list_remove(&t->live_brt_link);
list_remove(&t->zombie_brt_link);
toku_list_remove(&t->live_brt_link);
toku_list_remove(&t->zombie_brt_link);
toku_brtheader_unlock(h);
}
}
......@@ -2980,16 +2980,16 @@ brtheader_note_brt_open(BRT live, char** fnamep) {
char *fname = *fnamep;
assert(fname);
*fnamep = NULL;
while (!list_empty(&h->zombie_brts)) {
while (!toku_list_empty(&h->zombie_brts)) {
//Remove dead brt from list
BRT zombie = list_struct(list_pop(&h->zombie_brts), struct brt, zombie_brt_link);
BRT zombie = toku_list_struct(toku_list_pop(&h->zombie_brts), struct brt, zombie_brt_link);
toku_brtheader_unlock(h); //Cannot be holding lock when swapping brts.
retval = toku_txn_note_swap_brt(live, zombie); //Steal responsibility, close
toku_brtheader_lock(h);
if (retval) break;
}
if (retval==0)
list_push(&h->live_brts, &live->live_brt_link);
toku_list_push(&h->live_brts, &live->live_brt_link);
//Use fname, or throw it away.
//Must not use fname on failure (or when brt is closed, a (possibly corrupt) header will be written.
if (retval == 0 && h->fname == NULL)
......@@ -3111,7 +3111,7 @@ int toku_brt_open(BRT t, const char *fname, const char *fname_in_env, int is_cre
goto died_after_read_and_pin;
}
toku_brtheader_lock(t->h);
if (!list_empty(&t->h->live_brts) || !list_empty(&t->h->zombie_brts)) {
if (!toku_list_empty(&t->h->live_brts) || !toku_list_empty(&t->h->zombie_brts)) {
//Disallow changing if exists two brts with the same header (counting this one)
//The upgrade would be impossible/very hard!
r = EINVAL;
......@@ -3290,8 +3290,8 @@ toku_brtheader_close (CACHEFILE cachefile, void *header_v, char **malloced_error
struct brt_header *h = header_v;
assert(h->type == BRTHEADER_CURRENT);
toku_brtheader_lock(h);
assert(list_empty(&h->live_brts));
assert(list_empty(&h->zombie_brts));
assert(toku_list_empty(&h->live_brts));
assert(toku_list_empty(&h->zombie_brts));
toku_brtheader_unlock(h);
int r = 0;
if (h->panic) {
......@@ -3358,15 +3358,15 @@ toku_brt_db_delay_closed (BRT zombie, DB* db, int (*close_db)(DB*, u_int32_t), u
else {
//Try to pass responsibility off.
toku_brtheader_lock(zombie->h);
list_remove(&zombie->live_brt_link); //Remove from live.
toku_list_remove(&zombie->live_brt_link); //Remove from live.
BRT replacement = NULL;
if (!list_empty(&h->live_brts)) {
replacement = list_struct(list_head(&h->live_brts), struct brt, live_brt_link);
if (!toku_list_empty(&h->live_brts)) {
replacement = toku_list_struct(toku_list_head(&h->live_brts), struct brt, live_brt_link);
}
else if (!list_empty(&h->zombie_brts)) {
replacement = list_struct(list_head(&h->zombie_brts), struct brt, zombie_brt_link);
else if (!toku_list_empty(&h->zombie_brts)) {
replacement = toku_list_struct(toku_list_head(&h->zombie_brts), struct brt, zombie_brt_link);
}
list_push(&h->zombie_brts, &zombie->zombie_brt_link); //Add to dead list.
toku_list_push(&h->zombie_brts, &zombie->zombie_brt_link); //Add to dead list.
toku_brtheader_unlock(zombie->h);
if (replacement == NULL) r = 0; //Just delay close
else {
......@@ -3382,8 +3382,8 @@ toku_brt_db_delay_closed (BRT zombie, DB* db, int (*close_db)(DB*, u_int32_t), u
int toku_close_brt_lsn (BRT brt, TOKULOGGER logger, char **error_string, BOOL oplsn_valid, LSN oplsn) {
assert(toku_omt_size(brt->txns)==0);
int r;
while (!list_empty(&brt->cursors)) {
BRT_CURSOR c = list_struct(list_pop(&brt->cursors), struct brt_cursor, cursors_link);
while (!toku_list_empty(&brt->cursors)) {
BRT_CURSOR c = toku_list_struct(toku_list_pop(&brt->cursors), struct brt_cursor, cursors_link);
r=toku_brt_cursor_close(c);
if (r!=0) return r;
}
......@@ -3417,9 +3417,9 @@ int toku_brt_create(BRT *brt_ptr) {
if (brt == 0)
return ENOMEM;
memset(brt, 0, sizeof *brt);
list_init(&brt->live_brt_link);
list_init(&brt->zombie_brt_link);
list_init(&brt->cursors);
toku_list_init(&brt->live_brt_link);
toku_list_init(&brt->zombie_brt_link);
toku_list_init(&brt->cursors);
brt->flags = 0;
brt->did_set_flags = FALSE;
brt->did_set_descriptor = FALSE;
......@@ -3529,7 +3529,7 @@ int toku_brt_cursor (BRT brt, BRT_CURSOR *cursorptr, TOKULOGGER logger) {
cursor->current_in_omt = FALSE;
cursor->prefetching = FALSE;
cursor->oldest_living_xid = toku_logger_get_oldest_living_xid(logger);
list_push(&brt->cursors, &cursor->cursors_link);
toku_list_push(&brt->cursors, &cursor->cursors_link);
int r = toku_omt_cursor_create(&cursor->omtcursor);
assert(r==0);
toku_omt_cursor_set_invalidate_callback(cursor->omtcursor,
......@@ -3557,7 +3557,7 @@ brt_cursor_invalidate_no_callback(BRT_CURSOR brtcursor) {
int toku_brt_cursor_close(BRT_CURSOR cursor) {
brt_cursor_invalidate_no_callback(cursor);
brt_cursor_cleanup_dbts(cursor);
list_remove(&cursor->cursors_link);
toku_list_remove(&cursor->cursors_link);
toku_omt_cursor_destroy(&cursor->omtcursor);
toku_free_n(cursor, sizeof *cursor);
return 0;
......@@ -4607,7 +4607,7 @@ BOOL toku_brt_cursor_uninitialized(BRT_CURSOR c) {
int toku_brt_get_cursor_count (BRT brt) {
int n = 0;
struct list *list;
struct toku_list *list;
for (list = brt->cursors.next; list != &brt->cursors; list = list->next)
n += 1;
return n;
......
......@@ -38,7 +38,7 @@
#include "cachetable.h"
#include "rwlock.h"
#include "fifo.h"
#include "list.h"
#include "toku_list.h"
#include "key.h"
#include "kv-pair.h"
#include "leafentry.h"
......
......@@ -8,7 +8,7 @@
#include "brt-internal.h"
#include "log.h"
#include "toku_assert.h"
#include "list.h"
#include "toku_list.h"
#include "memarena.h"
#include "logfilemgr.h"
#include <stdio.h>
......
......@@ -110,7 +110,7 @@
// changing the OMT's shape, one can simply step through the list
// invalidating all the OMTCURSORs.
//
// The list of OMTCURSORs should use the list.h abstraction. If it's
// The list of OMTCURSORs should use the toku_list.h abstraction. If it's
// not clear how to use it, Rich can explain it.
......
#include "list.h"
#include "toku_list.h"
#include "toku_assert.h"
#include "test.h"
......@@ -7,7 +7,7 @@
#include <stdlib.h>
struct testlist {
struct list next;
struct toku_list next;
int tag;
};
......@@ -17,128 +17,128 @@ static void testlist_init (struct testlist *tl, int tag) {
static void test_push_pop (int n) {
int i;
struct list head;
struct toku_list head;
list_init(&head);
toku_list_init(&head);
for (i=0; i<n; i++) {
struct testlist *tl = (struct testlist *) toku_malloc(sizeof *tl);
assert(tl);
testlist_init(tl, i);
list_push(&head, &tl->next);
assert(!list_empty(&head));
toku_list_push(&head, &tl->next);
assert(!toku_list_empty(&head));
}
for (i=n-1; i>=0; i--) {
struct list *list;
struct toku_list *list;
struct testlist *tl;
list = list_head(&head);
tl = list_struct(list, struct testlist, next);
list = toku_list_head(&head);
tl = toku_list_struct(list, struct testlist, next);
assert(tl->tag == 0);
list = list_tail(&head);
tl = list_struct(list, struct testlist, next);
list = toku_list_tail(&head);
tl = toku_list_struct(list, struct testlist, next);
assert(tl->tag == i);
list = list_pop(&head);
tl = list_struct(list, struct testlist, next);
list = toku_list_pop(&head);
tl = toku_list_struct(list, struct testlist, next);
assert(tl->tag == i);
toku_free(tl);
}
assert(list_empty(&head));
assert(toku_list_empty(&head));
}
static void test_push_pop_head (int n) {
int i;
struct list head;
struct toku_list head;
list_init(&head);
toku_list_init(&head);
for (i=0; i<n; i++) {
struct testlist *tl = (struct testlist *) toku_malloc(sizeof *tl);
assert(tl);
testlist_init(tl, i);
list_push(&head, &tl->next);
assert(!list_empty(&head));
toku_list_push(&head, &tl->next);
assert(!toku_list_empty(&head));
}
for (i=0; i<n; i++) {
struct list *list;
struct toku_list *list;
struct testlist *tl;
list = list_head(&head);
tl = list_struct(list, struct testlist, next);
list = toku_list_head(&head);
tl = toku_list_struct(list, struct testlist, next);
assert(tl->tag == i);
list = list_tail(&head);
tl = list_struct(list, struct testlist, next);
list = toku_list_tail(&head);
tl = toku_list_struct(list, struct testlist, next);
assert(tl->tag == n-1);
list = list_pop_head(&head);
tl = list_struct(list, struct testlist, next);
list = toku_list_pop_head(&head);
tl = toku_list_struct(list, struct testlist, next);
assert(tl->tag == i);
toku_free(tl);
}
assert(list_empty(&head));
assert(toku_list_empty(&head));
}
static void test_push_head_pop (int n) {
int i;
struct list head;
struct toku_list head;
list_init(&head);
toku_list_init(&head);
for (i=0; i<n; i++) {
struct testlist *tl = (struct testlist *) toku_malloc(sizeof *tl);
assert(tl);
testlist_init(tl, i);
list_push_head(&head, &tl->next);
assert(!list_empty(&head));
toku_list_push_head(&head, &tl->next);
assert(!toku_list_empty(&head));
}
for (i=0; i<n; i++) {
struct list *list;
struct toku_list *list;
struct testlist *tl;
list = list_head(&head);
tl = list_struct(list, struct testlist, next);
list = toku_list_head(&head);
tl = toku_list_struct(list, struct testlist, next);
assert(tl->tag == n-1);
list = list_tail(&head);
tl = list_struct(list, struct testlist, next);
list = toku_list_tail(&head);
tl = toku_list_struct(list, struct testlist, next);
assert(tl->tag == i);
list = list_pop(&head);
tl = list_struct(list, struct testlist, next);
list = toku_list_pop(&head);
tl = toku_list_struct(list, struct testlist, next);
assert(tl->tag == i);
toku_free(tl);
}
assert(list_empty(&head));
assert(toku_list_empty(&head));
}
#if 0
// cant move an empty list
static void test_move_empty (void) {
struct list h1, h2;
struct toku_list h1, h2;
list_init(&h1);
list_init(&h2);
list_move(&h1, &h2);
assert(list_empty(&h2));
assert(list_empty(&h1));
toku_list_init(&h1);
toku_list_init(&h2);
toku_list_move(&h1, &h2);
assert(toku_list_empty(&h2));
assert(toku_list_empty(&h1));
}
#endif
static void test_move (int n) {
struct list h1, h2;
struct toku_list h1, h2;
int i;
list_init(&h1);
list_init(&h2);
toku_list_init(&h1);
toku_list_init(&h2);
for (i=0; i<n; i++) {
struct testlist *tl = (struct testlist *) toku_malloc(sizeof *tl);
assert(tl);
testlist_init(tl, i);
list_push(&h2, &tl->next);
toku_list_push(&h2, &tl->next);
}
list_move(&h1, &h2);
assert(!list_empty(&h1));
assert(list_empty(&h2));
toku_list_move(&h1, &h2);
assert(!toku_list_empty(&h1));
assert(toku_list_empty(&h2));
i = 0;
while (!list_empty(&h1)) {
struct list *list = list_pop_head(&h1);
struct testlist *tl = list_struct(list, struct testlist, next);
while (!toku_list_empty(&h1)) {
struct toku_list *list = toku_list_pop_head(&h1);
struct testlist *tl = toku_list_struct(list, struct testlist, next);
assert(tl->tag == i);
toku_free(tl);
i += 1;
......
......@@ -7,7 +7,7 @@
#include <db.h>
#include "../newbrt/brttypes.h"
#include "../newbrt/brt.h"
#include "../newbrt/list.h"
#include "toku_list.h"
#include "./lock_tree/locktree.h"
#include "./lock_tree/db_id.h"
#include "./lock_tree/idlth.h"
......@@ -29,7 +29,7 @@ struct __toku_db_internal {
BOOL key_compare_was_set; // true if a comparison function was provided before call to db->open() (if false, use environment's comparison function)
BOOL val_compare_was_set;
char *dname; // dname is constant for this handle (handle must be closed before file is renamed)
struct list dbs_that_must_close_before_abort;
struct toku_list dbs_that_must_close_before_abort;
};
#if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 1
......@@ -59,7 +59,7 @@ struct __toku_db_env_internal {
CACHETABLE cachetable;
TOKULOGGER logger;
toku_ltm* ltm;
struct list open_txns;
struct toku_list open_txns;
DB *directory; //Maps dnames to inames
DB *persistent_environment; //Stores environment settings, can be used for upgrade
OMT open_dbs; //Stores open db handles, sorted first by dname and then by numerical value of pointer to the db (arbitrarily assigned memory location)
......
......@@ -115,17 +115,17 @@ static inline int env_opened(DB_ENV *env) {
}
static void env_init_open_txn(DB_ENV *env) {
list_init(&env->i->open_txns);
toku_list_init(&env->i->open_txns);
}
// add a txn to the list of open txn's
static void env_add_open_txn(DB_ENV *env, DB_TXN *txn) {
list_push(&env->i->open_txns, (struct list *) (void *) &txn->open_txns);
toku_list_push(&env->i->open_txns, (struct toku_list *) (void *) &txn->open_txns);
}
// remove a txn from the list of open txn's
static void env_remove_open_txn(DB_ENV *UU(env), DB_TXN *txn) {
list_remove((struct list *) (void *) &txn->open_txns);
toku_list_remove((struct toku_list *) (void *) &txn->open_txns);
}
static int toku_txn_abort(DB_TXN * txn);
......@@ -582,7 +582,7 @@ static int toku_env_close(DB_ENV * env, u_int32_t flags) {
// if panicked, or if any open transactions, or any open dbs, then do nothing.
if (toku_env_is_panicked(env)) goto panic_and_quit_early;
if (!list_empty(&env->i->open_txns)) {
if (!toku_list_empty(&env->i->open_txns)) {
r = toku_ydb_do_error(env, EINVAL, "Cannot close environment due to open transactions\n");
goto panic_and_quit_early;
}
......@@ -1357,15 +1357,15 @@ static int toku_txn_commit(DB_TXN * txn, u_int32_t flags) {
//Promote list to parent (dbs that must close before abort)
if (txn->parent) {
//Combine lists.
while (!list_empty(&db_txn_struct_i(txn)->dbs_that_must_close_before_abort)) {
struct list *list = list_pop(&db_txn_struct_i(txn)->dbs_that_must_close_before_abort);
list_push(&db_txn_struct_i(txn->parent)->dbs_that_must_close_before_abort, list);
while (!toku_list_empty(&db_txn_struct_i(txn)->dbs_that_must_close_before_abort)) {
struct toku_list *list = toku_list_pop(&db_txn_struct_i(txn)->dbs_that_must_close_before_abort);
toku_list_push(&db_txn_struct_i(txn->parent)->dbs_that_must_close_before_abort, list);
}
}
else {
//Empty the list
while (!list_empty(&db_txn_struct_i(txn)->dbs_that_must_close_before_abort)) {
list_pop(&db_txn_struct_i(txn)->dbs_that_must_close_before_abort);
while (!toku_list_empty(&db_txn_struct_i(txn)->dbs_that_must_close_before_abort)) {
toku_list_pop(&db_txn_struct_i(txn)->dbs_that_must_close_before_abort);
}
}
......@@ -1408,7 +1408,7 @@ static int toku_txn_abort(DB_TXN * txn) {
env_remove_open_txn(txn->mgrp, txn);
//All dbs that must close before abort, must now be closed
assert(list_empty(&db_txn_struct_i(txn)->dbs_that_must_close_before_abort));
assert(toku_list_empty(&db_txn_struct_i(txn)->dbs_that_must_close_before_abort));
//int r = toku_logger_abort(db_txn_struct_i(txn)->tokutxn, ydb_yield, NULL);
int r = toku_txn_abort_txn(db_txn_struct_i(txn)->tokutxn, ydb_yield, NULL);
......@@ -1502,7 +1502,7 @@ static int toku_txn_begin(DB_ENV *env, DB_TXN * stxn, DB_TXN ** txn, u_int32_t f
#endif
memset(db_txn_struct_i(result), 0, sizeof *db_txn_struct_i(result));
db_txn_struct_i(result)->flags = txn_flags;
list_init(&db_txn_struct_i(result)->dbs_that_must_close_before_abort);
toku_list_init(&db_txn_struct_i(result)->dbs_that_must_close_before_abort);
int r;
if (env->i->open_flags & DB_INIT_LOCK && !stxn) {
......@@ -1658,8 +1658,8 @@ static int toku_db_close(DB * db, u_int32_t flags) {
if (db_opened(db) && db->i->dname) // internal (non-user) dictionary has no dname
env_note_db_closed(db->dbenv, db); // tell env that this db is no longer in use by the user of this api (user-closed, may still be in use by fractal tree internals)
//Remove from transaction's list of 'must close' if necessary.
if (!list_empty(&db->i->dbs_that_must_close_before_abort))
list_remove(&db->i->dbs_that_must_close_before_abort);
if (!toku_list_empty(&db->i->dbs_that_must_close_before_abort))
toku_list_remove(&db->i->dbs_that_must_close_before_abort);
int r = toku_brt_db_delay_closed(db->i->brt, db, db_close_before_brt, flags);
return r;
......@@ -3680,7 +3680,7 @@ db_open_iname(DB * db, DB_TXN * txn, const char *iname, u_int32_t flags, int mod
//Add to transaction's list of 'must close' if necessary.
if (txn) {
//Do last so we don't have to undo.
list_push(&db_txn_struct_i(txn)->dbs_that_must_close_before_abort,
toku_list_push(&db_txn_struct_i(txn)->dbs_that_must_close_before_abort,
&db->i->dbs_that_must_close_before_abort);
}
......@@ -4538,7 +4538,7 @@ static int toku_db_create(DB ** db, DB_ENV * env, u_int32_t flags) {
result->i->open_flags = 0;
result->i->open_mode = 0;
result->i->brt = 0;
list_init(&result->i->dbs_that_must_close_before_abort);
toku_list_init(&result->i->dbs_that_must_close_before_abort);
r = toku_brt_create(&result->i->brt);
if (r != 0) {
toku_free(result->i);
......
......@@ -8,79 +8,79 @@
//TODO: #1378 This is not threadsafe. Make sure when splitting locks
//that we protect these calls.
// This list is intended to be embedded in other data structures.
struct list {
struct list *next, *prev;
// This toku_list is intended to be embedded in other data structures.
struct toku_list {
struct toku_list *next, *prev;
};
static inline void list_init(struct list *head) {
static inline void toku_list_init(struct toku_list *head) {
head->next = head->prev = head;
}
static inline int list_empty(struct list *head) {
static inline int toku_list_empty(struct toku_list *head) {
return head->next == head;
}
static inline struct list *list_head(struct list *head) {
static inline struct toku_list *toku_list_head(struct toku_list *head) {
return head->next;
}
static inline struct list *list_tail(struct list *head) {
static inline struct toku_list *toku_list_tail(struct toku_list *head) {
return head->prev;
}
static inline void list_insert_between(struct list *a, struct list *list, struct list *b) {
static inline void toku_list_insert_between(struct toku_list *a, struct toku_list *toku_list, struct toku_list *b) {
list->next = a->next;
list->prev = b->prev;
a->next = b->prev = list;
toku_list->next = a->next;
toku_list->prev = b->prev;
a->next = b->prev = toku_list;
}
static inline void list_push(struct list *head, struct list *list) {
list_insert_between(head->prev, list, head);
static inline void toku_list_push(struct toku_list *head, struct toku_list *toku_list) {
toku_list_insert_between(head->prev, toku_list, head);
}
static inline void list_push_head(struct list *head, struct list *list) {
list_insert_between(head, list, head->next);
static inline void toku_list_push_head(struct toku_list *head, struct toku_list *toku_list) {
toku_list_insert_between(head, toku_list, head->next);
}
static inline void list_remove(struct list *list) {
struct list *prev = list->prev;
struct list *next = list->next;
static inline void toku_list_remove(struct toku_list *toku_list) {
struct toku_list *prev = toku_list->prev;
struct toku_list *next = toku_list->next;
next->prev = prev;
prev->next = next;
list_init(list); // Set the list element to be empty
toku_list_init(toku_list); // Set the toku_list element to be empty
}
static inline struct list *list_pop(struct list *head) {
struct list *list = head->prev;
list_remove(list);
return list;
static inline struct toku_list *toku_list_pop(struct toku_list *head) {
struct toku_list *toku_list = head->prev;
toku_list_remove(toku_list);
return toku_list;
}
static inline struct list *list_pop_head(struct list *head) {
struct list *list = head->next;
list_remove(list);
return list;
static inline struct toku_list *toku_list_pop_head(struct toku_list *head) {
struct toku_list *toku_list = head->next;
toku_list_remove(toku_list);
return toku_list;
}
static inline void list_move(struct list *newhead, struct list *oldhead) {
struct list *first = oldhead->next;
struct list *last = oldhead->prev;
// assert(!list_empty(oldhead));
static inline void toku_list_move(struct toku_list *newhead, struct toku_list *oldhead) {
struct toku_list *first = oldhead->next;
struct toku_list *last = oldhead->prev;
// assert(!toku_list_empty(oldhead));
newhead->next = first;
newhead->prev = last;
last->next = first->prev = newhead;
list_init(oldhead);
toku_list_init(oldhead);
}
// Note: Need the extra level of parens in these macros so that
// list_struct(h, foo, b)->zot
// toku_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.
#if defined(__GNUC__) && __GNUC__ >= 4
#define list_struct(p, t, f) ((t*)((char*)(p) - __builtin_offsetof(t, f)))
#define toku_list_struct(p, t, f) ((t*)((char*)(p) - __builtin_offsetof(t, f)))
#else
#define list_struct(p, t, f) ((t*)((char*)(p) - ((char*)&((t*)0)->f)))
#define toku_list_struct(p, t, f) ((t*)((char*)(p) - ((char*)&((t*)0)->f)))
#endif
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment