/*BHEADER********************************************************************** * Copyright (c) 2008, Lawrence Livermore National Security, LLC. * Produced at the Lawrence Livermore National Laboratory. * This file is part of HYPRE. See file COPYRIGHT for details. * * HYPRE is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License (as published by the Free * Software Foundation) version 2.1 dated February 1999. * * $Revision: 2.4 $ ***********************************************************************EHEADER*/ /*************************************************************************** * * Routines for linked list for boomerAMG * ****************************************************************************/ #include "utilities.h" #define LIST_HEAD -1 #define LIST_TAIL -2 /************************************************************** * * dispose_elt(): dispose of memory space used by the element * pointed to by element_ptr. Use the 'free()' * system call to return it to the free memory * pool. * **************************************************************/ void dispose_elt ( hypre_LinkList element_ptr ) { free( element_ptr ); } /***************************************************************** * * remove_point: removes a point from the lists * ****************************************************************/ void remove_point(hypre_LinkList *LoL_head_ptr, hypre_LinkList *LoL_tail_ptr, int measure, int index, int *lists, int *where) { hypre_LinkList LoL_head = *LoL_head_ptr; hypre_LinkList LoL_tail = *LoL_tail_ptr; hypre_LinkList list_ptr; list_ptr = LoL_head; do { if (measure == list_ptr->data) { /* point to be removed is only point on list, which must be destroyed */ if (list_ptr->head == index && list_ptr->tail == index) { /* removing only list, so num_left better be 0! */ if (list_ptr == LoL_head && list_ptr == LoL_tail) { LoL_head = NULL; LoL_tail = NULL; dispose_elt(list_ptr); *LoL_head_ptr = LoL_head; *LoL_tail_ptr = LoL_tail; return; } else if (LoL_head == list_ptr) /*removing 1st (max_measure) list */ { list_ptr -> next_elt -> prev_elt = NULL; LoL_head = list_ptr->next_elt; dispose_elt(list_ptr); *LoL_head_ptr = LoL_head; *LoL_tail_ptr = LoL_tail; return; } else if (LoL_tail == list_ptr) /* removing last list */ { list_ptr -> prev_elt -> next_elt = NULL; LoL_tail = list_ptr->prev_elt; dispose_elt(list_ptr); *LoL_head_ptr = LoL_head; *LoL_tail_ptr = LoL_tail; return; } else { list_ptr -> next_elt -> prev_elt = list_ptr -> prev_elt; list_ptr -> prev_elt -> next_elt = list_ptr -> next_elt; dispose_elt(list_ptr); *LoL_head_ptr = LoL_head; *LoL_tail_ptr = LoL_tail; return; } } else if (list_ptr->head == index) /* index is head of list */ { list_ptr->head = lists[index]; where[lists[index]] = LIST_HEAD; return; } else if (list_ptr->tail == index) /* index is tail of list */ { list_ptr->tail = where[index]; lists[where[index]] = LIST_TAIL; return; } else /* index is in middle of list */ { lists[where[index]] = lists[index]; where[lists[index]] = where[index]; return; } } list_ptr = list_ptr -> next_elt; } while (list_ptr != NULL); printf("No such list!\n"); return; } /***************************************************************** * * create_elt() : Create an element using Item for its data field * *****************************************************************/ hypre_LinkList create_elt( int Item ) { hypre_LinkList new_elt_ptr; /* Allocate memory space for the new node. * return with error if no space available */ if ( (new_elt_ptr = (hypre_LinkList) malloc (sizeof(hypre_ListElement))) == NULL) { printf("\n create_elt: malloc failed \n\n"); } else /* new_elt_ptr = hypre_CTAlloc(hypre_LinkList, 1); */ { new_elt_ptr -> data = Item; new_elt_ptr -> next_elt = NULL; new_elt_ptr -> prev_elt = NULL; new_elt_ptr -> head = LIST_TAIL; new_elt_ptr -> tail = LIST_HEAD; } return (new_elt_ptr); } /***************************************************************** * * enter_on_lists places point in new list * ****************************************************************/ void enter_on_lists(hypre_LinkList *LoL_head_ptr, hypre_LinkList *LoL_tail_ptr, int measure, int index, int *lists, int *where) { hypre_LinkList LoL_head = *LoL_head_ptr; hypre_LinkList LoL_tail = *LoL_tail_ptr; hypre_LinkList list_ptr; hypre_LinkList new_ptr; int old_tail; list_ptr = LoL_head; if (LoL_head == NULL) /* no lists exist yet */ { new_ptr = create_elt(measure); new_ptr->head = index; new_ptr->tail = index; lists[index] = LIST_TAIL; where[index] = LIST_HEAD; LoL_head = new_ptr; LoL_tail = new_ptr; *LoL_head_ptr = LoL_head; *LoL_tail_ptr = LoL_tail; return; } else { do { if (measure > list_ptr->data) { new_ptr = create_elt(measure); new_ptr->head = index; new_ptr->tail = index; lists[index] = LIST_TAIL; where[index] = LIST_HEAD; if ( list_ptr->prev_elt != NULL) { new_ptr->prev_elt = list_ptr->prev_elt; list_ptr->prev_elt->next_elt = new_ptr; list_ptr->prev_elt = new_ptr; new_ptr->next_elt = list_ptr; } else { new_ptr->next_elt = list_ptr; list_ptr->prev_elt = new_ptr; new_ptr->prev_elt = NULL; LoL_head = new_ptr; } *LoL_head_ptr = LoL_head; *LoL_tail_ptr = LoL_tail; return; } else if (measure == list_ptr->data) { old_tail = list_ptr->tail; lists[old_tail] = index; where[index] = old_tail; lists[index] = LIST_TAIL; list_ptr->tail = index; return; } list_ptr = list_ptr->next_elt; } while (list_ptr != NULL); new_ptr = create_elt(measure); new_ptr->head = index; new_ptr->tail = index; lists[index] = LIST_TAIL; where[index] = LIST_HEAD; LoL_tail->next_elt = new_ptr; new_ptr->prev_elt = LoL_tail; new_ptr->next_elt = NULL; LoL_tail = new_ptr; *LoL_head_ptr = LoL_head; *LoL_tail_ptr = LoL_tail; return; } }