raplist.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:12k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * Copyright (c) 1993 Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. All advertising materials mentioning features or use of this software
  15.  *    must display the following acknowledgement:
  16.  * This product includes software developed by the Computer Systems
  17.  * Engineering Group at Lawrence Berkeley Laboratory.
  18.  * 4. Neither the name of the University nor of the Laboratory may be used
  19.  *    to endorse or promote products derived from this software without
  20.  *    specific prior written permission.
  21.  *
  22.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  23.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  26.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  28.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  31.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  32.  * SUCH DAMAGE.
  33.  *
  34.  * Author:
  35.  *   Mohit Talwar (mohit@catarina.usc.edu)
  36.  *
  37.  * $Header: /cvsroot/nsnam/ns-2/rap/raplist.cc,v 1.4 2005/09/18 23:33:34 tomh Exp $
  38.  * 
  39.  * This is taken from UCB Nachos project
  40.  * 
  41.  * list.cc 
  42.  *
  43.  *      Routines to manage a singly-linked list of "things".
  44.  *
  45.  *      A "ListElement" is allocated for each item to be put on the
  46.  *      list; it is de-allocated when the item is removed. This means
  47.  *      we don't need to keep a "next" pointer in every object we
  48.  *      want to put on a list.
  49.  */
  50. #include "utilities.h"
  51. #include "raplist.h"
  52. //----------------------------------------------------------------------
  53. // ListElement::ListElement
  54. //  Initialize a List element, so it can be added somewhere on a List.
  55. //
  56. // "itemPtr" is the item to be put on the List.  It can be a pointer
  57. // to anything.
  58. // "sortKey" is the priority of the item, if any.
  59. //----------------------------------------------------------------------
  60. ListElement::ListElement(void *itemPtr, float sortKey)
  61. {
  62.   item = itemPtr;
  63.   key = sortKey;
  64.   next = NULL; // assume we'll put it at the end of the List 
  65. }
  66. //----------------------------------------------------------------------
  67. // List::List
  68. // Initialize a List, empty to start with.
  69. // Elements can now be added to the List.
  70. //----------------------------------------------------------------------
  71. List::List()
  72. {
  73.   size  = 0;
  74.   first = last = NULL; 
  75. }
  76. //----------------------------------------------------------------------
  77. // List::~List
  78. // Prepare a List for deallocation.  If the List still contains any 
  79. // ListElements, de-allocate them.  However, note that we do *not*
  80. // de-allocate the "items" on the List -- this module allocates
  81. // and de-allocates the ListElements to keep track of each item,
  82. // but a given item may be on multiple Lists, so we can't
  83. // de-allocate them here.
  84. //----------------------------------------------------------------------
  85. List::~List()
  86.   while (Remove() != NULL)
  87.     ;  // delete all the List elements
  88. }
  89. //----------------------------------------------------------------------
  90. // List::Append
  91. //      Append an "item" to the end of the List.
  92. //      
  93. // Allocate a ListElement to keep track of the item.
  94. //      If the List is empty, then this will be the only element.
  95. // Otherwise, put it at the end.
  96. //
  97. // "item" is the thing to put on the List, it can be a pointer to 
  98. // anything.
  99. //----------------------------------------------------------------------
  100. void List::Append(void *item)
  101. {
  102.   ListElement *element = new ListElement(item, 0);
  103.   if (IsEmpty()) 
  104.     { // List is empty
  105.       first = element;
  106.       last = element;
  107.     } 
  108.   else 
  109.     { // else put it after last
  110.       last->next = element;
  111.       last = element;
  112.     }
  113.   
  114.   size++;
  115. }
  116. //----------------------------------------------------------------------
  117. // List::Prepend
  118. //      Put an "item" on the front of the List.
  119. //      
  120. // Allocate a ListElement to keep track of the item.
  121. //      If the List is empty, then this will be the only element.
  122. // Otherwise, put it at the beginning.
  123. //
  124. // "item" is the thing to put on the List, it can be a pointer to 
  125. // anything.
  126. //----------------------------------------------------------------------
  127. void List::Prepend(void *item)
  128. {
  129.   ListElement *element = new ListElement(item, 0);
  130.   
  131.   if (IsEmpty()) 
  132.     { // List is empty
  133.       first = element;
  134.       last = element;
  135.     } 
  136.   else 
  137.     { // else put it before first
  138.       element->next = first;
  139.       first = element;
  140.     }
  141.   size++;
  142. }
  143. //----------------------------------------------------------------------
  144. // List::Remove
  145. //      Remove the first "item" from the front of the List.
  146. // 
  147. // Returns:
  148. // Pointer to removed item, NULL if nothing on the List.
  149. //----------------------------------------------------------------------
  150. void *List::Remove()
  151. {
  152.   return SortedRemove(NULL);  // Same as SortedRemove, but ignore the key
  153. }
  154. //----------------------------------------------------------------------
  155. // List::Mapcar
  156. // Apply a function to each item on the List, by walking through  
  157. // the List, one element at a time.
  158. //
  159. // Unlike LISP, this mapcar does not return anything!
  160. //
  161. // "func" is the procedure to apply to each element of the List.
  162. //----------------------------------------------------------------------
  163. void List::Mapcar(VoidFunctionPtr func)
  164. {
  165.   for (ListElement *ptr = first; ptr != NULL; ptr = ptr->next)
  166.     (*func)((long)ptr->item);
  167. }
  168. //----------------------------------------------------------------------
  169. // List::IsEmpty
  170. //      Returns TRUE if the List is empty (has no items).
  171. //----------------------------------------------------------------------
  172. int List::IsEmpty() 
  173. {
  174.   if (first == NULL)
  175.     return TRUE;
  176.   else
  177.     return FALSE;
  178. }
  179. //----------------------------------------------------------------------
  180. // List::SortedInsert
  181. //      Insert an "item" into a List, so that the List elements are
  182. // sorted in increasing order by "sortKey".
  183. //      
  184. // Allocate a ListElement to keep track of the item.
  185. //      If the List is empty, then this will be the only element.
  186. // Otherwise, walk through the List, one element at a time,
  187. // to find where the new item should be placed.
  188. //
  189. // "item" is the thing to put on the List, it can be a pointer to 
  190. // anything.
  191. // "sortKey" is the priority of the item.
  192. //----------------------------------------------------------------------
  193. void List::SortedInsert(void *item, float sortKey)
  194. {
  195.   ListElement *element = new ListElement(item, sortKey);
  196.   ListElement *ptr;         // keep track
  197.   
  198.   if (IsEmpty()) 
  199.     { // List is empty, put in front
  200.       first = element;
  201.       last = element;
  202.     } 
  203.   else if (sortKey < first->key) 
  204.     { // item goes on front of List
  205.       element->next = first;
  206.       first = element;
  207.     } 
  208.   else 
  209.     { // look for first elt in List bigger than item
  210.       for (ptr = first; ptr->next != NULL; ptr = ptr->next) {
  211. if (sortKey < ptr->next->key) 
  212.   {
  213.     element->next = ptr->next;
  214.     ptr->next = element;
  215.     return;
  216.   }
  217.       }
  218.       last->next = element; // item goes at end of List
  219.       last = element;
  220.     }
  221.   
  222.   size++;
  223. }
  224. //----------------------------------------------------------------------
  225. // List::SortedRemove
  226. //      Remove the first "item" from the front of a sorted List.
  227. // 
  228. // Returns:
  229. // Pointer to removed item, NULL if nothing on the List.
  230. // Sets *keyPtr to the priority value of the removed item
  231. // (this is needed by interrupt.cc, for instance).
  232. //
  233. // "keyPtr" is a pointer to the location in which to store the 
  234. // priority of the removed item.
  235. //----------------------------------------------------------------------
  236. void *List::SortedRemove(float *keyPtr)
  237. {
  238.   ListElement *element = first;
  239.   void *thing;
  240.   
  241.   if (IsEmpty()) 
  242.     return NULL;
  243.   
  244.   thing = first->item;
  245.   if (first == last) 
  246.     { // List had one item, now has none 
  247.       first = NULL;
  248.       last = NULL;
  249.     } 
  250.   else 
  251.     first = element->next;
  252.   if (keyPtr != NULL)
  253.     *keyPtr = element->key;
  254.   delete element;
  255.   
  256.   size--;
  257.   return thing;
  258. }
  259. //----------------------------------------------------------------------
  260. // List::MinKey
  261. //      Return the key of the item in the front of a sorted List.
  262. // 
  263. // Returns :
  264. // -1 if List is empty
  265. //----------------------------------------------------------------------
  266. float List::MinKey()
  267. {
  268.   if (IsEmpty())
  269.     return -1;
  270.   else
  271.     return first->key;
  272. }
  273. //----------------------------------------------------------------------
  274. // List::SetInsert
  275. //      Insert "key" into a List, so that the List elements are unique.
  276. //
  277. // Returns :
  278. //      TRUE if "key" inserted, FALSE o/w
  279. //
  280. // Caveat :
  281. //      Does not allocate space for key! Provided by calling function.
  282. //      If FALSE, calling function should delete allocated space.
  283. //
  284. // "key" is the thing to put on the List.
  285. //      "eq" is the comparison function used to compare two items.
  286. //----------------------------------------------------------------------
  287. int List::SetInsert(void *key, CompareFunction eq)
  288. {
  289.   if (IsPresent(key, eq))
  290.     return FALSE;
  291.   Prepend(key);
  292.   return TRUE;
  293. }
  294. //----------------------------------------------------------------------
  295. // List::SetRemove
  296. //      Remove "key" from List.
  297. // 
  298. // Returns :
  299. //      handle to "key" in list if removed, NULL o/w
  300. //
  301. // Caveat :
  302. //      if not NULL, Calling function should delete allocated space.
  303. //
  304. // "key" is the item to be removed.
  305. //      "eq" is the comparison function used to compare two items.
  306. //----------------------------------------------------------------------
  307. void *List::SetRemove(void *key, CompareFunction eq)
  308. {
  309.   ListElement *prev, *curr;
  310.   void *thing;
  311.   if (!IsPresent(key, eq))
  312.     return NULL;
  313.  
  314.   for (prev = NULL, curr = first; 
  315.        curr != NULL; 
  316.        prev = curr, curr = curr->next)
  317.     if ((*eq)(key, curr->item))
  318.       break;
  319.   assert(curr != NULL); // Since its present we'd better find it
  320.   if (curr == first)
  321.     first = curr->next;
  322.   else
  323.     prev->next = curr->next;
  324.   
  325.   if (curr == last)
  326.     last = prev;
  327.   thing = curr->item;
  328.   delete curr;
  329.   size--;
  330.   return thing;
  331. }
  332. //----------------------------------------------------------------------
  333. // List::IsPresent
  334. //      Is "key" there in the Set
  335. //
  336. // Returns :
  337. //      handle to the "key" in list (NULL if not found)
  338. //      
  339. // "key" is the item to be searched.
  340. //      "eq" is the comparison function used to compare two items.
  341. //----------------------------------------------------------------------
  342. void *List::IsPresent(void *key, CompareFunction eq)
  343. {
  344.   ListElement *ptr;
  345.   for (ptr = first; ptr != NULL; ptr = ptr->next) // Check all items
  346.     if ((*eq)(key, ptr->item))
  347.       return ptr->item;
  348.   return NULL;
  349. }
  350. //----------------------------------------------------------------------
  351. // List::Purge
  352. //      Remove all elements with (key eq "key") from the Set
  353. //
  354. //      "key" is the item to be searched and deleted.
  355. //      "eq" is the comparison function used to compare two items.
  356. //      "destroy" is the function used to delete the purged "key".
  357. //----------------------------------------------------------------------
  358. void List::Purge(void *key, CompareFunction eq, VoidFunctionPtr destroy)
  359. {
  360.   ListElement *prev, *curr, *temp;
  361.   void *thing;
  362.   for (prev = NULL, curr = first; curr != NULL; ) // Check all items
  363.     if ((*eq)(key, curr->item))
  364.       {
  365.         if (curr == first)
  366.           first = curr->next;
  367.         else
  368.           prev->next = curr->next;
  369. if (curr == last)
  370.           last = prev;
  371.         thing = curr->item;
  372. temp = curr;
  373. curr = curr->next;
  374.         (* destroy)((long) thing);
  375.         delete temp;
  376.         size--;
  377.       }
  378.   else
  379.     {
  380.       prev = curr;
  381.       curr = curr->next;
  382.     }
  383. }