00001 // $Id: XrdSutBuckList.cc 30949 2009-11-02 16:37:58Z ganis $ 00002 00003 const char *XrdSutBuckListCVSID = "$Id: XrdSutBuckList.cc 30949 2009-11-02 16:37:58Z ganis $"; 00004 /******************************************************************************/ 00005 /* */ 00006 /* X r d S u t B u c k L i s t . c c */ 00007 /* */ 00008 /* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */ 00009 /* All Rights Reserved. See XrdInfo.cc for complete License Terms */ 00010 /* Produced by Andrew Hanushevsky for Stanford University under contract */ 00011 /* DE-AC03-76-SFO0515 with the Department of Energy */ 00012 /******************************************************************************/ 00013 00014 #include <XrdSut/XrdSutBuckList.hh> 00015 00016 /******************************************************************************/ 00017 /* */ 00018 /* Light single-linked list for managing buckets inside the exchanged */ 00019 /* buffer */ 00020 /* */ 00021 /******************************************************************************/ 00022 00023 //___________________________________________________________________________ 00024 XrdSutBuckList::XrdSutBuckList(XrdSutBucket *b) 00025 { 00026 // Constructor 00027 00028 previous = current = begin = end = 0; 00029 size = 0; 00030 00031 if (b) { 00032 XrdSutBuckListNode *f = new XrdSutBuckListNode(b,0); 00033 current = begin = end = f; 00034 size++; 00035 } 00036 } 00037 00038 //___________________________________________________________________________ 00039 XrdSutBuckList::~XrdSutBuckList() 00040 { 00041 // Destructor 00042 00043 XrdSutBuckListNode *n = 0; 00044 XrdSutBuckListNode *b = begin; 00045 while (b) { 00046 n = b->Next(); 00047 delete (b); 00048 b = n; 00049 } 00050 } 00051 00052 //___________________________________________________________________________ 00053 XrdSutBuckListNode *XrdSutBuckList::Find(XrdSutBucket *b) 00054 { 00055 // Find node containing bucket b 00056 00057 XrdSutBuckListNode *nd = begin; 00058 for (; nd; nd = nd->Next()) { 00059 if (nd->Buck() == b) 00060 return nd; 00061 } 00062 return (XrdSutBuckListNode *)0; 00063 } 00064 00065 //___________________________________________________________________________ 00066 void XrdSutBuckList::PutInFront(XrdSutBucket *b) 00067 { 00068 // Add at the beginning of the list 00069 // Check to avoid duplicates 00070 00071 if (!Find(b)) { 00072 XrdSutBuckListNode *nb = new XrdSutBuckListNode(b,begin); 00073 begin = nb; 00074 if (!end) 00075 end = nb; 00076 size++; 00077 } 00078 } 00079 00080 //___________________________________________________________________________ 00081 void XrdSutBuckList::PushBack(XrdSutBucket *b) 00082 { 00083 // Add at the end of the list 00084 // Check to avoid duplicates 00085 00086 if (!Find(b)) { 00087 XrdSutBuckListNode *nb = new XrdSutBuckListNode(b,0); 00088 if (!begin) 00089 begin = nb; 00090 if (end) 00091 end->SetNext(nb); 00092 end = nb; 00093 size++; 00094 } 00095 } 00096 00097 //___________________________________________________________________________ 00098 void XrdSutBuckList::Remove(XrdSutBucket *b) 00099 { 00100 // Remove node containing bucket b 00101 00102 XrdSutBuckListNode *curr = current; 00103 XrdSutBuckListNode *prev = previous; 00104 00105 if (!curr || curr->Buck() != b || (prev && curr != prev->Next())) { 00106 // We need first to find the address 00107 curr = begin; 00108 prev = 0; 00109 for (; curr; curr = curr->Next()) { 00110 if (curr->Buck() == b) 00111 break; 00112 prev = curr; 00113 } 00114 } 00115 00116 // The bucket is not in the list 00117 if (!curr) 00118 return; 00119 00120 // Now we have all the information to remove 00121 if (prev) { 00122 current = curr->Next(); 00123 prev->SetNext(current); 00124 previous = curr; 00125 } else if (curr == begin) { 00126 // First buffer 00127 current = curr->Next(); 00128 begin = current; 00129 previous = 0; 00130 } 00131 00132 // Cleanup and update size 00133 delete curr; 00134 size--; 00135 } 00136 00137 //___________________________________________________________________________ 00138 XrdSutBucket *XrdSutBuckList::Begin() 00139 { 00140 // Iterator functionality: init 00141 00142 previous = 0; 00143 current = begin; 00144 if (current) 00145 return current->Buck(); 00146 return (XrdSutBucket *)0; 00147 } 00148 00149 //___________________________________________________________________________ 00150 XrdSutBucket *XrdSutBuckList::Next() 00151 { 00152 // Iterator functionality: get next 00153 00154 previous = current; 00155 if (current) { 00156 current = current->Next(); 00157 if (current) 00158 return current->Buck(); 00159 } 00160 return (XrdSutBucket *)0; 00161 }