Main Page   Compound List   File List   Compound Members   File Members  

list.cc

Go to the documentation of this file.
00001 // list.cc 
00002 //
00003 //      Routines to manage a singly-linked list of "things".
00004 //
00005 //      A "ListElement" is allocated for each item to be put on the
00006 //      list; it is de-allocated when the item is removed. This means
00007 //      we don't need to keep a "next" pointer in every object we
00008 //      want to put on a list.
00009 // 
00010 //      NOTE: Mutual exclusion must be provided by the caller.
00011 //      If you want a synchronized list, you must use the routines 
00012 //      in synchlist.cc.
00013 //
00014 // Copyright (c) 1992-1993 The Regents of the University of California.
00015 // All rights reserved.  See copyright.h for copyright notice and limitation 
00016 // of liability and disclaimer of warranty provisions.
00017 
00018 #include "copyright.h"
00019 #include "list.h"
00020 
00021 //----------------------------------------------------------------------
00022 // ListElement::ListElement
00023 //      Initialize a list element, so it can be added somewhere on a list.
00024 //
00025 //      "itemPtr" is the item to be put on the list.  It can be a pointer
00026 //              to anything.
00027 //      "sortKey" is the priority of the item, if any.
00028 //----------------------------------------------------------------------
00029 
00030 ListElement::ListElement(void *itemPtr, int sortKey)
00031 {
00032      item = itemPtr;
00033      key = sortKey;
00034      next = NULL;       // assume we'll put it at the end of the list 
00035 }
00036 
00037 //----------------------------------------------------------------------
00038 // List::List
00039 //      Initialize a list, empty to start with.
00040 //      Elements can now be added to the list.
00041 //----------------------------------------------------------------------
00042 
00043 List::List()
00044 { 
00045     first = last = NULL; 
00046 }
00047 
00048 //----------------------------------------------------------------------
00049 // List::~List
00050 //      Prepare a list for deallocation.  If the list still contains any 
00051 //      ListElements, de-allocate them.  However, note that we do *not*
00052 //      de-allocate the "items" on the list -- this module allocates
00053 //      and de-allocates the ListElements to keep track of each item,
00054 //      but a given item may be on multiple lists, so we can't
00055 //      de-allocate them here.
00056 //----------------------------------------------------------------------
00057 
00058 List::~List()
00059 { 
00060     while (Remove() != NULL)
00061         ;        // delete all the list elements
00062 }
00063 
00064 //----------------------------------------------------------------------
00065 // List::Append
00066 //      Append an "item" to the end of the list.
00067 //      
00068 //      Allocate a ListElement to keep track of the item.
00069 //      If the list is empty, then this will be the only element.
00070 //      Otherwise, put it at the end.
00071 //
00072 //      "item" is the thing to put on the list, it can be a pointer to 
00073 //              anything.
00074 //----------------------------------------------------------------------
00075 
00076 void
00077 List::Append(void *item)
00078 {
00079     ListElement *element = new ListElement(item, 0);
00080 
00081     if (IsEmpty()) {            // list is empty
00082         first = element;
00083         last = element;
00084     } else {                    // else put it after last
00085         last->next = element;
00086         last = element;
00087     }
00088 }
00089 
00090 //----------------------------------------------------------------------
00091 // List::Prepend
00092 //      Put an "item" on the front of the list.
00093 //      
00094 //      Allocate a ListElement to keep track of the item.
00095 //      If the list is empty, then this will be the only element.
00096 //      Otherwise, put it at the beginning.
00097 //
00098 //      "item" is the thing to put on the list, it can be a pointer to 
00099 //              anything.
00100 //----------------------------------------------------------------------
00101 
00102 void
00103 List::Prepend(void *item)
00104 {
00105     ListElement *element = new ListElement(item, 0);
00106 
00107     if (IsEmpty()) {            // list is empty
00108         first = element;
00109         last = element;
00110     } else {                    // else put it before first
00111         element->next = first;
00112         first = element;
00113     }
00114 }
00115 
00116 //----------------------------------------------------------------------
00117 // List::Remove
00118 //      Remove the first "item" from the front of the list.
00119 // 
00120 // Returns:
00121 //      Pointer to removed item, NULL if nothing on the list.
00122 //----------------------------------------------------------------------
00123 
00124 void *
00125 List::Remove()
00126 {
00127     return SortedRemove(NULL);  // Same as SortedRemove, but ignore the key
00128 }
00129 
00130 //----------------------------------------------------------------------
00131 // List::Mapcar
00132 //      Apply a function to each item on the list, by walking through  
00133 //      the list, one element at a time.
00134 //
00135 //      Unlike LISP, this mapcar does not return anything!
00136 //
00137 //      "func" is the procedure to apply to each element of the list.
00138 //----------------------------------------------------------------------
00139 
00140 void
00141 List::Mapcar(VoidFunctionPtr func)
00142 {
00143     for (ListElement *ptr = first; ptr != NULL; ptr = ptr->next) {
00144        DEBUG('l', "In mapcar, about to invoke %x(%x)\n", func, ptr->item);
00145        (*func)((int)ptr->item);
00146     }
00147 }
00148 
00149 //----------------------------------------------------------------------
00150 // List::IsEmpty
00151 //      Returns TRUE if the list is empty (has no items).
00152 //----------------------------------------------------------------------
00153 
00154 bool
00155 List::IsEmpty() 
00156 { 
00157     if (first == NULL)
00158         return TRUE;
00159     else
00160         return FALSE; 
00161 }
00162 
00163 //----------------------------------------------------------------------
00164 // List::SortedInsert
00165 //      Insert an "item" into a list, so that the list elements are
00166 //      sorted in increasing order by "sortKey".
00167 //      
00168 //      Allocate a ListElement to keep track of the item.
00169 //      If the list is empty, then this will be the only element.
00170 //      Otherwise, walk through the list, one element at a time,
00171 //      to find where the new item should be placed.
00172 //
00173 //      "item" is the thing to put on the list, it can be a pointer to 
00174 //              anything.
00175 //      "sortKey" is the priority of the item.
00176 //----------------------------------------------------------------------
00177 
00178 void
00179 List::SortedInsert(void *item, int sortKey)
00180 {
00181     ListElement *element = new ListElement(item, sortKey);
00182     ListElement *ptr;           // keep track
00183 
00184     if (IsEmpty()) {    // if list is empty, put
00185         first = element;
00186         last = element;
00187     } else if (sortKey < first->key) {  
00188                 // item goes on front of list
00189         element->next = first;
00190         first = element;
00191     } else {            // look for first elt in list bigger than item
00192         for (ptr = first; ptr->next != NULL; ptr = ptr->next) {
00193             if (sortKey < ptr->next->key) {
00194                 element->next = ptr->next;
00195                 ptr->next = element;
00196                 return;
00197             }
00198         }
00199         last->next = element;           // item goes at end of list
00200         last = element;
00201     }
00202 }
00203 
00204 //----------------------------------------------------------------------
00205 // List::SortedRemove
00206 //      Remove the first "item" from the front of a sorted list.
00207 // 
00208 // Returns:
00209 //      Pointer to removed item, NULL if nothing on the list.
00210 //      Sets *keyPtr to the priority value of the removed item
00211 //      (this is needed by interrupt.cc, for instance).
00212 //
00213 //      "keyPtr" is a pointer to the location in which to store the 
00214 //              priority of the removed item.
00215 //----------------------------------------------------------------------
00216 
00217 void *
00218 List::SortedRemove(int *keyPtr)
00219 {
00220     ListElement *element = first;
00221     void *thing;
00222 
00223     if (IsEmpty()) 
00224         return NULL;
00225 
00226     thing = first->item;
00227     if (first == last) {        // list had one item, now has none 
00228         first = NULL;
00229         last = NULL;
00230     } else {
00231         first = element->next;
00232     }
00233     if (keyPtr != NULL)
00234         *keyPtr = element->key;
00235     delete element;
00236     return thing;
00237 }
00238 

Generated on Mon Feb 10 09:54:45 2003 for nachos by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002
The University of Southern California does not screen or control the content on this website and thus does not guarantee the accuracy, integrity, or quality of such content. All content on this website is provided by and is the sole responsibility of the person from which such content originated, and such content does not necessarily reflect the opinions of the University administration or the Board of Trustees