00001 /** @file psList.h 00002 * @brief Support for doubly linked lists 00003 * 00004 * @author Robert Lupton, Princeton University 00005 * @author Robert Daniel DeSonia, MHPCC 00006 * 00007 * @ingroup LinkedList 00008 * 00009 * @version $Revision: 1.1.1.1 $ $Name: $ 00010 * @date $Date: 2005/09/14 20:42:48 $ 00011 * 00012 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii 00013 */ 00014 00015 #ifndef PS_LIST_H 00016 #define PS_LIST_H 00017 00018 #include <pthread.h> // we need a mutex to make this stuff thread safe. 00019 00020 #include "psCompare.h" 00021 #include "psArray.h" 00022 00023 /** @addtogroup LinkedList 00024 * @{ 00025 */ 00026 00027 /** Special values of index into list 00028 * 00029 * This list of possible list position values should be contiguous non-positive values ending with 00030 * PS_LIST_UNKNOWN. Any value less-than-or-equal-to PS_LIST_UNKNOWN is considered a undefined position. 00031 * 00032 */ 00033 enum { 00034 PS_LIST_HEAD = 0, ///< at head 00035 PS_LIST_TAIL = -1, ///< at tail 00036 }; 00037 00038 /** Doubly-linked list element */ 00039 typedef struct psListElem 00040 { 00041 struct psListElem* prev; ///< previous link in list 00042 struct psListElem* next; ///< next link in list 00043 psPtr data; ///< real data item 00044 } 00045 psListElem; 00046 00047 /** The psList Linked list structure. User should not allocate this struct 00048 * directly; rather the psListAlloc should be used. 00049 * 00050 * @see psListAlloc 00051 */ 00052 typedef struct 00053 { 00054 long n; ///< number of elements on list 00055 psListElem* head; ///< first element on list (may be NULL) 00056 psListElem* tail; ///< last element on list (may be NULL) 00057 psArray* iterators; 00058 ///< array of all iterators associated with this list. First iterator is 00059 ///< used internally to improve performance when using indexed access, all 00060 ///< others are user-level iterators created by psListIteratorAlloc. 00061 00062 pthread_mutex_t lock; ///< mutex to lock a node during changes 00063 // void *lock; ///< Optional lock for thread safety 00064 } 00065 psList; 00066 00067 /** The psList iterator structure. This should be allocated via 00068 * psListIteratorAlloc and not directly. 00069 * 00070 * The life span of a psListIterator object is ended by either a psFree 00071 * of this structure OR psFree of the psList in which it operates on. 00072 * 00073 * @see psListIteratorAlloc, psListIteratorSet, psListGetAndIncrement, psListGetAndDecrement 00074 */ 00075 typedef struct 00076 { 00077 psList* list; ///< List iterator to works on 00078 psListElem* cursor; ///< current cursor position 00079 bool offEnd; ///< Iterator off the end? 00080 long index; ///< the index number in the list 00081 bool mutable; ///< Is it permissible to modify the list? 00082 } 00083 psListIterator; 00084 00085 00086 /** Checks the type of a particular pointer. 00087 * 00088 * Uses the appropriate deallocation function in psMemBlock to check the ptr datatype. 00089 * 00090 * @return bool: True if the pointer matches a psList structure, false otherwise. 00091 */ 00092 bool psMemCheckList( 00093 psPtr ptr ///< the pointer whose type to check 00094 ) 00095 ; 00096 00097 00098 /** Creates a psList linked list object. 00099 * 00100 * @return psList* A new psList object. 00101 */ 00102 psList* psListAlloc( 00103 psPtr data ///< initial data item; may be NULL if an empty psList is desired 00104 ); 00105 00106 /** Creates a psListIterator object and associates it with a psList. 00107 * 00108 * @return psListIterator* A new psListIterator object. 00109 */ 00110 psListIterator* psListIteratorAlloc( 00111 psList* list, ///< the psList to iterate with 00112 long location, ///< the initial starting point. 00113 ///< This can be a numeric index, PS_LIST_HEAD, or PS_LIST_TAIL. 00114 bool mutable ///< Is it permissible to modify list? 00115 ); 00116 00117 /** Set the iterator of the list to a given position. If location is invalid the 00118 * iterator position is not changed. 00119 * 00120 * @return bool TRUE if iterator successfully set, otherwise FALSE. 00121 */ 00122 bool psListIteratorSet( 00123 psListIterator* iterator, ///< list iterator 00124 long location ///< index number, PS_LIST_HEAD, or PS_LIST_TAIL 00125 ); 00126 00127 /** Adds an element to a psList at position given. 00128 * 00129 * @return bool TRUE if item was successfully added, otherwise FALSE. 00130 */ 00131 bool psListAdd( 00132 psList* list, ///< list to add item to 00133 long location, ///< index, PS_LIST_HEAD, PS_LIST_TAIL, or numbered location. 00134 psPtr data ///< data item to add. If NULL, list is not modified. 00135 ); 00136 00137 /** Adds an data item to a psList at position just after the list position given 00138 * 00139 * @return bool TRUE if item was successfully added, otherwise FALSE. 00140 */ 00141 bool psListAddAfter( 00142 psListIterator* iterator, ///< list position to add item to 00143 psPtr data ///< data item to add. If NULL, list is not modified. 00144 ); 00145 00146 /** Adds an data item to a psList at position just before the list position given 00147 * 00148 * @return bool TRUE if item was successfully added, otherwise FALSE. 00149 */ 00150 bool psListAddBefore( 00151 psListIterator* iterator, ///< list position to add item to 00152 psPtr data ///< data item to add. If NULL, list is not modified. 00153 ); 00154 00155 /** Remove an item at the specified location from a list. 00156 * 00157 * @return bool TRUE if element is successfully removed, otherwise FALSE. 00158 */ 00159 bool psListRemove( 00160 psList* list, ///< list to remove element from 00161 long location ///< index of item 00162 ); 00163 00164 /** Remove an item from a list. 00165 * 00166 * @return bool TRUE if element is successfully removed, otherwise FALSE. 00167 */ 00168 bool psListRemoveData( 00169 psList* list, ///< list to remove element from 00170 psPtr data ///< data item to find and remove 00171 ); 00172 00173 /** Retrieve an item from a list. 00174 * 00175 * @return psPtr the item corresponding to the location parameter. If 00176 * location is invalid (e.g., a numbered index greater 00177 * than the list size or if the list is empty), a 00178 * NULL is returned. 00179 */ 00180 psPtr psListGet( 00181 psList* list, ///< list to retrieve element from 00182 long location ///< index number, PS_LIST_HEAD, or PS_LIST_TAIL 00183 ); 00184 00185 /** Position the specified iterator to the next item in list. 00186 * 00187 * @return psPtr the data item at the original iterator position or NULL if the 00188 * iterator went past the end of the list. 00189 */ 00190 psPtr psListGetAndIncrement( 00191 psListIterator* iterator ///< iterator to move 00192 ); 00193 00194 /** Position the specified iterator to the previous item in list. 00195 * 00196 * @return psPtr the data item at the original iterator position or NULL if the 00197 * iterator went past the beginning of the list. 00198 */ 00199 psPtr psListGetAndDecrement( 00200 psListIterator* iterator ///< iterator to move 00201 ); 00202 00203 /** Convert a linked list to an array 00204 * 00205 * @return psArray* A new psArray populated with elements from the list, 00206 * or NULL if the given dlist parameter is NULL. 00207 */ 00208 psArray* psListToArray( 00209 const psList* list ///< List to convert 00210 ); 00211 00212 /** Convert array to a doubly-linked list 00213 * 00214 * @return psList* A new psList populated with elements formt the psArray, 00215 * or NULL is the given arr parameter is NULL. 00216 */ 00217 psList* psArrayToList( 00218 const psArray* array ///< vector to convert 00219 ); 00220 00221 /** Sort a list via a comparison function. 00222 * 00223 * The comparison function must return an integer less than, equal to, or 00224 * greater than zero if the first argument is considered to be respectively 00225 * less than, equal to, or greater than the second. 00226 * 00227 * If two members compare as equal, their order in the sorted array is 00228 * undefined. 00229 * 00230 * @return psList* Sorted list. 00231 */ 00232 psList* psListSort( 00233 psList* list, ///< the list to sort 00234 psComparePtrFunc func ///< the comparison function 00235 ); 00236 00237 /// @} End of DataGroup Functions 00238 00239 #endif // #ifndef PS_LIST_H 00240
1.4.2