HashTableIterator.inl
Go to the documentation of this file.00001 //*** HashTableIterator.inl *** 00002 00003 #include "Debug.h" 00004 00005 //*** Constructor *** 00006 00007 template<class HASHTABLEKEY, class TYPE> 00008 HashTableIterator<HASHTABLEKEY, TYPE>::HashTableIterator(const HashTable<HASHTABLEKEY, TYPE>& table): 00009 table_(&table), 00010 currentGetIndex_(0) 00011 { 00012 MoveFirst(); 00013 } 00014 00015 00016 //*** MoveFirst *** 00017 00018 template<class HASHTABLEKEY, class TYPE> 00019 void HashTableIterator<HASHTABLEKEY, TYPE>::MoveFirst() 00020 { 00021 if (!table_->items_ || table_->GetItemCount()==0) 00022 { 00023 currentGetIndex_=-1; 00024 return; 00025 } 00026 00027 // Set the current pointers to look at the first slot 00028 currentGetIndex_=0; 00029 00030 // Loop through all the slots until we find one that is in use 00031 while (!table_->items_[currentGetIndex_].inUse && currentGetIndex_<table_->slotCount_) 00032 { 00033 // Proceed to next slot 00034 currentGetIndex_++; 00035 } 00036 } 00037 00038 00039 //*** MoveNext*** 00040 00041 template<class HASHTABLEKEY, class TYPE> 00042 void HashTableIterator<HASHTABLEKEY, TYPE>::MoveNext() 00043 { 00044 if (!table_->items_ || table_->GetItemCount()==0) 00045 { 00046 currentGetIndex_=-1; 00047 return; 00048 } 00049 00050 // Check if we are currently looking at a valid item 00051 if (!IsValid()) 00052 { 00053 // If not, abort and return 0 (no next item found) 00054 return; 00055 } 00056 00057 // Get the next item 00058 currentGetIndex_++; 00059 00060 // Loop through all the slots until we find one that is in use 00061 while (!table_->items_[currentGetIndex_].inUse && currentGetIndex_<table_->slotCount_) 00062 { 00063 // Proceed to next slot 00064 currentGetIndex_++; 00065 } 00066 } 00067 00068 00069 //*** MoveLast *** 00070 00071 template<class HASHTABLEKEY, class TYPE> 00072 void HashTableIterator<HASHTABLEKEY, TYPE>::MoveLast() 00073 { 00074 if (!table_->items_ || table_->GetItemCount()==0) 00075 { 00076 currentGetIndex_=-1; 00077 return; 00078 } 00079 00080 // Set the current index pointers to look at the last slot 00081 currentGetIndex_=table_->slotCount_-1; 00082 00083 // Loop through all the slots until we find one that is in used 00084 while (!table_->items_[currentGetIndex_].inUse && currentGetIndex_>=0) 00085 { 00086 // Proceed to previous slot 00087 currentGetIndex_--; 00088 } 00089 } 00090 00091 00092 //*** MovePrevious *** 00093 00094 template<class HASHTABLEKEY, class TYPE> 00095 void HashTableIterator<HASHTABLEKEY, TYPE>::MovePrevious() 00096 { 00097 // Check if we are currently looking at a valid item 00098 if (!IsValid()) 00099 { 00100 // If not, abort and return 0 (no next item found) 00101 return; 00102 } 00103 00104 // Get the previous item 00105 currentGetIndex_--; 00106 00107 // Loop through all the slots until we find one that is in used 00108 while (!table_->items_[currentGetIndex_].inUse && currentGetIndex_>=0) 00109 { 00110 // Proceed to previous slot 00111 currentGetIndex_--; 00112 } 00113 } 00114 00115 00116 //*** GetCurrent *** 00117 00118 template<class HASHTABLEKEY, class TYPE> 00119 TYPE& HashTableIterator<HASHTABLEKEY, TYPE>::GetCurrent() const 00120 { 00121 Assert(IsValid(),"Invalid get location"); 00122 00123 // Check if we are currently looking at a valid item 00124 if (!IsValid()) 00125 { 00126 // If not, abort and return 0 (no current item found) 00127 static TYPE defaultValue; 00128 return defaultValue; 00129 } 00130 00131 // Return the item 00132 return table_->items_[currentGetIndex_].data; 00133 } 00134 00135 00136 //*** IsValid *** 00137 00138 template<class HASHTABLEKEY, class TYPE> 00139 bool HashTableIterator<HASHTABLEKEY, TYPE>::IsValid() const 00140 { 00141 if (!table_->items_ || table_->GetItemCount()==0) 00142 { 00143 return false; 00144 } 00145 00146 if (currentGetIndex_<0 || currentGetIndex_>=table_->slotCount_) 00147 { 00148 return false; 00149 } 00150 00151 return table_->items_[currentGetIndex_].inUse; 00152 } 00153 00154 00155 //*** Find *** 00156 00157 template<class HASHTABLEKEY, class TYPE> 00158 bool HashTableIterator<HASHTABLEKEY, TYPE>::Find(const HASHTABLEKEY& key) 00159 { 00160 if (!table_->items_ || table_->GetItemCount()==0) 00161 { 00162 currentGetIndex_=-1; 00163 return false; 00164 } 00165 00166 // Find the slot for this key 00167 int slot = key.GetHash() & (table_->slotCount_-1); 00168 int assignedSlot=slot; 00169 int itemsAssignedToSlot=table_->items_[slot].itemCount; 00170 00171 // Loop through the items until we find the one we are looking for 00172 while (itemsAssignedToSlot>0) 00173 { 00174 00175 if (table_->items_[slot].inUse) 00176 { 00177 int thisSlot=table_->items_[slot].key.GetHash()&(table_->slotCount_-1); 00178 if (thisSlot==assignedSlot) 00179 { 00180 itemsAssignedToSlot--; 00181 00182 // Is this the one we're looking for? 00183 if (key.GetHash()==table_->items_[slot].key.GetHash() && key.Compare(&table_->items_[slot].key)) 00184 { 00185 // Yes, so set the current get pointers to point at it 00186 currentGetIndex_=slot; 00187 00188 // Item found 00189 return true; 00190 } 00191 } 00192 } 00193 00194 // Not found the one we're looking for, so continue with the next item 00195 slot=(slot+1)&(table_->slotCount_-1); 00196 } 00197 00198 // We didn't find the item 00199 return false; 00200 } 00201 00202 00203 //*** GetCurrentKey *** 00204 00205 template<class HASHTABLEKEY, class TYPE> 00206 const HASHTABLEKEY& HashTableIterator<HASHTABLEKEY, TYPE>::GetCurrentKey() const 00207 { 00208 // Check if we are looking at a valid item 00209 if (!IsValid()) 00210 { 00211 static HASHTABLEKEY defaultValue; 00212 return defaultValue; 00213 } 00214 00215 // Return the key for the current get item 00216 return table_->items_[currentGetIndex_].key; 00217 } 00218
Reproduction/republishing of any material on this site without permission is strictly prohibited.
