CUBRID Engine  latest
broker_list.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 
20 /*
21  * link_list.c - This module contains operations for singly linked list.
22  * The list header is a recent appended node.
23  */
24 
25 #ident "$Id$"
26 
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 
31 
32 #include "cas_common.h"
33 #include "broker_list.h"
34 
35 
36 static T_LIST *delete_node (T_LIST * head, T_LIST * del_node, void (*node_dealloc) (T_LIST *));
37 static int true_func (void *key, void *value);
38 static void swap_node (T_LIST * node1, T_LIST * node2);
39 
40 
41 /*
42  * name: link_list_add - append a node to a designated list
43  *
44  * arguments: cur_head - the list header(IN/OUT)
45  * add_key - the key of the node
46  * add_val - the value of the node
47  * assign_func - a function for assigning key and value
48  *
49  * returns/side-effects:
50  * 0 : success
51  * < 0 : error code
52  *
53  * description: add new node to the list.
54  * created node is new list header.
55  *
56  * NOTE:
57  * Since the type of 'key' and 'value' of the node is 'void*',
58  * it is only possible to assign value which size is same as void ptr.
59  * For example, if string is copied to 'key', you must allocate memory
60  * in assigning function.
61  */
62 int
63 link_list_add (T_LIST ** cur_head, void *add_key, void *add_val, int (*assign_func) (T_LIST *, void *, void *))
64 {
65  T_LIST *tmp;
66  T_LIST *new_node;
67  int error;
68  T_LIST *head = *cur_head;
69 
70  tmp = (T_LIST *) malloc (sizeof (T_LIST));
71  if (tmp == NULL)
72  return -1;
73 
74  if (head == NULL)
75  {
76  new_node = tmp;
77  }
78  else
79  {
80  *tmp = *head;
81  new_node = head;
82  }
83 
84  error = (*assign_func) (new_node, add_key, add_val);
85  if (error < 0)
86  {
87  FREE_MEM (tmp);
88  return error;
89  }
90  new_node->next = tmp;
91 
92  *cur_head = tmp;
93  return 0;
94 }
95 
96 /*
97  * name: link_list_find
98  *
99  * arguments: head - list header
100  * key - key value for list search
101  * cmp_func - comparing function
102  *
103  * returns/side-effects:
104  * node ptr if exist.
105  * NULL ptr otherwise.
106  *
107  * description: search list with key value.
108  *
109  * NOTE:
110  */
111 T_LIST *
112 link_list_find (T_LIST * head, void *key, void *val, int (*key_cmp_func) (void *, void *),
113  int (*val_cmp_func) (void *, void *))
114 {
115  T_LIST *tmp;
116 
117  if (head == NULL)
118  return NULL;
119 
120  if (key_cmp_func == NULL)
121  key_cmp_func = true_func;
122  if (val_cmp_func == NULL)
123  val_cmp_func = true_func;
124 
125  tmp = head;
126  do
127  {
128  if ((*key_cmp_func) (tmp->key, key) && (*val_cmp_func) (tmp->value, val))
129  return tmp;
130  tmp = tmp->next;
131  }
132  while (tmp != head);
133 
134  return NULL; /* not found */
135 }
136 
137 /*
138  * name: link_list_node_delete - delete a node
139  *
140  * arguments: head - list header
141  * key - key value
142  * cmp_func - comparing function
143  * node_dealloc - 'key', 'value' deallocation function
144  *
145  * returns/side-effects:
146  * list header ptr after the node is deleted.
147  *
148  * description: delete one node from list.
149  *
150  * NOTE:
151  * If 'key' or 'value' has its own memory, the memory must be freed
152  * in 'node_dealloc' function. But, the node container is freed in
153  * this module.
154  */
155 int
156 link_list_node_delete (T_LIST ** cur_head, void *key, int (*cmp_func) (void *, void *), void (*node_dealloc) (T_LIST *))
157 {
158  T_LIST *tmp;
159  T_LIST *del;
160  T_LIST *head = *cur_head;
161 
162  while (1)
163  {
164  del = link_list_find (head, key, NULL, cmp_func, NULL);
165  if (del == NULL)
166  break;
167 
168  tmp = delete_node (head, del, node_dealloc);
169  *cur_head = head = tmp;
170  }
171 
172 
173  return 0;
174 }
175 
176 /*
177  * name: link_list_node-delete2 - delete a node
178  *
179  * arguments: head - list header
180  * key - key value
181  * value
182  * key_cmp_func - key comparing function
183  * val_cmp_func - value comparing function
184  * node_dealloc - 'key', 'value' deallocation function
185  *
186  * returns/side-effects:
187  * list header ptr after the node is deleted.
188  *
189  * description: delete one node from list.
190  *
191  * NOTE:
192  * If 'key' or 'value' has its own memory, the memory must be freed
193  * in 'node_dealloc' function. But, the node container is freed in
194  * this module.
195  */
196 int
197 link_list_node_delete2 (T_LIST ** cur_head, void *key, void *value, int (*key_cmp_func) (void *, void *),
198  int (*val_cmp_func) (void *, void *), void (*node_dealloc) (T_LIST *))
199 {
200  T_LIST *tmp;
201  T_LIST *del;
202  T_LIST *head = *cur_head;
203 
204  del = link_list_find (head, key, value, key_cmp_func, val_cmp_func);
205  if (del == NULL)
206  return -1;
207 
208  tmp = delete_node (head, del, node_dealloc);
209  *cur_head = tmp;
210  return 0;
211 }
212 
213 /*
214  * name: link_list_delete - delete list
215  *
216  * arguments: head - list header
217  * node_dealloc - 'key', 'value' deallocation function
218  *
219  * returns/side-effects:
220  * (T_LIST*) NULL
221  *
222  * description: delete all nodes of list.
223  *
224  * NOTE:
225  * If 'key' or 'value' has its own memory, the memory must be freed
226  * in 'node_dealloc' function. But, the node container is freed in
227  * this module.
228  */
229 int
230 link_list_delete (T_LIST ** cur_head, void (*node_dealloc) (T_LIST *))
231 {
232  T_LIST *head = *cur_head;
233 
234  while (head)
235  {
236  head = delete_node (head, head, node_dealloc);
237  }
238  *cur_head = NULL;
239 
240  return 0;
241 }
242 
243 void *
244 link_list_traverse (T_LIST * head, void *(*traverse_func) (T_LIST *, void *))
245 {
246  T_LIST *tmp;
247  void *result = NULL;
248 
249  if (head == NULL)
250  return NULL;
251 
252  tmp = head;
253  do
254  {
255  result = (*traverse_func) (tmp, result);
256  tmp = tmp->next;
257  }
258  while (tmp != head);
259  return result;
260 }
261 
262 int
263 link_list_default_assign_func (T_LIST * node, void *key, void *value)
264 {
265  node->key = key;
266  node->value = value;
267  return 0;
268 }
269 
270 int
271 link_list_default_compare_func (void *key, void *value)
272 {
273  if (key == value)
274  return 1;
275  return 0;
276 }
277 
278 
279 static T_LIST *
280 delete_node (T_LIST * head, T_LIST * del_node, void (*node_dealloc) (T_LIST *))
281 {
282  T_LIST *new_head;
283  T_LIST *free_node;
284 
285  if (head == NULL)
286  return NULL;
287 
288  if (del_node->next == head)
289  {
290  if (del_node == head)
291  {
292  free_node = del_node;
293  new_head = NULL;
294  }
295  else
296  {
297  free_node = del_node->next;
298  swap_node (del_node, del_node->next);
299  new_head = del_node;
300  }
301  }
302  else
303  {
304  free_node = del_node->next;
305  swap_node (del_node, del_node->next);
306  new_head = head;
307  }
308 
309  if (node_dealloc)
310  (*node_dealloc) (free_node);
311  FREE_MEM (free_node);
312 
313  return new_head;
314 }
315 
316 static int
317 true_func (void *key, void *value)
318 {
319  return 1;
320 }
321 
322 static void
323 swap_node (T_LIST * node1, T_LIST * node2)
324 {
325  T_LIST tmp;
326 
327  tmp = *node1;
328  *node1 = *node2;
329  *node2 = tmp;
330 }
int link_list_node_delete(T_LIST **cur_head, void *key, int(*cmp_func)(void *, void *), void(*node_dealloc)(T_LIST *))
Definition: broker_list.c:156
struct list_tag * next
Definition: broker_list.h:50
void * value
Definition: broker_list.h:49
int link_list_add(T_LIST **cur_head, void *add_key, void *add_val, int(*assign_func)(T_LIST *, void *, void *))
Definition: broker_list.c:63
static T_LIST * delete_node(T_LIST *head, T_LIST *del_node, void(*node_dealloc)(T_LIST *))
Definition: broker_list.c:280
T_LIST * link_list_find(T_LIST *head, void *key, void *val, int(*key_cmp_func)(void *, void *), int(*val_cmp_func)(void *, void *))
Definition: broker_list.c:112
void * key
Definition: broker_list.h:48
static int true_func(void *key, void *value)
Definition: broker_list.c:317
static void swap_node(T_LIST *node1, T_LIST *node2)
Definition: broker_list.c:323
int link_list_delete(T_LIST **cur_head, void(*node_dealloc)(T_LIST *))
Definition: broker_list.c:230
#define NULL
Definition: freelistheap.h:34
int link_list_node_delete2(T_LIST **cur_head, void *key, void *value, int(*key_cmp_func)(void *, void *), int(*val_cmp_func)(void *, void *), void(*node_dealloc)(T_LIST *))
Definition: broker_list.c:197
#define FREE_MEM(PTR)
Definition: cas_common.h:58
static void error(const char *msg)
Definition: gencat.c:331
int link_list_default_compare_func(void *key, void *value)
Definition: broker_list.c:271
static void free_node(T_NODE_INFO *node)
Definition: cas_runner.c:1444
void * link_list_traverse(T_LIST *head, void *(*traverse_func)(T_LIST *, void *))
Definition: broker_list.c:244
int link_list_default_assign_func(T_LIST *node, void *key, void *value)
Definition: broker_list.c:263