00001 
00032 #ifndef LL_LLLOCALIDHASHMAP_H
00033 #define LL_LLLOCALIDHASHMAP_H
00034 
00035 #include "stdtypes.h"
00036 #include "llerror.h"
00037 
00038 const S32 MAX_ITERS = 4;
00039 
00040 
00041 
00042 
00043 
00044 
00045 template <class DATA, int SIZE>
00046 class LLLocalIDHashNode
00047 {
00048 public:
00049         LLLocalIDHashNode();
00050 
00051 public:
00052         S32 mCount;
00053         U32     mKey[SIZE];
00054         DATA mData[SIZE];
00055         LLLocalIDHashNode<DATA, SIZE> *mNextNodep;
00056 };
00057 
00058 
00059 
00060 
00061 
00062 template <class DATA, int SIZE>
00063 LLLocalIDHashNode<DATA, SIZE>::LLLocalIDHashNode()
00064 {
00065         mCount = 0;
00066         mNextNodep = NULL;
00067 }
00068 
00069 
00070 
00071 
00072 template <class DATA_TYPE, int SIZE>
00073 class LLLocalIDHashMap;
00074 
00075 template <class DATA_TYPE, int SIZE>
00076 class LLLocalIDHashMapIter
00077 {
00078 public:
00079         LLLocalIDHashMapIter(LLLocalIDHashMap<DATA_TYPE, SIZE> *hash_mapp);
00080         ~LLLocalIDHashMapIter();
00081 
00082         void setMap(LLLocalIDHashMap<DATA_TYPE, SIZE> *hash_mapp);
00083         inline void first();
00084         inline void next();
00085         inline DATA_TYPE& current(); 
00086         inline BOOL done() const;
00087         inline S32  currentBin() const;
00088         inline void setBin(S32 bin);
00089 
00090         DATA_TYPE& operator*() const
00091         {
00092                 return mCurHashNodep->mData[mCurHashNodeKey];
00093         }
00094         DATA_TYPE* operator->() const
00095         {
00096                 return &(operator*());
00097         }
00098 
00099         LLLocalIDHashMap<DATA_TYPE, SIZE> *mHashMapp;
00100         LLLocalIDHashNode<DATA_TYPE, SIZE> *mCurHashNodep;
00101 
00102         S32 mCurHashMapNodeNum;
00103         S32 mCurHashNodeKey;
00104 
00105         DATA_TYPE mNull;
00106 
00107         S32 mIterID;
00108 };
00109 
00110 
00111 
00112 template <class DATA_TYPE, int SIZE>
00113 class LLLocalIDHashMap
00114 {
00115 public:
00116         friend class LLLocalIDHashMapIter<DATA_TYPE, SIZE>;
00117 
00118         LLLocalIDHashMap(); 
00119                                                 
00120         
00121         LLLocalIDHashMap(const DATA_TYPE &null_data);
00122         
00123         
00124         ~LLLocalIDHashMap();
00125 
00126         inline DATA_TYPE &get(const U32 local_id);
00127         inline BOOL check(const U32 local_id) const;
00128         inline DATA_TYPE &set(const U32 local_id, const DATA_TYPE data);
00129         inline BOOL remove(const U32 local_id);
00130         void removeAll();
00131 
00132         void setNull(const DATA_TYPE data) { mNull = data; }
00133 
00134         inline S32 getLength() const; 
00135 
00136         void dumpIter();
00137         void dumpBin(U32 bin);
00138 
00139 protected:
00140         
00141         void addIter(LLLocalIDHashMapIter<DATA_TYPE, SIZE> *iter);
00142         void removeIter(LLLocalIDHashMapIter<DATA_TYPE, SIZE> *iter);
00143 
00144         
00145         
00146         BOOL removeWithShift(const U32 local_id);
00147 
00148 protected:
00149         LLLocalIDHashNode<DATA_TYPE, SIZE> mNodes[256];
00150 
00151         S32 mIterCount;
00152         LLLocalIDHashMapIter<DATA_TYPE, SIZE> *mIters[MAX_ITERS];
00153 
00154         DATA_TYPE mNull;
00155 };
00156 
00157 
00158 
00159 
00160 
00161 
00162 template <class DATA_TYPE, int SIZE>
00163 LLLocalIDHashMap<DATA_TYPE, SIZE>::LLLocalIDHashMap()
00164 :       mIterCount(0),
00165         mNull()
00166 {
00167         S32 i;
00168         for (i = 0; i < MAX_ITERS; i++)
00169         {
00170                 mIters[i] = NULL;
00171         }
00172 }
00173 
00174 template <class DATA_TYPE, int SIZE>
00175 LLLocalIDHashMap<DATA_TYPE, SIZE>::LLLocalIDHashMap(const DATA_TYPE &null_data)
00176 :       mIterCount(0),
00177         mNull(null_data)
00178 {
00179         S32 i;
00180         for (i = 0; i < MAX_ITERS; i++)
00181         {
00182                 mIters[i] = NULL;
00183         }
00184 }
00185 
00186 template <class DATA_TYPE, int SIZE>
00187 LLLocalIDHashMap<DATA_TYPE, SIZE>::~LLLocalIDHashMap()
00188 {
00189         S32 i;
00190         for (i = 0; i < MAX_ITERS; i++)
00191         {
00192                 if (mIters[i])
00193                 {
00194                         mIters[i]->mHashMapp = NULL;
00195                         mIterCount--;
00196                 }
00197         }
00198         removeAll();
00199 }
00200 
00201 template <class DATA_TYPE, int SIZE>
00202 void LLLocalIDHashMap<DATA_TYPE, SIZE>::removeAll()
00203 {
00204         S32 bin;
00205         for (bin = 0; bin < 256; bin++)
00206         {
00207                 LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[bin];
00208 
00209                 BOOL first = TRUE;
00210                 do 
00211                 {
00212                         S32 i;
00213                         const S32 count = nodep->mCount;
00214 
00215                         
00216                         for (i = 0; i < count; i++)
00217                         {
00218                                 nodep->mData[i] = mNull;
00219                         }
00220 
00221                         nodep->mCount = 0;
00222                         
00223 
00224                         LLLocalIDHashNode<DATA_TYPE, SIZE>* curp = nodep;
00225                         nodep = nodep->mNextNodep;
00226 
00227                         
00228                         if (first)
00229                         {
00230                                 first = FALSE;
00231                                 curp->mNextNodep = NULL;
00232                         }
00233                         else
00234                         {
00235                                 delete curp;
00236                         }
00237                 } while (nodep);
00238         }
00239 }
00240 
00241 template <class DATA_TYPE, int SIZE>
00242 void LLLocalIDHashMap<DATA_TYPE, SIZE>::dumpIter()
00243 {
00244         std::cout << "Hash map with " << mIterCount << " iterators" << std::endl;
00245 
00246         std::cout << "Hash Map Iterators:" << std::endl;
00247         S32 i;
00248         for (i = 0; i < MAX_ITERS; i++)
00249         {
00250                 if (mIters[i])
00251                 {
00252                         llinfos << i << " " << mIters[i]->mCurHashNodep << " " << mIters[i]->mCurHashNodeKey << llendl;
00253                 }
00254                 else
00255                 {
00256                         llinfos << i << "null" << llendl;
00257                 }
00258         }
00259 }
00260 
00261 template <class DATA_TYPE, int SIZE>
00262 void LLLocalIDHashMap<DATA_TYPE, SIZE>::dumpBin(U32 bin)
00263 {
00264         std::cout << "Dump bin " << bin << std::endl;
00265 
00266         LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[bin];
00267         S32 node = 0;
00268         do 
00269         {
00270                 std::cout << "Bin " << bin 
00271                         << " node " << node
00272                         << " count " << nodep->mCount
00273                         << " contains " << std::flush;
00274 
00275                 S32 i;
00276                 for (i = 0; i < nodep->mCount; i++)
00277                 {
00278                         std::cout << nodep->mData[i] << " " << std::flush;
00279                 }
00280 
00281                 std::cout << std::endl;
00282 
00283                 nodep = nodep->mNextNodep;
00284                 node++;
00285         } while (nodep);
00286 }
00287 
00288 template <class DATA_TYPE, int SIZE>
00289 inline S32 LLLocalIDHashMap<DATA_TYPE, SIZE>::getLength() const
00290 {
00291         S32 count = 0;
00292         S32 bin;
00293         for (bin = 0; bin < 256; bin++)
00294         {
00295                 const LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[bin];
00296                 while (nodep)
00297                 {
00298                         count += nodep->mCount;
00299                         nodep = nodep->mNextNodep;
00300                 }
00301         }
00302         return count;
00303 }
00304 
00305 template <class DATA_TYPE, int SIZE>
00306 inline DATA_TYPE &LLLocalIDHashMap<DATA_TYPE, SIZE>::get(const U32 local_id)
00307 {
00308         LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[local_id & 0xff];
00309 
00310         do 
00311         {
00312                 S32 i;
00313                 const S32 count = nodep->mCount;
00314 
00315                 
00316                 for (i = 0; i < count; i++)
00317                 {
00318                         if (nodep->mKey[i] == local_id)
00319                         {
00320                                 
00321                                 return nodep->mData[i];
00322                         }
00323                 }
00324 
00325                 
00326                 nodep = nodep->mNextNodep;
00327         } while (nodep);
00328 
00329         return mNull;
00330 }
00331 
00332 
00333 template <class DATA_TYPE, int SIZE>
00334 inline BOOL LLLocalIDHashMap<DATA_TYPE, SIZE>::check(const U32 local_id) const
00335 {
00336         const LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[local_id & 0xff];
00337 
00338         do 
00339         {
00340                 S32 i;
00341                 const S32 count = nodep->mCount;
00342 
00343                 
00344                 for (i = 0; i < count; i++)
00345                 {
00346                         if (nodep->mKey[i] == local_id)
00347                         {
00348                                 
00349                                 return TRUE;
00350                         }
00351                 }
00352 
00353                 
00354                 nodep = nodep->mNextNodep;
00355         } while (nodep);
00356 
00357         
00358         return FALSE;
00359 }
00360 
00361 
00362 template <class DATA_TYPE, int SIZE>
00363 inline DATA_TYPE &LLLocalIDHashMap<DATA_TYPE, SIZE>::set(const U32 local_id, const DATA_TYPE data)
00364 {
00365         
00366         
00367         
00368 
00369         LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[local_id & 0xff];
00370 
00371         while (1)
00372         {
00373                 const S32 count = nodep->mCount;
00374 
00375                 S32 i;
00376                 for (i = 0; i < count; i++)
00377                 {
00378                         if (nodep->mKey[i] == local_id)
00379                         {
00380                                 
00381                                 
00382                                 nodep->mData[i] = data;
00383                                 return nodep->mData[i];
00384                         }
00385                 }
00386                 if (!nodep->mNextNodep)
00387                 {
00388                         
00389                         if (i < SIZE)
00390                         {
00391                                 
00392                                 
00393                                 nodep->mKey[i] = local_id;
00394                                 nodep->mData[i] = data;
00395                                 nodep->mCount++;
00396 
00397                                 return nodep->mData[i];
00398                         }
00399                         else
00400                         {
00401                                 
00402                                 nodep->mNextNodep = new LLLocalIDHashNode<DATA_TYPE, SIZE>;
00403                                 nodep->mNextNodep->mKey[0] = local_id;
00404                                 nodep->mNextNodep->mData[0] = data;
00405                                 nodep->mNextNodep->mCount = 1;
00406 
00407                                 return nodep->mNextNodep->mData[0];
00408                         }
00409                 }
00410 
00411                 
00412                 nodep = nodep->mNextNodep;
00413         }
00414 }
00415 
00416 
00417 template <class DATA_TYPE, int SIZE>
00418 inline BOOL LLLocalIDHashMap<DATA_TYPE, SIZE>::remove(const U32 local_id)
00419 {
00420         
00421         
00422         
00423         
00424         
00425 
00426         const S32 node_index = local_id & 0xff;
00427 
00428         LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[node_index];
00429 
00430         
00431         do 
00432         {
00433                 const S32 count = nodep->mCount;
00434 
00435                 S32 i;
00436                 for (i = 0; i < count; i++)
00437                 {
00438                         if (nodep->mKey[i] == local_id)
00439                         {
00440                                 
00441                                 
00442                                 
00443                                 
00444                                 
00445                                 
00446                                 BOOL need_shift = FALSE;
00447                                 S32 cur_iter;
00448                                 if (mIterCount)
00449                                 {
00450                                         for (cur_iter = 0; cur_iter < MAX_ITERS; cur_iter++)
00451                                         {
00452                                                 if (mIters[cur_iter])
00453                                                 {
00454                                                         
00455                                                         
00456                                                         
00457                                                         
00458                                                         if (mIters[cur_iter]->mCurHashMapNodeNum == node_index)
00459                                                         {
00460                                                                 if ((mIters[cur_iter]->mCurHashNodep == nodep)
00461                                                                         && (mIters[cur_iter]->mCurHashNodeKey == i))
00462                                                                 {
00463                                                                         
00464                                                                         
00465                                                                 }
00466                                                                 else
00467                                                                 {
00468                                                                         
00469                                                                         
00470                                                                         
00471                                                                         
00472                                                                         need_shift = TRUE;
00473                                                                 }
00474                                                         }
00475                                                 }
00476                                         }
00477                                 }
00478 
00479                                 
00480                                 if (need_shift)
00481                                 {
00482                                         return removeWithShift(local_id);
00483                                 }
00484 
00485                                 
00486                                 
00487                                 for (cur_iter = 0; cur_iter < MAX_ITERS; cur_iter++)
00488                                 {
00489                                         if (mIters[cur_iter])
00490                                         {
00491                                                 
00492                                                 
00493                                                 
00494                                                 
00495                                                 if (mIters[cur_iter]->mCurHashMapNodeNum == node_index)
00496                                                 {
00497                                                         if ((mIters[cur_iter]->mCurHashNodep == nodep)
00498                                                                 && (mIters[cur_iter]->mCurHashNodeKey == i))
00499                                                         {
00500                                                                 
00501                                                                 
00502                                                                 if (nodep->mCount > 1)
00503                                                                 {
00504                                                                         
00505                                                                         
00506                                                                         mIters[cur_iter]->mCurHashNodeKey--;
00507                                                                 }
00508                                                                 else
00509                                                                 {
00510                                                                         
00511                                                                         
00512                                                                         
00513                                                                         
00514                                                                         mIters[cur_iter]->next();
00515                                                                         mIters[cur_iter]->mCurHashNodeKey--;
00516                                                                 }
00517                                                         }
00518                                                 }
00519                                         }
00520                                 }
00521 
00522                                 
00523                                 
00524                                 
00525                                 
00526 
00527                                 LLLocalIDHashNode<DATA_TYPE, SIZE> *prevp = &mNodes[node_index];
00528                                 LLLocalIDHashNode<DATA_TYPE, SIZE> *lastp = prevp;
00529 
00530                                 
00531                                 while (lastp->mNextNodep)
00532                                 {
00533                                         prevp = lastp;
00534                                         lastp = lastp->mNextNodep;
00535                                 }
00536 
00537                                 
00538                                 nodep->mKey[i] = lastp->mKey[lastp->mCount - 1];
00539                                 nodep->mData[i] = lastp->mData[lastp->mCount - 1];
00540 
00541                                 
00542                                 lastp->mCount--;
00543                                 lastp->mData[lastp->mCount] = mNull;
00544 
00545                                 if (!lastp->mCount)
00546                                 {
00547                                         
00548                                         if (lastp != &mNodes[local_id & 0xff])
00549                                         {
00550                                                 
00551                                                 
00552                                                 
00553                                                 prevp->mNextNodep = NULL;
00554                                                 delete lastp;
00555                                         }
00556                                 }
00557 
00558                                 return TRUE;
00559                         }
00560                 }
00561 
00562                 
00563                 nodep = nodep->mNextNodep;
00564         } while (nodep);
00565 
00566         return FALSE;
00567 }
00568 
00569 template <class DATA_TYPE, int SIZE>
00570 BOOL LLLocalIDHashMap<DATA_TYPE, SIZE>::removeWithShift(const U32 local_id)
00571 {
00572         const S32 node_index = local_id & 0xFF;
00573         LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[node_index];
00574         LLLocalIDHashNode<DATA_TYPE, SIZE>* prevp = NULL;
00575         BOOL found = FALSE;
00576 
00577         do 
00578         {
00579                 const S32 count = nodep->mCount;
00580                 S32 i;
00581                 for (i = 0; i < count; i++)
00582                 {
00583                         if (nodep->mKey[i] == local_id)
00584                         {
00585                                 
00586                                 
00587                                 found = TRUE;
00588                         }
00589 
00590                         if (found)
00591                         {
00592                                 
00593                                 
00594                                 S32 cur_iter;
00595                                 for (cur_iter = 0; cur_iter <MAX_ITERS; cur_iter++)
00596                                 {
00597                                         LLLocalIDHashMapIter<DATA_TYPE, SIZE>* iter;
00598                                         iter = mIters[cur_iter];
00599                                         
00600                                         if (iter
00601                                                 && iter->mCurHashMapNodeNum == node_index
00602                                                 && iter->mCurHashNodep == nodep
00603                                                 && iter->mCurHashNodeKey == i)
00604                                         {
00605                                                 if (i > 0)
00606                                                 {
00607                                                         
00608                                                         
00609                                                         iter->mCurHashNodeKey--;
00610                                                 }
00611                                                 else if (prevp)
00612                                                 {
00613                                                         
00614                                                         iter->mCurHashNodep = prevp;
00615                                                         iter->mCurHashNodeKey = prevp->mCount - 1;
00616                                                 }
00617                                                 else
00618                                                 {
00619                                                         
00620                                                         
00621 
00622                                                         
00623                                                         
00624                                                         
00625                                                         iter->mCurHashNodeKey = -1;
00626                                                 }
00627                                         }
00628                                 }
00629 
00630                                 
00631                                 if (i < count-1)
00632                                 {
00633                                         
00634                                         
00635                                         nodep->mKey[i] = nodep->mKey[i+1];
00636                                         nodep->mData[i] = nodep->mData[i+1];
00637                                 }
00638                                 else if (nodep->mNextNodep)
00639                                 {
00640                                         
00641                                         
00642                                         nodep->mKey[i] = nodep->mNextNodep->mKey[0];
00643                                         nodep->mData[i] = nodep->mNextNodep->mData[0];
00644                                 }
00645                                 else
00646                                 {
00647                                         
00648                                         
00649                                         nodep->mKey[i] = 0;
00650                                         nodep->mData[i] = mNull;
00651                                 }
00652                         }
00653                 }
00654 
00655                 
00656                 if (found
00657                         && !nodep->mNextNodep)
00658                 {
00659                         
00660                         nodep->mCount--;
00661 
00662                         if (nodep->mCount == 0)
00663                         {
00664                                 
00665                                 if (nodep != &mNodes[node_index])
00666                                 {
00667                                         
00668                                         llassert(prevp);
00669 
00670                                         
00671                                         
00672                                         
00673                                         prevp->mNextNodep = NULL;
00674                                         delete nodep;
00675                                         nodep = NULL;
00676                                 }
00677                         }
00678 
00679                         
00680                         return found;
00681                 }
00682 
00683                 prevp = nodep;
00684                 nodep = nodep->mNextNodep;
00685         } while (nodep);
00686 
00687         return found;
00688 }
00689 
00690 template <class DATA_TYPE, int SIZE>
00691 void LLLocalIDHashMap<DATA_TYPE, SIZE>::removeIter(LLLocalIDHashMapIter<DATA_TYPE, SIZE> *iter)
00692 {
00693         S32 i;
00694         for (i = 0; i < MAX_ITERS; i++)
00695         {
00696                 if (mIters[i] == iter)
00697                 {
00698                         mIters[i] = NULL;
00699                         mIterCount--;
00700                         return;
00701                 }
00702         }
00703         llerrs << "Iterator " << iter << " not found for removal in hash map!" << llendl;
00704 }
00705 
00706 template <class DATA_TYPE, int SIZE>
00707 void LLLocalIDHashMap<DATA_TYPE, SIZE>::addIter(LLLocalIDHashMapIter<DATA_TYPE, SIZE> *iter)
00708 {
00709         S32 i;
00710         for (i = 0; i < MAX_ITERS; i++)
00711         {
00712                 if (mIters[i] == NULL)
00713                 {
00714                         mIters[i] = iter;
00715                         mIterCount++;
00716                         return;
00717                 }
00718         }
00719         llerrs << "More than " << MAX_ITERS << " iterating over a map simultaneously!" << llendl;
00720 }
00721 
00722 
00723 
00724 
00725 
00726 
00727 template <class DATA_TYPE, int SIZE>
00728 LLLocalIDHashMapIter<DATA_TYPE, SIZE>::LLLocalIDHashMapIter(LLLocalIDHashMap<DATA_TYPE, SIZE> *hash_mapp)
00729 {
00730         mHashMapp = NULL;
00731         setMap(hash_mapp);
00732 }
00733 
00734 template <class DATA_TYPE, int SIZE>
00735 LLLocalIDHashMapIter<DATA_TYPE, SIZE>::~LLLocalIDHashMapIter()
00736 {
00737         if (mHashMapp)
00738         {
00739                 mHashMapp->removeIter(this);
00740         }
00741 }
00742 
00743 template <class DATA_TYPE, int SIZE>
00744 void LLLocalIDHashMapIter<DATA_TYPE, SIZE>::setMap(LLLocalIDHashMap<DATA_TYPE, SIZE> *hash_mapp)
00745 {
00746         if (mHashMapp)
00747         {
00748                 mHashMapp->removeIter(this);
00749         }
00750         mHashMapp = hash_mapp;
00751         if (mHashMapp)
00752         {
00753                 mHashMapp->addIter(this);
00754         }
00755 
00756         mCurHashNodep = NULL;
00757         mCurHashMapNodeNum = -1;
00758         mCurHashNodeKey = 0;
00759 }
00760 
00761 template <class DATA_TYPE, int SIZE>
00762 inline void LLLocalIDHashMapIter<DATA_TYPE, SIZE>::first()
00763 {
00764         
00765         S32 i;
00766         for (i = 0; i < 256; i++)
00767         {
00768                 if (mHashMapp->mNodes[i].mCount)
00769                 {
00770 
00771                         mCurHashNodep = &mHashMapp->mNodes[i];
00772                         mCurHashMapNodeNum = i;
00773                         mCurHashNodeKey = 0;
00774                         
00775                         return;
00776                 }
00777         }
00778 
00779         
00780         mCurHashNodep = NULL;
00781         
00782         return;
00783 }
00784 
00785 template <class DATA_TYPE, int SIZE>
00786 inline BOOL LLLocalIDHashMapIter<DATA_TYPE, SIZE>::done() const
00787 {
00788         return mCurHashNodep ? FALSE : TRUE;
00789 }
00790 
00791 template <class DATA_TYPE, int SIZE>
00792 inline S32 LLLocalIDHashMapIter<DATA_TYPE, SIZE>::currentBin() const
00793 {
00794         if (  (mCurHashMapNodeNum > 255)
00795                 ||(mCurHashMapNodeNum < 0))
00796         {
00797                 return 0;
00798         }
00799         else
00800         {
00801                 return mCurHashMapNodeNum;
00802         }
00803 }
00804 
00805 template <class DATA_TYPE, int SIZE>
00806 inline void LLLocalIDHashMapIter<DATA_TYPE, SIZE>::setBin(S32 bin)
00807 {
00808         
00809         S32 i;
00810         bin = llclamp(bin, 0, 255);
00811         for (i = bin; i < 256; i++)
00812         {
00813                 if (mHashMapp->mNodes[i].mCount)
00814                 {
00815 
00816                         mCurHashNodep = &mHashMapp->mNodes[i];
00817                         mCurHashMapNodeNum = i;
00818                         mCurHashNodeKey = 0;
00819                         return;
00820                 }
00821         }
00822         for (i = 0; i < bin; i++)
00823         {
00824                 if (mHashMapp->mNodes[i].mCount)
00825                 {
00826 
00827                         mCurHashNodep = &mHashMapp->mNodes[i];
00828                         mCurHashMapNodeNum = i;
00829                         mCurHashNodeKey = 0;
00830                         return;
00831                 }
00832         }
00833         
00834         mCurHashNodep = NULL;
00835 }
00836 
00837 template <class DATA_TYPE, int SIZE>
00838 inline DATA_TYPE &LLLocalIDHashMapIter<DATA_TYPE, SIZE>::current()
00839 {
00840         if (!mCurHashNodep)
00841         {
00842                 return mNull;
00843         }
00844         return mCurHashNodep->mData[mCurHashNodeKey];
00845 }
00846 
00847 template <class DATA_TYPE, int SIZE>
00848 inline void LLLocalIDHashMapIter<DATA_TYPE, SIZE>::next()
00849 {
00850         
00851         if (!mCurHashNodep)
00852         {
00853                 
00854                 return;
00855         }
00856 
00857         
00858         mCurHashNodeKey++;
00859         if (mCurHashNodeKey < mCurHashNodep->mCount)
00860         {
00861                 
00862                 
00863                 return;
00864         }
00865 
00866         
00867         mCurHashNodep = mCurHashNodep->mNextNodep;
00868         if (mCurHashNodep)
00869         {
00870                 
00871                 mCurHashNodeKey = 0;
00872                 
00873                 return;
00874         }
00875 
00876         
00877         mCurHashMapNodeNum++;
00878 
00879         S32 i;
00880         for (i = mCurHashMapNodeNum; i < 256; i++)
00881         {
00882                 if (mHashMapp->mNodes[i].mCount)
00883                 {
00884                         
00885                         mCurHashNodep = &mHashMapp->mNodes[i];
00886                         mCurHashMapNodeNum = i;
00887                         mCurHashNodeKey = 0;
00888                         
00889                         return;
00890                 }
00891         }
00892 
00893         
00894         mCurHashNodep = NULL;
00895         mHashMapp->mIterCount--; 
00896         
00897         return;
00898 }
00899 
00900 #endif // LL_LLLOCALIDHASHMAP_H