Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

raplist.cc

Go to the documentation of this file.
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 }

Generated on Tue Apr 20 12:14:28 2004 for NS2.26SourcesOriginal by doxygen 1.3.3