File broker_list.c¶
File List > broker > broker_list.c
Go to the documentation of this file
/*
* Copyright 2008 Search Solution Corporation
* Copyright 2016 CUBRID Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* link_list.c - This module contains operations for singly linked list.
* The list header is a recent appended node.
*/
#ident "$Id$"
#include <stdio.h>
#include <stdlib.h>
#include "cas_common.h"
#include "broker_list.h"
static T_LIST *delete_node (T_LIST * head, T_LIST * del_node, void (*node_dealloc) (T_LIST *));
static int true_func (void *key, void *value);
static void swap_node (T_LIST * node1, T_LIST * node2);
/*
* name: link_list_add - append a node to a designated list
*
* arguments: cur_head - the list header(IN/OUT)
* add_key - the key of the node
* add_val - the value of the node
* assign_func - a function for assigning key and value
*
* returns/side-effects:
* 0 : success
* < 0 : error code
*
* description: add new node to the list.
* created node is new list header.
*
* NOTE:
* Since the type of 'key' and 'value' of the node is 'void*',
* it is only possible to assign value which size is same as void ptr.
* For example, if string is copied to 'key', you must allocate memory
* in assigning function.
*/
int
link_list_add (T_LIST ** cur_head, void *add_key, void *add_val, int (*assign_func) (T_LIST *, void *, void *))
{
T_LIST *tmp;
T_LIST *new_node;
int error;
T_LIST *head = *cur_head;
tmp = (T_LIST *) malloc (sizeof (T_LIST));
if (tmp == NULL)
return -1;
if (head == NULL)
{
new_node = tmp;
}
else
{
*tmp = *head;
new_node = head;
}
error = (*assign_func) (new_node, add_key, add_val);
if (error < 0)
{
FREE_MEM (tmp);
return error;
}
new_node->next = tmp;
*cur_head = tmp;
return 0;
}
/*
* name: link_list_find
*
* arguments: head - list header
* key - key value for list search
* cmp_func - comparing function
*
* returns/side-effects:
* node ptr if exist.
* NULL ptr otherwise.
*
* description: search list with key value.
*
* NOTE:
*/
T_LIST *
link_list_find (T_LIST * head, void *key, void *val, int (*key_cmp_func) (void *, void *),
int (*val_cmp_func) (void *, void *))
{
T_LIST *tmp;
if (head == NULL)
return NULL;
if (key_cmp_func == NULL)
key_cmp_func = true_func;
if (val_cmp_func == NULL)
val_cmp_func = true_func;
tmp = head;
do
{
if ((*key_cmp_func) (tmp->key, key) && (*val_cmp_func) (tmp->value, val))
return tmp;
tmp = tmp->next;
}
while (tmp != head);
return NULL; /* not found */
}
/*
* name: link_list_node_delete - delete a node
*
* arguments: head - list header
* key - key value
* cmp_func - comparing function
* node_dealloc - 'key', 'value' deallocation function
*
* returns/side-effects:
* list header ptr after the node is deleted.
*
* description: delete one node from list.
*
* NOTE:
* If 'key' or 'value' has its own memory, the memory must be freed
* in 'node_dealloc' function. But, the node container is freed in
* this module.
*/
int
link_list_node_delete (T_LIST ** cur_head, void *key, int (*cmp_func) (void *, void *), void (*node_dealloc) (T_LIST *))
{
T_LIST *tmp;
T_LIST *del;
T_LIST *head = *cur_head;
while (1)
{
del = link_list_find (head, key, NULL, cmp_func, NULL);
if (del == NULL)
break;
tmp = delete_node (head, del, node_dealloc);
*cur_head = head = tmp;
}
return 0;
}
/*
* name: link_list_node-delete2 - delete a node
*
* arguments: head - list header
* key - key value
* value
* key_cmp_func - key comparing function
* val_cmp_func - value comparing function
* node_dealloc - 'key', 'value' deallocation function
*
* returns/side-effects:
* list header ptr after the node is deleted.
*
* description: delete one node from list.
*
* NOTE:
* If 'key' or 'value' has its own memory, the memory must be freed
* in 'node_dealloc' function. But, the node container is freed in
* this module.
*/
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 *))
{
T_LIST *tmp;
T_LIST *del;
T_LIST *head = *cur_head;
del = link_list_find (head, key, value, key_cmp_func, val_cmp_func);
if (del == NULL)
return -1;
tmp = delete_node (head, del, node_dealloc);
*cur_head = tmp;
return 0;
}
/*
* name: link_list_delete - delete list
*
* arguments: head - list header
* node_dealloc - 'key', 'value' deallocation function
*
* returns/side-effects:
* (T_LIST*) NULL
*
* description: delete all nodes of list.
*
* NOTE:
* If 'key' or 'value' has its own memory, the memory must be freed
* in 'node_dealloc' function. But, the node container is freed in
* this module.
*/
int
link_list_delete (T_LIST ** cur_head, void (*node_dealloc) (T_LIST *))
{
T_LIST *head = *cur_head;
while (head)
{
head = delete_node (head, head, node_dealloc);
}
*cur_head = NULL;
return 0;
}
void *
link_list_traverse (T_LIST * head, void *(*traverse_func) (T_LIST *, void *))
{
T_LIST *tmp;
void *result = NULL;
if (head == NULL)
return NULL;
tmp = head;
do
{
result = (*traverse_func) (tmp, result);
tmp = tmp->next;
}
while (tmp != head);
return result;
}
int
link_list_default_assign_func (T_LIST * node, void *key, void *value)
{
node->key = key;
node->value = value;
return 0;
}
int
link_list_default_compare_func (void *key, void *value)
{
if (key == value)
return 1;
return 0;
}
static T_LIST *
delete_node (T_LIST * head, T_LIST * del_node, void (*node_dealloc) (T_LIST *))
{
T_LIST *new_head;
T_LIST *free_node;
if (head == NULL)
return NULL;
if (del_node->next == head)
{
if (del_node == head)
{
free_node = del_node;
new_head = NULL;
}
else
{
free_node = del_node->next;
swap_node (del_node, del_node->next);
new_head = del_node;
}
}
else
{
free_node = del_node->next;
swap_node (del_node, del_node->next);
new_head = head;
}
if (node_dealloc)
(*node_dealloc) (free_node);
FREE_MEM (free_node);
return new_head;
}
static int
true_func (void *key, void *value)
{
return 1;
}
static void
swap_node (T_LIST * node1, T_LIST * node2)
{
T_LIST tmp;
tmp = *node1;
*node1 = *node2;
*node2 = tmp;
}