00001 /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ 00002 /* 00003 * Copyright (c) 1993 Regents of the University of California. 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 3. All advertising materials mentioning features or use of this software 00015 * must display the following acknowledgement: 00016 * This product includes software developed by the Computer Systems 00017 * Engineering Group at Lawrence Berkeley Laboratory. 00018 * 4. Neither the name of the University nor of the Laboratory may be used 00019 * to endorse or promote products derived from this software without 00020 * specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 00023 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00024 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00025 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 00026 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00027 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00028 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00029 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00031 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00032 * SUCH DAMAGE. 00033 * 00034 * Author: 00035 * Mohit Talwar (mohit@catarina.usc.edu) 00036 * 00037 * $Header: /nfs/jade/vint/CVSROOT/ns-2/rap/raplist.cc,v 1.3 1999/09/24 23:44:39 haoboy Exp $ 00038 * 00039 * This is taken from UCB Nachos project 00040 * 00041 * list.cc 00042 * 00043 * Routines to manage a singly-linked list of "things". 00044 * 00045 * A "ListElement" is allocated for each item to be put on the 00046 * list; it is de-allocated when the item is removed. This means 00047 * we don't need to keep a "next" pointer in every object we 00048 * want to put on a list. 00049 */ 00050 00051 #include "utilities.h" 00052 #include "raplist.h" 00053 00054 //---------------------------------------------------------------------- 00055 // ListElement::ListElement 00056 // Initialize a List element, so it can be added somewhere on a List. 00057 // 00058 // "itemPtr" is the item to be put on the List. It can be a pointer 00059 // to anything. 00060 // "sortKey" is the priority of the item, if any. 00061 //---------------------------------------------------------------------- 00062 00063 ListElement::ListElement(void *itemPtr, float sortKey) 00064 { 00065 item = itemPtr; 00066 key = sortKey; 00067 next = NULL; // assume we'll put it at the end of the List 00068 } 00069 00070 //---------------------------------------------------------------------- 00071 // List::List 00072 // Initialize a List, empty to start with. 00073 // Elements can now be added to the List. 00074 //---------------------------------------------------------------------- 00075 00076 List::List() 00077 { 00078 size = 0; 00079 first = last = NULL; 00080 } 00081 00082 //---------------------------------------------------------------------- 00083 // List::~List 00084 // Prepare a List for deallocation. If the List still contains any 00085 // ListElements, de-allocate them. However, note that we do *not* 00086 // de-allocate the "items" on the List -- this module allocates 00087 // and de-allocates the ListElements to keep track of each item, 00088 // but a given item may be on multiple Lists, so we can't 00089 // de-allocate them here. 00090 //---------------------------------------------------------------------- 00091 00092 List::~List() 00093 { 00094 while (Remove() != NULL) 00095 ; // delete all the List elements 00096 } 00097 00098 //---------------------------------------------------------------------- 00099 // List::Append 00100 // Append an "item" to the end of the List. 00101 // 00102 // Allocate a ListElement to keep track of the item. 00103 // If the List is empty, then this will be the only element. 00104 // Otherwise, put it at the end. 00105 // 00106 // "item" is the thing to put on the List, it can be a pointer to 00107 // anything. 00108 //---------------------------------------------------------------------- 00109 00110 void List::Append(void *item) 00111 { 00112 ListElement *element = new ListElement(item, 0); 00113 if (IsEmpty()) 00114 { // List is empty 00115 first = element; 00116 last = element; 00117 } 00118 else 00119 { // else put it after last 00120 last->next = element; 00121 last = element; 00122 } 00123 00124 size++; 00125 } 00126 00127 //---------------------------------------------------------------------- 00128 // List::Prepend 00129 // Put an "item" on the front of the List. 00130 // 00131 // Allocate a ListElement to keep track of the item. 00132 // If the List is empty, then this will be the only element. 00133 // Otherwise, put it at the beginning. 00134 // 00135 // "item" is the thing to put on the List, it can be a pointer to 00136 // anything. 00137 //---------------------------------------------------------------------- 00138 00139 void List::Prepend(void *item) 00140 { 00141 ListElement *element = new ListElement(item, 0); 00142 00143 if (IsEmpty()) 00144 { // List is empty 00145 first = element; 00146 last = element; 00147 } 00148 else 00149 { // else put it before first 00150 element->next = first; 00151 first = element; 00152 } 00153 00154 size++; 00155 } 00156 00157 //---------------------------------------------------------------------- 00158 // List::Remove 00159 // Remove the first "item" from the front of the List. 00160 // 00161 // Returns: 00162 // Pointer to removed item, NULL if nothing on the List. 00163 //---------------------------------------------------------------------- 00164 00165 void *List::Remove() 00166 { 00167 return SortedRemove(NULL); // Same as SortedRemove, but ignore the key 00168 } 00169 00170 //---------------------------------------------------------------------- 00171 // List::Mapcar 00172 // Apply a function to each item on the List, by walking through 00173 // the List, one element at a time. 00174 // 00175 // Unlike LISP, this mapcar does not return anything! 00176 // 00177 // "func" is the procedure to apply to each element of the List. 00178 //---------------------------------------------------------------------- 00179 00180 void List::Mapcar(VoidFunctionPtr func) 00181 { 00182 for (ListElement *ptr = first; ptr != NULL; ptr = ptr->next) 00183 (*func)((int)ptr->item); 00184 } 00185 00186 //---------------------------------------------------------------------- 00187 // List::IsEmpty 00188 // Returns TRUE if the List is empty (has no items). 00189 //---------------------------------------------------------------------- 00190 00191 int List::IsEmpty() 00192 { 00193 if (first == NULL) 00194 return TRUE; 00195 else 00196 return FALSE; 00197 } 00198 00199 //---------------------------------------------------------------------- 00200 // List::SortedInsert 00201 // Insert an "item" into a List, so that the List elements are 00202 // sorted in increasing order by "sortKey". 00203 // 00204 // Allocate a ListElement to keep track of the item. 00205 // If the List is empty, then this will be the only element. 00206 // Otherwise, walk through the List, one element at a time, 00207 // to find where the new item should be placed. 00208 // 00209 // "item" is the thing to put on the List, it can be a pointer to 00210 // anything. 00211 // "sortKey" is the priority of the item. 00212 //---------------------------------------------------------------------- 00213 00214 void List::SortedInsert(void *item, float sortKey) 00215 { 00216 ListElement *element = new ListElement(item, sortKey); 00217 ListElement *ptr; // keep track 00218 00219 if (IsEmpty()) 00220 { // List is empty, put in front 00221 first = element; 00222 last = element; 00223 } 00224 else if (sortKey < first->key) 00225 { // item goes on front of List 00226 element->next = first; 00227 first = element; 00228 } 00229 else 00230 { // look for first elt in List bigger than item 00231 for (ptr = first; ptr->next != NULL; ptr = ptr->next) { 00232 if (sortKey < ptr->next->key) 00233 { 00234 element->next = ptr->next; 00235 ptr->next = element; 00236 return; 00237 } 00238 } 00239 last->next = element; // item goes at end of List 00240 last = element; 00241 } 00242 00243 size++; 00244 } 00245 00246 //---------------------------------------------------------------------- 00247 // List::SortedRemove 00248 // Remove the first "item" from the front of a sorted List. 00249 // 00250 // Returns: 00251 // Pointer to removed item, NULL if nothing on the List. 00252 // Sets *keyPtr to the priority value of the removed item 00253 // (this is needed by interrupt.cc, for instance). 00254 // 00255 // "keyPtr" is a pointer to the location in which to store the 00256 // priority of the removed item. 00257 //---------------------------------------------------------------------- 00258 00259 void *List::SortedRemove(float *keyPtr) 00260 { 00261 ListElement *element = first; 00262 void *thing; 00263 00264 if (IsEmpty()) 00265 return NULL; 00266 00267 thing = first->item; 00268 if (first == last) 00269 { // List had one item, now has none 00270 first = NULL; 00271 last = NULL; 00272 } 00273 else 00274 first = element->next; 00275 00276 if (keyPtr != NULL) 00277 *keyPtr = element->key; 00278 delete element; 00279 00280 size--; 00281 return thing; 00282 } 00283 00284 //---------------------------------------------------------------------- 00285 // List::MinKey 00286 // Return the key of the item in the front of a sorted List. 00287 // 00288 // Returns : 00289 // -1 if List is empty 00290 //---------------------------------------------------------------------- 00291 00292 float List::MinKey() 00293 { 00294 if (IsEmpty()) 00295 return -1; 00296 else 00297 return first->key; 00298 } 00299 00300 //---------------------------------------------------------------------- 00301 // List::SetInsert 00302 // Insert "key" into a List, so that the List elements are unique. 00303 // 00304 // Returns : 00305 // TRUE if "key" inserted, FALSE o/w 00306 // 00307 // Caveat : 00308 // Does not allocate space for key! Provided by calling function. 00309 // If FALSE, calling function should delete allocated space. 00310 // 00311 // "key" is the thing to put on the List. 00312 // "eq" is the comparison function used to compare two items. 00313 //---------------------------------------------------------------------- 00314 00315 int List::SetInsert(void *key, CompareFunction eq) 00316 { 00317 if (IsPresent(key, eq)) 00318 return FALSE; 00319 00320 Prepend(key); 00321 return TRUE; 00322 } 00323 00324 //---------------------------------------------------------------------- 00325 // List::SetRemove 00326 // Remove "key" from List. 00327 // 00328 // Returns : 00329 // handle to "key" in list if removed, NULL o/w 00330 // 00331 // Caveat : 00332 // if not NULL, Calling function should delete allocated space. 00333 // 00334 // "key" is the item to be removed. 00335 // "eq" is the comparison function used to compare two items. 00336 //---------------------------------------------------------------------- 00337 00338 void *List::SetRemove(void *key, CompareFunction eq) 00339 { 00340 ListElement *prev, *curr; 00341 void *thing; 00342 00343 if (!IsPresent(key, eq)) 00344 return NULL; 00345 00346 for (prev = NULL, curr = first; 00347 curr != NULL; 00348 prev = curr, curr = curr->next) 00349 if ((*eq)(key, curr->item)) 00350 break; 00351 00352 assert(curr != NULL); // Since its present we'd better find it 00353 00354 if (curr == first) 00355 first = curr->next; 00356 else 00357 prev->next = curr->next; 00358 00359 if (curr == last) 00360 last = prev; 00361 00362 thing = curr->item; 00363 delete curr; 00364 00365 size--; 00366 return thing; 00367 } 00368 00369 //---------------------------------------------------------------------- 00370 // List::IsPresent 00371 // Is "key" there in the Set 00372 // 00373 // Returns : 00374 // handle to the "key" in list (NULL if not found) 00375 // 00376 // "key" is the item to be searched. 00377 // "eq" is the comparison function used to compare two items. 00378 //---------------------------------------------------------------------- 00379 00380 void *List::IsPresent(void *key, CompareFunction eq) 00381 { 00382 ListElement *ptr; 00383 00384 for (ptr = first; ptr != NULL; ptr = ptr->next) // Check all items 00385 if ((*eq)(key, ptr->item)) 00386 return ptr->item; 00387 00388 return NULL; 00389 } 00390 00391 //---------------------------------------------------------------------- 00392 // List::Purge 00393 // Remove all elements with (key eq "key") from the Set 00394 // 00395 // "key" is the item to be searched and deleted. 00396 // "eq" is the comparison function used to compare two items. 00397 // "destroy" is the function used to delete the purged "key". 00398 //---------------------------------------------------------------------- 00399 00400 void List::Purge(void *key, CompareFunction eq, VoidFunctionPtr destroy) 00401 { 00402 ListElement *prev, *curr, *temp; 00403 void *thing; 00404 00405 for (prev = NULL, curr = first; curr != NULL; ) // Check all items 00406 if ((*eq)(key, curr->item)) 00407 { 00408 if (curr == first) 00409 first = curr->next; 00410 else 00411 prev->next = curr->next; 00412 00413 if (curr == last) 00414 last = prev; 00415 00416 thing = curr->item; 00417 temp = curr; 00418 00419 curr = curr->next; 00420 00421 (* destroy)((int) thing); 00422 delete temp; 00423 size--; 00424 } 00425 else 00426 { 00427 prev = curr; 00428 curr = curr->next; 00429 } 00430 }
1.3.3