mirror of
https://github.com/MariaDB/server.git
synced 2025-01-27 17:33:44 +01:00
Add a normal linked-list implementation.
This commit is contained in:
parent
a34246f01c
commit
3a1b90f1cc
6 changed files with 307 additions and 4 deletions
|
@ -76,8 +76,7 @@ EXTRA_DIST = include/btr0btr.h include/btr0btr.ic include/btr0cur.h include/btr
|
|||
include/univ.i include/usr0sess.h include/usr0sess.ic include/usr0types.h \
|
||||
include/ut0byte.h include/ut0byte.ic include/ut0dbg.h include/ut0lst.h \
|
||||
include/ut0mem.h include/ut0mem.ic include/ut0rnd.h include/ut0rnd.ic \
|
||||
include/ut0sort.h include/ut0ut.h include/ut0ut.ic include/ut0vec.h include/ut0vec.ic \
|
||||
cmakelists.txt
|
||||
include/ut0sort.h include/ut0ut.h include/ut0ut.ic include/ut0vec.h include/ut0vec.ic include/ut0list.h include/ut0list.ic cmakelists.txt
|
||||
|
||||
# Don't update the files from bitkeeper
|
||||
%::SCCS/s.%
|
||||
|
|
|
@ -32,4 +32,4 @@ ADD_LIBRARY(innobase btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
|
|||
thr/thr0loc.c
|
||||
trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c
|
||||
usr/usr0sess.c
|
||||
ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c)
|
||||
ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c ut/ut0list.c)
|
||||
|
|
134
include/ut0list.h
Normal file
134
include/ut0list.h
Normal file
|
@ -0,0 +1,134 @@
|
|||
/***********************************************************************
|
||||
A double-linked list. This differs from the one in ut0lst.h in that in this
|
||||
one, each list node contains a pointer to the data, whereas the one in
|
||||
ut0lst.h uses a strategy where the list pointers are embedded in the data
|
||||
items themselves.
|
||||
|
||||
Use this one when you need to store arbitrary data in the list where you
|
||||
can't embed the list pointers in the data, if a data item needs to be
|
||||
stored in multiple lists, etc.
|
||||
|
||||
Note about the memory management: ib_list_t is a fixed-size struct whose
|
||||
allocation/deallocation is done through ib_list_create/ib_list_free, but the
|
||||
memory for the list nodes is allocated through a user-given memory heap,
|
||||
which can either be the same for all nodes or vary per node. Most users will
|
||||
probably want to create a memory heap to store the item-specific data, and
|
||||
pass in this same heap to the list node creation functions, thus
|
||||
automatically freeing the list node when the item's heap is freed.
|
||||
|
||||
************************************************************************/
|
||||
|
||||
|
||||
#ifndef IB_LIST_H
|
||||
#define IB_LIST_H
|
||||
|
||||
#include "mem0mem.h"
|
||||
|
||||
typedef struct ib_list_struct ib_list_t;
|
||||
typedef struct ib_list_node_struct ib_list_node_t;
|
||||
typedef struct ib_list_helper_struct ib_list_helper_t;
|
||||
|
||||
/********************************************************************
|
||||
Create a new list. */
|
||||
|
||||
ib_list_t*
|
||||
ib_list_create(void);
|
||||
/*=================*/
|
||||
/* out: list */
|
||||
|
||||
/********************************************************************
|
||||
Free a list. */
|
||||
|
||||
void
|
||||
ib_list_free(
|
||||
/*=========*/
|
||||
ib_list_t* list); /* in: list */
|
||||
|
||||
/********************************************************************
|
||||
Add the data to the start of the list. */
|
||||
|
||||
ib_list_node_t*
|
||||
ib_list_add_first(
|
||||
/*==============*/
|
||||
/* out: new list node*/
|
||||
ib_list_t* list, /* in: list */
|
||||
void* data, /* in: data */
|
||||
mem_heap_t* heap); /* in: memory heap to use */
|
||||
|
||||
/********************************************************************
|
||||
Add the data to the end of the list. */
|
||||
|
||||
ib_list_node_t*
|
||||
ib_list_add_last(
|
||||
/*=============*/
|
||||
/* out: new list node*/
|
||||
ib_list_t* list, /* in: list */
|
||||
void* data, /* in: data */
|
||||
mem_heap_t* heap); /* in: memory heap to use */
|
||||
|
||||
/********************************************************************
|
||||
Add the data after the indicated node. */
|
||||
|
||||
ib_list_node_t*
|
||||
ib_list_add_after(
|
||||
/*==============*/
|
||||
/* out: new list node*/
|
||||
ib_list_t* list, /* in: list */
|
||||
ib_list_node_t* prev_node, /* in: node preceding new node (can
|
||||
be NULL) */
|
||||
void* data, /* in: data */
|
||||
mem_heap_t* heap); /* in: memory heap to use */
|
||||
|
||||
/********************************************************************
|
||||
Remove the node from the list. */
|
||||
|
||||
void
|
||||
ib_list_remove(
|
||||
/*===========*/
|
||||
ib_list_t* list, /* in: list */
|
||||
ib_list_node_t* node); /* in: node to remove */
|
||||
|
||||
/********************************************************************
|
||||
Get the first node in the list. */
|
||||
UNIV_INLINE
|
||||
ib_list_node_t*
|
||||
ib_list_get_first(
|
||||
/*==============*/
|
||||
/* out: first node, or NULL */
|
||||
ib_list_t* list); /* in: list */
|
||||
|
||||
/********************************************************************
|
||||
Get the last node in the list. */
|
||||
UNIV_INLINE
|
||||
ib_list_node_t*
|
||||
ib_list_get_last(
|
||||
/*=============*/
|
||||
/* out: last node, or NULL */
|
||||
ib_list_t* list); /* in: list */
|
||||
|
||||
/* List. */
|
||||
struct ib_list_struct {
|
||||
ib_list_node_t* first; /* first node */
|
||||
ib_list_node_t* last; /* last node */
|
||||
};
|
||||
|
||||
/* A list node. */
|
||||
struct ib_list_node_struct {
|
||||
ib_list_node_t* prev; /* previous node */
|
||||
ib_list_node_t* next; /* next node */
|
||||
void* data; /* user data */
|
||||
};
|
||||
|
||||
/* Quite often, the only additional piece of data you need is the per-item
|
||||
memory heap, so we have this generic struct available to use in those
|
||||
cases. */
|
||||
struct ib_list_helper_struct {
|
||||
mem_heap_t* heap; /* memory heap */
|
||||
void* data; /* user data */
|
||||
};
|
||||
|
||||
#ifndef UNIV_NONINL
|
||||
#include "ut0list.ic"
|
||||
#endif
|
||||
|
||||
#endif
|
23
include/ut0list.ic
Normal file
23
include/ut0list.ic
Normal file
|
@ -0,0 +1,23 @@
|
|||
/********************************************************************
|
||||
Get the first node in the list. */
|
||||
UNIV_INLINE
|
||||
ib_list_node_t*
|
||||
ib_list_get_first(
|
||||
/*==============*/
|
||||
/* out: first node, or NULL */
|
||||
ib_list_t* list) /* in: list */
|
||||
{
|
||||
return(list->first);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Get the last node in the list. */
|
||||
UNIV_INLINE
|
||||
ib_list_node_t*
|
||||
ib_list_get_last(
|
||||
/*=============*/
|
||||
/* out: last node, or NULL */
|
||||
ib_list_t* list) /* in: list */
|
||||
{
|
||||
return(list->last);
|
||||
}
|
|
@ -19,6 +19,6 @@ include ../include/Makefile.i
|
|||
|
||||
noinst_LIBRARIES = libut.a
|
||||
|
||||
libut_a_SOURCES = ut0byte.c ut0dbg.c ut0mem.c ut0rnd.c ut0ut.c ut0vec.c
|
||||
libut_a_SOURCES = ut0byte.c ut0dbg.c ut0mem.c ut0rnd.c ut0ut.c ut0vec.c ut0list.c
|
||||
|
||||
EXTRA_PROGRAMS =
|
||||
|
|
147
ut/ut0list.c
Normal file
147
ut/ut0list.c
Normal file
|
@ -0,0 +1,147 @@
|
|||
#include "ut0list.h"
|
||||
#ifdef UNIV_NONINL
|
||||
#include "ut0list.ic"
|
||||
#endif
|
||||
|
||||
/********************************************************************
|
||||
Create a new list. */
|
||||
|
||||
ib_list_t*
|
||||
ib_list_create(void)
|
||||
/*=================*/
|
||||
/* out: list */
|
||||
{
|
||||
ib_list_t* list = mem_alloc(sizeof(ib_list_t));
|
||||
|
||||
list->first = NULL;
|
||||
list->last = NULL;
|
||||
|
||||
return(list);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Free a list. */
|
||||
|
||||
void
|
||||
ib_list_free(
|
||||
/*=========*/
|
||||
ib_list_t* list) /* in: list */
|
||||
{
|
||||
/* We don't check that the list is empty because it's entirely valid
|
||||
to e.g. have all the nodes allocated from a single heap that is then
|
||||
freed after the list itself is freed. */
|
||||
|
||||
mem_free(list);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Add the data to the start of the list. */
|
||||
|
||||
ib_list_node_t*
|
||||
ib_list_add_first(
|
||||
/*==============*/
|
||||
/* out: new list node*/
|
||||
ib_list_t* list, /* in: list */
|
||||
void* data, /* in: data */
|
||||
mem_heap_t* heap) /* in: memory heap to use */
|
||||
{
|
||||
return(ib_list_add_after(list, ib_list_get_first(list), data, heap));
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Add the data to the end of the list. */
|
||||
|
||||
ib_list_node_t*
|
||||
ib_list_add_last(
|
||||
/*=============*/
|
||||
/* out: new list node*/
|
||||
ib_list_t* list, /* in: list */
|
||||
void* data, /* in: data */
|
||||
mem_heap_t* heap) /* in: memory heap to use */
|
||||
{
|
||||
return(ib_list_add_after(list, ib_list_get_last(list), data, heap));
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Add the data after the indicated node. */
|
||||
|
||||
ib_list_node_t*
|
||||
ib_list_add_after(
|
||||
/*==============*/
|
||||
/* out: new list node*/
|
||||
ib_list_t* list, /* in: list */
|
||||
ib_list_node_t* prev_node, /* in: node preceding new node (can
|
||||
be NULL) */
|
||||
void* data, /* in: data */
|
||||
mem_heap_t* heap) /* in: memory heap to use */
|
||||
{
|
||||
ib_list_node_t* node = mem_heap_alloc(heap, sizeof(ib_list_node_t));
|
||||
|
||||
node->data = data;
|
||||
|
||||
if (!list->first) {
|
||||
/* Empty list. */
|
||||
|
||||
ut_a(!prev_node);
|
||||
|
||||
node->prev = NULL;
|
||||
node->next = NULL;
|
||||
|
||||
list->first = node;
|
||||
list->last = node;
|
||||
} else if (!prev_node) {
|
||||
/* Start of list. */
|
||||
|
||||
node->prev = NULL;
|
||||
node->next = list->first;
|
||||
|
||||
list->first->prev = node;
|
||||
|
||||
list->first = node;
|
||||
} else {
|
||||
/* Middle or end of list. */
|
||||
|
||||
node->prev = prev_node;
|
||||
node->next = prev_node->next;
|
||||
|
||||
prev_node->next = node;
|
||||
|
||||
if (node->next) {
|
||||
node->next->prev = node;
|
||||
} else {
|
||||
list->last = node;
|
||||
}
|
||||
}
|
||||
|
||||
return(node);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Remove the node from the list. */
|
||||
|
||||
void
|
||||
ib_list_remove(
|
||||
/*===========*/
|
||||
ib_list_t* list, /* in: list */
|
||||
ib_list_node_t* node) /* in: node to remove */
|
||||
{
|
||||
if (node->prev) {
|
||||
node->prev->next = node->next;
|
||||
} else {
|
||||
/* First item in list. */
|
||||
|
||||
ut_ad(list->first == node);
|
||||
|
||||
list->first = node->next;
|
||||
}
|
||||
|
||||
if (node->next) {
|
||||
node->next->prev = node->prev;
|
||||
} else {
|
||||
/* Last item in list. */
|
||||
|
||||
ut_ad(list->last == node);
|
||||
|
||||
list->last = node->prev;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue