1 | /***************************************************************************** |
2 | |
3 | Copyright (c) 2006, 2016, Oracle and/or its affiliates. All Rights Reserved. |
4 | |
5 | This program is free software; you can redistribute it and/or modify it under |
6 | the terms of the GNU General Public License as published by the Free Software |
7 | Foundation; version 2 of the License. |
8 | |
9 | This program is distributed in the hope that it will be useful, but WITHOUT |
10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU General Public License along with |
14 | this program; if not, write to the Free Software Foundation, Inc., |
15 | 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
16 | |
17 | *****************************************************************************/ |
18 | |
19 | /*******************************************************************//** |
20 | @file ut/ut0list.cc |
21 | A double-linked list |
22 | |
23 | Created 4/26/2006 Osku Salerma |
24 | ************************************************************************/ |
25 | |
26 | #include "ut0list.h" |
27 | |
28 | /****************************************************************//** |
29 | Create a new list. |
30 | @return list */ |
31 | ib_list_t* |
32 | ib_list_create(void) |
33 | /*=================*/ |
34 | { |
35 | return(static_cast<ib_list_t*>(ut_zalloc_nokey(sizeof(ib_list_t)))); |
36 | } |
37 | |
38 | /****************************************************************//** |
39 | Free a list. */ |
40 | void |
41 | ib_list_free( |
42 | /*=========*/ |
43 | ib_list_t* list) /*!< in: list */ |
44 | { |
45 | /* We don't check that the list is empty because it's entirely valid |
46 | to e.g. have all the nodes allocated from a single heap that is then |
47 | freed after the list itself is freed. */ |
48 | |
49 | ut_free(list); |
50 | } |
51 | |
52 | /****************************************************************//** |
53 | Add the data after the indicated node. |
54 | @return new list node */ |
55 | static |
56 | ib_list_node_t* |
57 | ib_list_add_after( |
58 | /*==============*/ |
59 | ib_list_t* list, /*!< in: list */ |
60 | ib_list_node_t* prev_node, /*!< in: node preceding new node (can |
61 | be NULL) */ |
62 | void* data, /*!< in: data */ |
63 | mem_heap_t* heap) /*!< in: memory heap to use */ |
64 | { |
65 | ib_list_node_t* node; |
66 | |
67 | node = static_cast<ib_list_node_t*>( |
68 | mem_heap_alloc(heap, sizeof(*node))); |
69 | |
70 | node->data = data; |
71 | |
72 | if (!list->first) { |
73 | /* Empty list. */ |
74 | |
75 | ut_a(!prev_node); |
76 | |
77 | node->prev = NULL; |
78 | node->next = NULL; |
79 | |
80 | list->first = node; |
81 | list->last = node; |
82 | } else if (!prev_node) { |
83 | /* Start of list. */ |
84 | |
85 | node->prev = NULL; |
86 | node->next = list->first; |
87 | |
88 | list->first->prev = node; |
89 | |
90 | list->first = node; |
91 | } else { |
92 | /* Middle or end of list. */ |
93 | |
94 | node->prev = prev_node; |
95 | node->next = prev_node->next; |
96 | |
97 | prev_node->next = node; |
98 | |
99 | if (node->next) { |
100 | node->next->prev = node; |
101 | } else { |
102 | list->last = node; |
103 | } |
104 | } |
105 | |
106 | return(node); |
107 | } |
108 | |
109 | /****************************************************************//** |
110 | Add the data to the end of the list. |
111 | @return new list node */ |
112 | ib_list_node_t* |
113 | ib_list_add_last( |
114 | /*=============*/ |
115 | ib_list_t* list, /*!< in: list */ |
116 | void* data, /*!< in: data */ |
117 | mem_heap_t* heap) /*!< in: memory heap to use */ |
118 | { |
119 | return(ib_list_add_after(list, ib_list_get_last(list), data, heap)); |
120 | } |
121 | |
122 | /****************************************************************//** |
123 | Remove the node from the list. */ |
124 | void |
125 | ib_list_remove( |
126 | /*===========*/ |
127 | ib_list_t* list, /*!< in: list */ |
128 | ib_list_node_t* node) /*!< in: node to remove */ |
129 | { |
130 | if (node->prev) { |
131 | node->prev->next = node->next; |
132 | } else { |
133 | /* First item in list. */ |
134 | |
135 | ut_ad(list->first == node); |
136 | |
137 | list->first = node->next; |
138 | } |
139 | |
140 | if (node->next) { |
141 | node->next->prev = node->prev; |
142 | } else { |
143 | /* Last item in list. */ |
144 | |
145 | ut_ad(list->last == node); |
146 | |
147 | list->last = node->prev; |
148 | } |
149 | |
150 | node->prev = node->next = NULL; |
151 | } |
152 | |