Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages | Examples

SkipList.h

Go to the documentation of this file.
00001 //
00002 //  Copyright (c) 2003-2005 by Autodesk, Inc.
00003 //
00004 //  By using this code, you are agreeing to the terms and conditions of
00005 //  the License Agreement included in the documentation for this code.
00006 //
00007 //  AUTODESK MAKES NO WARRANTIES, EXPRESS OR IMPLIED,
00008 //  AS TO THE CORRECTNESS OF THIS CODE OR ANY DERIVATIVE
00009 //  WORKS WHICH INCORPORATE IT.
00010 //
00011 //  AUTODESK PROVIDES THE CODE ON AN "AS-IS" BASIS
00012 //  AND EXPLICITLY DISCLAIMS ANY LIABILITY, INCLUDING
00013 //  CONSEQUENTIAL AND INCIDENTAL DAMAGES FOR ERRORS,
00014 //  OMISSIONS, AND OTHER PROBLEMS IN THE CODE.
00015 //
00016 //  Use, duplication, or disclosure by the U.S. Government is subject to
00017 //  restrictions set forth in FAR 52.227-19 (Commercial Computer Software
00018 //  Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) (Rights in Technical
00019 //  Data and Computer Software), as applicable.
00020 //
00021 
00022 #ifndef _DWFCORE_SKIPLIST_H
00023 #define _DWFCORE_SKIPLIST_H
00024 
00025 
00031 
00032 
00033 #include "dwfcore/STL.h"
00034 #include "dwfcore/Hash.h"
00035 #include "dwfcore/Timer.h"
00036 #include "dwfcore/Iterator.h"
00037 #include "dwfcore/Comparator.h"
00038 
00039 
00040     
00041 
00042 #ifndef DWFCORE_SKIPLIST_PROBABILITY_DISTRIB
00054 #define DWFCORE_SKIPLIST_PROBABILITY_DISTRIB    0.5f
00055 #endif
00056 
00057 #ifndef DWFCORE_SKIPLIST_MAX_NODE_LEVEL
00065 #define DWFCORE_SKIPLIST_MAX_NODE_LEVEL         31
00066 #endif
00067 
00068 #ifndef DWFCORE_SKIPLIST_INITIAL_HEIGHT
00077 #define DWFCORE_SKIPLIST_INITIAL_HEIGHT        5
00078 #endif
00079 
00080 
00081 namespace DWFCore
00082 {
00083 
00084 
00105 template < class K, class V, class E = tDWFCompareEqual<K>, class L = tDWFCompareLess<K>, class Z = tDWFDefinedEmpty<K> >
00106 class DWFSkipList : public DWFCoreMemory
00107 {
00108 
00109 public:
00110 
00116     DWFSkipList()
00117         throw( DWFMemoryException )
00118         : _pHeader( NULL )
00119         , _nMaxHeight( DWFCORE_SKIPLIST_INITIAL_HEIGHT )
00120         , _nMaxLevel( 0 )
00121         , _nCount( 0 )
00122     {
00123         _pHeader = DWFCORE_ALLOC_OBJECT( _Node(DWFCORE_SKIPLIST_MAX_NODE_LEVEL) );
00124         if (_pHeader == NULL)
00125         {
00126             _DWFCORE_THROW( DWFMemoryException, L"Failed to allocate header node" );
00127         }
00128     }
00129 
00135     virtual ~DWFSkipList()
00136         throw()
00137     {
00138         _Node* pNext = NULL;
00139         typename _Node::_Iterator iNode( _pHeader->forward(0) );
00140 
00141         while (iNode.valid())
00142         {
00143             pNext = iNode.get();
00144             iNode.next();
00145 
00146             DWFCORE_FREE_OBJECT( pNext );
00147         }
00148 
00149         DWFCORE_FREE_OBJECT( _pHeader );
00150     }
00151 
00152     //
00153     // Inner class definitions
00154     //
00155 private:
00156 
00157     class _Node
00158     {
00159 
00160     public:
00161 
00162         class _Iterator : public DWFIterator<_Node*>
00163         {
00164         
00165         public:
00166 
00167             _Iterator( _Node* pFirst )
00168                 throw()
00169                 : _pFirst( pFirst )
00170                 , _pNext( pFirst )
00171             {;}
00172 
00173             virtual ~_Iterator()
00174                 throw()
00175             {;}
00176 
00177             void reset()
00178                 throw()
00179             {
00180                 _pNext = _pFirst;
00181             }
00182 
00183             bool valid()
00184                 throw()
00185             {
00186                 return (_pNext != NULL);
00187             }
00188 
00189             bool next()
00190                 throw()
00191             {
00192                 _pNext = _pNext->forward( 0 );
00193                 
00194                 return valid();
00195             }
00196             
00197             _Node*& get()
00198                 throw()
00199             {
00200                 return _pNext;
00201             }
00202 
00203         private:
00204 
00205             _Node* _pFirst;
00206             _Node* _pNext;
00207         };
00208 
00209     public:
00210 
00211         _Node( int nHeight )
00212             throw( DWFMemoryException )
00213         {
00214             _ppForward = DWFCORE_ALLOC_MEMORY( _Node*, (nHeight + 1) );
00215             
00216             if (_ppForward == NULL)
00217             {
00218                 _DWFCORE_THROW( DWFMemoryException, L"Failed to allocate array" );
00219             }
00220 
00221             DWFCORE_ZERO_MEMORY( _ppForward, sizeof(_Node*) * (nHeight + 1) );
00222 
00223             Z fNull;
00224             _Key = fNull();
00225         }
00226 
00227         _Node( int      nHeight,
00228                const K& rKey,
00229                const V& rValue )
00230             throw( DWFMemoryException )
00231             : _Key( rKey )
00232             , _Value( rValue )
00233         {
00234             _ppForward = DWFCORE_ALLOC_MEMORY( _Node*, (nHeight + 1) );
00235             
00236             if (_ppForward == NULL)
00237             {
00238                 _DWFCORE_THROW( DWFMemoryException, L"Failed to allocate array" );
00239             }
00240 
00241             DWFCORE_ZERO_MEMORY( _ppForward, sizeof(_Node*) * (nHeight + 1) );
00242         }
00243 
00244         ~_Node()
00245             throw()
00246         {
00247             if (_ppForward)
00248             {
00249                 DWFCORE_FREE_MEMORY( _ppForward );
00250             }
00251         }
00252 
00253         _Node* forward( uint16_t iLevel )
00254             throw()
00255         {
00256             return (_ppForward ? _ppForward[iLevel] : NULL);
00257         }
00258 
00259         void forward( uint16_t iLevel, _Node* pNode )
00260             throw()
00261         {
00262             _ppForward[iLevel] = pNode;
00263         }
00264 
00265         K& key()
00266             throw()
00267         {
00268             return _Key;
00269         }
00270 
00271         void key( const K& rKey )
00272             throw()
00273         {
00274             _Key = rKey;
00275         }
00276 
00277         V& value()
00278             throw()
00279         {
00280             return _Value;
00281         }
00282 
00283         void value( const V& rValue )
00284             throw()
00285         {
00286             _Value = rValue;
00287         }
00288 
00289     private:
00290 
00291         _Node** _ppForward;
00292         K       _Key;
00293         V       _Value;
00294     };
00295 
00296 public:
00297 
00303     class Iterator : public DWFCoreMemory
00304                    , public DWFKVIterator<K,V>
00305     {
00306     
00307     public:
00308 
00314         Iterator()
00315             throw()
00316             : _pNodeIterator( NULL )
00317             , _pCurrent( NULL )
00318         {;}      
00319 
00325         Iterator( typename _Node::_Iterator* pNodeIterator )
00326             throw()
00327             : _pNodeIterator( pNodeIterator )
00328             , _pCurrent( NULL )
00329         {;}      
00330 
00336         virtual ~Iterator()
00337             throw()
00338         {
00339             if (_pNodeIterator)
00340             {
00341                 DWFCORE_FREE_OBJECT( _pNodeIterator );
00342             }
00343         }
00344 
00345         virtual void reset()
00346             throw()
00347         {
00348             _pCurrent = NULL;
00349 
00350             if (_pNodeIterator)
00351             {
00352                 _pNodeIterator->reset();
00353             }
00354         }
00355 
00356         virtual bool valid()
00357             throw()
00358         {
00359             return (_pNodeIterator ? _pNodeIterator->valid() : false);
00360         }
00361 
00362         virtual bool next()
00363             throw()
00364         {
00365             _pCurrent = NULL;
00366 
00367             if (_pNodeIterator)
00368             {
00369                 return _pNodeIterator->next();
00370             }
00371             else
00372             {
00373                 return false;
00374             }
00375         }
00376         
00377         virtual K& key()
00378             throw( DWFException )
00379         {
00380             if (_pCurrent == NULL)
00381             {
00382                 if (_pNodeIterator)
00383                 {
00384                     _pCurrent = _pNodeIterator->get();
00385                 }
00386             }
00387             
00388             if (_pCurrent)
00389             {
00390                 return _pCurrent->key();
00391             }
00392             else
00393             {
00394                 _DWFCORE_THROW( DWFIllegalStateException, L"Cannot get key from iterator" );
00395             }
00396         }
00397 
00398         virtual V& value()
00399             throw( DWFException )
00400         {
00401             if (_pCurrent == NULL)
00402             {
00403                 if (_pNodeIterator)
00404                 {
00405                     _pCurrent = _pNodeIterator->get();
00406                 }
00407             }
00408             
00409             if (_pCurrent)
00410             {
00411                 return _pCurrent->value();
00412             }
00413             else
00414             {
00415                 _DWFCORE_THROW( DWFIllegalStateException, L"Cannot get value from iterator" );
00416             }
00417         }
00418 
00419     private:
00420 
00421         typename _Node::_Iterator*  _pNodeIterator;
00422         _Node*                      _pCurrent;
00423     };
00424 
00425 public:
00426 
00432     virtual void clear()
00433         throw( DWFMemoryException )
00434     {
00435         _Node* pNext = NULL;
00436         typename _Node::_Iterator iNode( _pHeader->forward(0) );
00437 
00438         while (iNode.valid())
00439         {
00440             pNext = iNode.get();
00441             iNode.next();
00442 
00443             DWFCORE_FREE_OBJECT( pNext );
00444         }
00445 
00446         DWFCORE_FREE_OBJECT( _pHeader );
00447 
00448         //
00449         // Reset the maximum level and the initial maximum height.
00450         //
00451         _nMaxLevel  = 0;
00452         _nMaxHeight = DWFCORE_SKIPLIST_INITIAL_HEIGHT;
00453         
00454         //
00455         // Reset the element count to 0.
00456         //
00457         _nCount = 0;
00458 
00459         //
00460         // rebuild the header node
00461         //
00462         _pHeader = DWFCORE_ALLOC_OBJECT( _Node(DWFCORE_SKIPLIST_MAX_NODE_LEVEL) );
00463         if (_pHeader == NULL)
00464         {
00465             _DWFCORE_THROW( DWFMemoryException, L"Failed to allocate header node" );
00466         }
00467     }
00468 
00475     virtual size_t size() const
00476         throw()
00477     {
00478         return _nCount;
00479     }
00480 
00489     virtual Iterator* iterator()
00490         throw()
00491     {
00492         return DWFCORE_ALLOC_OBJECT(Iterator(DWFCORE_ALLOC_OBJECT(typename _Node::_Iterator(_pHeader->forward(0)))));
00493     }
00494 
00504     virtual Iterator* iterator( const K& rKey )
00505         throw()
00506     {
00507         return DWFCORE_ALLOC_OBJECT(Iterator(DWFCORE_ALLOC_OBJECT(typename _Node::_Iterator(_search(rKey)))));
00508     }
00509 
00517     virtual V* find( const K& rKey )
00518         throw()
00519     {    
00520         _Node* pSearch = _search( rKey );
00521           
00522             //
00523             // If the node was found then return the value. 
00524             //
00525         if (pSearch)
00526         {
00527             return &(pSearch->value());
00528         }
00529         else
00530         {
00531             return NULL;
00532         }
00533     }
00534 
00542     virtual K* key( uint64_t iPos )
00543         throw( DWFException )
00544     {
00545         if (iPos >= _nCount)
00546         {
00547             _DWFCORE_THROW( DWFOverflowException, L"Index exceeds list size" );
00548         }
00549 
00550         _Node* pNode = _pHeader->forward( 0 );
00551 
00552         for (; iPos > 0; iPos--)
00553         {
00554             pNode = pNode->forward( 0 );
00555         }
00556 
00557         return &(pNode->key());
00558     }
00559 
00567     virtual V* value( uint64_t iPos )
00568         throw( DWFException )
00569     {
00570         if (iPos >= _nCount)
00571         {
00572             _DWFCORE_THROW( DWFOverflowException, L"Index exceeds list size" );
00573         }
00574 
00575         _Node* pNode = _pHeader->forward( 0 );
00576 
00577         for (; iPos > 0; iPos--)
00578         {
00579             pNode = pNode->forward( 0 );
00580         }
00581 
00582         return &(pNode->value());
00583     }
00584 
00592     virtual bool erase( const K& rKey )
00593         throw()
00594     {
00595         //
00596         // refresh _ppUpdate
00597         //
00598         DWFCORE_ZERO_MEMORY( _ppUpdate, sizeof(_Node*) * (DWFCORE_SKIPLIST_MAX_NODE_LEVEL + 1) );
00599 
00600         _Node*  pCurrentNode = _pHeader;
00601         _Node*  pAlreadyChecked = NULL;
00602             
00603         //
00604         // Locate key of value immediately to the left of the key in rank.  During
00605         // the loop skip first using the largest steps possible and then proceed
00606         // with successively smaller steps (levels).   At each level maintain the
00607         // last visited node of that level (used for updating later).
00608         //
00609         int16_t iLevel = _nMaxLevel;
00610         for (; iLevel >= 0; iLevel--)
00611         {
00612             while ((pCurrentNode->forward(iLevel) != NULL) && 
00613                    (pCurrentNode->forward(iLevel) != pAlreadyChecked) &&
00614                    (_tLessThan(pCurrentNode->forward(iLevel)->key(), rKey)))
00615             {
00616                 pCurrentNode = pCurrentNode->forward( iLevel );
00617             }
00618                 
00619             pAlreadyChecked = pCurrentNode->forward( iLevel );
00620             _ppUpdate[iLevel] = pCurrentNode;
00621         }
00622         
00623         //
00624         // Get the next node.
00625         //
00626         pCurrentNode = pCurrentNode->forward( 0 );
00627           
00628 
00629             //
00630             // If the current key is equal to that supplied then just update the value
00631             // and we are done.
00632             //
00633         if ((pCurrentNode != NULL) && _tEquals(pCurrentNode->key(), rKey))
00634         {
00635                 //
00636                 // Iterate through all previously last-visited nodes of each level and update
00637                 // their forward references to be the same of the deleted nodes level-equivalent
00638                 // forward references.
00639                 //
00640             for (iLevel = 0; iLevel <= _nMaxLevel; iLevel++)
00641             {
00642                 if (_ppUpdate[iLevel]->forward(iLevel) != pCurrentNode)
00643                 {
00644                     break;
00645                 }
00646                     
00647                 _ppUpdate[iLevel]->forward( iLevel, pCurrentNode->forward(iLevel) );
00648             }
00649 
00650                 //
00651                 // Readjust the maximum level in the skip-list if necessary by iterating through the
00652                 // header's forward references and checking for null references at the highest levels back.
00653                 //
00654             while((_nMaxLevel>0) && (_pHeader->forward(_nMaxLevel) == NULL))
00655             {
00656                 _nMaxLevel--;
00657             }
00658         
00659             _nCount--;
00660         
00661             DWFCORE_FREE_OBJECT( pCurrentNode );
00662 
00663             return true;
00664         } 
00665         else
00666         {
00667             return false;
00668         }
00669     }
00670 
00682     virtual bool insert( const K& rKey, const V& rValue, bool bReplace = true )
00683         throw( DWFException )
00684     {
00685         //
00686         // refresh _ppUpdate
00687         //
00688         DWFCORE_ZERO_MEMORY( _ppUpdate, sizeof(_Node*) * (DWFCORE_SKIPLIST_MAX_NODE_LEVEL + 1) );
00689 
00690         _Node*  pCurrentNode = _pHeader;
00691         _Node*  pAlreadyChecked = NULL;
00692             
00693         //
00694         // Locate key of value immediately to the left of the key in rank.  During
00695         // the loop skip first using the largest steps possible and then proceed
00696         // with successively smaller steps (levels).   At each level maintain the
00697         // last visited node of that level (used for updating later).
00698         //
00699         int16_t iLevel = _nMaxLevel;
00700         for (; iLevel >= 0; iLevel--)
00701         {
00702             while ((pCurrentNode->forward(iLevel) != NULL) && 
00703                    (pCurrentNode->forward(iLevel) != pAlreadyChecked) &&
00704                    (_tLessThan(pCurrentNode->forward(iLevel)->key(), rKey)))
00705             {
00706                 pCurrentNode = pCurrentNode->forward( iLevel );
00707             }
00708                 
00709             pAlreadyChecked = pCurrentNode->forward( iLevel );
00710             _ppUpdate[iLevel] = pCurrentNode;
00711         }
00712             
00713         //
00714         // Get the next node.
00715         //
00716         pCurrentNode = pCurrentNode->forward( 0 );
00717           
00718             //
00719             // If the current key is equal to that supplied then just update the value
00720             // and we are done.
00721             //
00722         if ((pCurrentNode != NULL) && (_tEquals(pCurrentNode->key(), rKey)))
00723         {                  
00724             if (bReplace)
00725             {
00726                 pCurrentNode->key( rKey );
00727                 pCurrentNode->value( rValue );
00728             }
00729 
00730             return false;
00731         }
00732         else
00733         {
00734             //
00735             // Generate a random level (height) for the new node.
00736             //
00737             uint16_t nNewLevel = _random();
00738               
00739                 //
00740                 // Update the maximum level height if this level is now larger.  (Could only be one greater!)
00741                 //
00742             if (nNewLevel >= _nMaxHeight)
00743             {
00744                 _nMaxHeight = nNewLevel + 1;
00745             }
00746                 
00747                 //
00748                 // If this level is the largest level so far selected in the skip-list then extend the
00749                 // list of maintain "update" pointers (of previously visited nodes of each level) for the
00750                 // intermediate levels between the previous maximum and the new maximum.
00751                 //
00752                 // Also checks to see that the absolute maximum has been reached and restricts the height increase.
00753                 //
00754             if (nNewLevel > _nMaxLevel)
00755             {
00756                 for(iLevel = _nMaxLevel + 1; iLevel <= nNewLevel; iLevel++)
00757                 {
00758                     _ppUpdate[iLevel] = _pHeader;
00759                 }
00760                  
00761                 //
00762                 // Update the skip-list maximum level from here on.
00763                 //
00764                 _nMaxLevel = nNewLevel;
00765             }
00766                 
00767             //
00768             // Create a new node.
00769             //
00770             pCurrentNode = DWFCORE_ALLOC_OBJECT( _Node(nNewLevel, rKey, rValue) );
00771 
00772             if (pCurrentNode == NULL)
00773             {
00774                 _DWFCORE_THROW( DWFMemoryException, L"Failed to allocate node" );
00775             }
00776               
00777                 //
00778                 // Update all forward references of previous skip-list nodes to reference the new value and 
00779                 // set the forward references of the new node to those of the previous update nodes at each level.
00780                 //
00781             for (iLevel = 0; iLevel <= nNewLevel; iLevel++)
00782             {
00783                 pCurrentNode->forward( iLevel, _ppUpdate[iLevel]->forward(iLevel) );
00784                 _ppUpdate[iLevel]->forward( iLevel, pCurrentNode );
00785             }                            
00786                 
00787             _nCount++;
00788 
00789             return true;
00790         }
00791     }
00792 
00793 private:
00794 
00795     //
00796     //
00797     //
00798     _Node* _search( const K& rKey )
00799         throw()
00800     {    
00801         _Node*  pCurrentNode = _pHeader;
00802         _Node*  pAlreadyChecked = NULL;
00803 
00804         //
00805         // Locate key of value immediately to the left of the key in rank.  During
00806         // the loop skip first using the largest steps possible and then proceed
00807         // with successively smaller steps (levels).   At each level maintain the
00808         // last visited node of that level (used for updating later).
00809         //
00810         int16_t iLevel = _nMaxLevel;
00811         for (; iLevel >= 0; iLevel--)
00812         {
00813             while ((pCurrentNode->forward(iLevel) != NULL) && 
00814                    (pCurrentNode->forward(iLevel) != pAlreadyChecked) &&
00815                    (_tLessThan(pCurrentNode->forward(iLevel)->key(), rKey)))
00816             {
00817                 pCurrentNode = pCurrentNode->forward( iLevel );
00818             }
00819                 
00820             pAlreadyChecked = pCurrentNode->forward( iLevel );
00821         }
00822 
00823         //
00824         // Get the next node.
00825         //
00826         pCurrentNode = pCurrentNode->forward( 0 );
00827           
00828             //
00829             // If the node was found then return the value. 
00830             //
00831         if ((pCurrentNode != NULL) && (_tEquals(pCurrentNode->key(), rKey)))
00832         {
00833             return pCurrentNode;
00834         }
00835         else
00836         {
00837             return NULL;
00838         }
00839     }
00840 
00841     uint16_t _random()
00842         throw()
00843     {
00844         uint16_t nLevel = 1;
00845         static bool bSeed = true;
00846 
00847         if (bSeed)
00848         {
00849             ::srand( DWFTimer::Tick32() );
00850             bSeed = false;
00851         }
00852 
00853 
00854         while ((::rand() < (RAND_MAX * DWFCORE_SKIPLIST_PROBABILITY_DISTRIB)) &&
00855                (nLevel <= _nMaxHeight) &&
00856                (nLevel < DWFCORE_SKIPLIST_MAX_NODE_LEVEL))
00857         {
00858             nLevel++;
00859         }
00860 
00861         return nLevel;
00862     }
00863 
00864 
00865 private:
00866 
00867         //
00868         // First node in the list ... does not represent a key.
00869         //
00870     _Node*      _pHeader;   
00871 
00872         //
00873         // Update node array used in _insert and _delete
00874         // Keep it here and use the maximum node level size
00875         // to eliminate allocations
00876         //
00877     _Node*      _ppUpdate[DWFCORE_SKIPLIST_MAX_NODE_LEVEL + 1];
00878 
00879         //
00880         // Current maximum height of a node allowed.
00881         //
00882     uint16_t    _nMaxHeight;
00883 
00884         //
00885         // Current maximum level used in any node.
00886         //
00887     uint16_t    _nMaxLevel;
00888 
00889         //
00890         // Current count of items in the list.
00891         //
00892     uint32_t    _nCount;
00893 
00894     //
00895     // Comparators
00896     //
00897     E           _tEquals;
00898     L           _tLessThan;
00899 
00900 private:
00901 
00902     DWFSkipList( const DWFSkipList& );
00903     DWFSkipList& operator=( const DWFSkipList& );
00904 };
00905 
00916 template<class V>
00917 class DWFCharKeySkipList : public DWFSkipList<const char*, V, tDWFCharCompareEqual, tDWFCharCompareLess>
00918 {
00919 public:
00920 
00926     DWFCharKeySkipList() throw() {;}
00927 
00933     virtual ~DWFCharKeySkipList() throw() {;}
00934 
00935 private:
00936 
00937     //
00938     // Not Implemented
00939     //
00940     DWFCharKeySkipList( const DWFCharKeySkipList& );
00941     DWFCharKeySkipList& operator=( const DWFCharKeySkipList& );
00942 };
00943 
00978 template<class V>
00979 class DWFWCharKeySkipList : public DWFSkipList<const wchar_t*, V, tDWFWCharCompareEqual, tDWFWCharCompareLess>
00980 {
00981 public:
00982 
00988     DWFWCharKeySkipList() throw() {;}
00989 
00995     virtual ~DWFWCharKeySkipList() throw() {;}
00996 
00997 private:
00998 
00999     //
01000     // Not Implemented
01001     //
01002     DWFWCharKeySkipList( const DWFWCharKeySkipList& );
01003     DWFWCharKeySkipList& operator=( const DWFWCharKeySkipList& );
01004 };
01005 
01013 template<class V>
01014 class DWFStringKeySkipList : public DWFSkipList<DWFString, V, tDWFCompareEqual<DWFString>, tDWFCompareLess<DWFString>, tDWFStringDefinedEmpty>
01015 {
01016 public:
01017 
01023     DWFStringKeySkipList() throw() {;}
01024 
01030     virtual ~DWFStringKeySkipList() throw() {;}
01031 
01032 private:
01033 
01034     //
01035     // Not Implemented
01036     //
01037     DWFStringKeySkipList( const DWFStringKeySkipList& );
01038     DWFStringKeySkipList& operator=( const DWFStringKeySkipList& );
01039 };
01040 
01041 
01052 template<class T, class E = tDWFCompareEqual<T>, class L = tDWFCompareLess<T>, class Z = tDWFDefinedEmpty<T> >
01053 class DWFSortedList : public DWFCoreMemory
01054 {
01055 
01056 private:
01057 
01058     typedef typename DWFSkipList<T, T, E, L, Z>::Iterator    tListIterator;
01059 
01060 public:
01061 
01067     class Iterator : public DWFCoreMemory
01068                    , public DWFIterator<T>
01069     {
01070         
01071     public:
01072 
01079         Iterator( tListIterator* pIterator )
01080             throw()
01081             : _pIterator( pIterator )
01082         {;}
01083 
01089         virtual ~Iterator()
01090             throw()
01091         {
01092             DWFCORE_FREE_OBJECT( _pIterator );
01093         }
01094 
01095         virtual void reset()
01096             throw()
01097         {
01098             _pIterator->reset();
01099         }
01100 
01101         virtual bool valid()
01102             throw()
01103         {
01104             return _pIterator->valid();
01105         }
01106 
01107         virtual bool next()
01108             throw()
01109         {
01110             return _pIterator->next();
01111         }
01112             
01113         virtual T& get()
01114             throw()
01115         {
01116             return _pIterator->key();
01117         }
01118 
01119     private:
01120 
01121         tListIterator* _pIterator;
01122     };
01123 
01124 public:
01125 
01131     DWFSortedList()
01132         throw()
01133     {;}
01134 
01140     virtual ~DWFSortedList()
01141         throw()
01142     {;}
01143 
01147     virtual void clear()
01148         throw()
01149     {
01150         _oList.clear();
01151     }
01152 
01156     virtual size_t size() const
01157         throw()
01158     {
01159         return _oList.size();
01160     }
01161     
01165     virtual Iterator* iterator()
01166         throw()
01167     {
01168         return DWFCORE_ALLOC_OBJECT( Iterator(_oList.iterator()) );
01169     }
01170 
01180     virtual Iterator* iterator( const T& rT )
01181         throw()
01182     {
01183         return DWFCORE_ALLOC_OBJECT( Iterator(_oList.iterator(rT)) );
01184     }
01185 
01193     virtual bool exists( const T& rT )
01194         throw()
01195     {    
01196         return (_oList.find(rT) != NULL);
01197     }
01198 
01206     virtual bool erase( const T& rT )
01207         throw()
01208     {
01209         return _oList.erase( rT );
01210     }
01211  
01222     virtual bool insert( const T& rT, bool bReplace = true )
01223         throw( DWFException )
01224     {
01225         return _oList.insert( rT, rT, bReplace );
01226     }
01227 
01228 private:
01229 
01230     DWFSkipList<T, T>   _oList;
01231 
01232 private:
01233 
01234     //
01235     // Not Implemented
01236     //
01237     DWFSortedList( const DWFSortedList& );
01238     DWFSortedList& operator=( const DWFSortedList& );
01239 };
01240 
01244 
01245 
01261 template< class T, class H = tDWFFNV1A32HashKernel<const char> >
01262 class DWFCharKeyHashList    : public DWFCoreMemory
01263 {
01264 
01265 private:
01266 
01267     typedef typename DWFSkipList<uint32_t, T>::Iterator  tListIterator;
01268     
01269 public:
01270 
01276     class Iterator : public DWFCoreMemory
01277                    , public DWFIterator<T>
01278     {
01279         
01280     public:
01281 
01288         Iterator( tListIterator* pIterator )
01289             throw()
01290             : _pIterator( pIterator )
01291         {;}
01292 
01298         virtual ~Iterator()
01299             throw()
01300         {
01301             DWFCORE_FREE_OBJECT( _pIterator );
01302         }
01303 
01304         virtual void reset()
01305             throw()
01306         {
01307             _pIterator->reset();
01308         }
01309 
01310         virtual bool valid()
01311             throw()
01312         {
01313             return _pIterator->valid();
01314         }
01315 
01316         virtual bool next()
01317             throw()
01318         {
01319             return _pIterator->next();
01320         }
01321             
01322         virtual T& get()
01323             throw()
01324         {
01325             return _pIterator->value();
01326         }
01327 
01328     private:
01329 
01330         tListIterator* _pIterator;
01331     };    
01332 
01333 public:
01334 
01340     DWFCharKeyHashList()
01341         throw()
01342     {;}
01343 
01349     virtual ~DWFCharKeyHashList()
01350         throw()
01351     {;}
01352 
01356     virtual void clear()
01357         throw()
01358     {
01359         //
01360         // clear base
01361         //
01362         _oList.clear();
01363     }
01364 
01368     virtual size_t size() const
01369         throw()
01370     {
01371         return _oList.size();
01372     }
01373 
01377     virtual Iterator* iterator()
01378         throw()
01379     {
01380         return DWFCORE_ALLOC_OBJECT( Iterator(_oList.iterator()) );
01381     }
01382 
01386     virtual Iterator* iterator( const char*& rKey )
01387         throw()
01388     {
01389         return DWFCORE_ALLOC_OBJECT( Iterator(_oList.iterator(_tHash(rKey))) );
01390     }
01391 
01395     virtual T* find( const char*& rKey )
01396         throw()
01397     {
01398         return _oList.find( _tHash(rKey) );
01399     }
01400 
01404     virtual bool erase( const char*& rKey )
01405         throw()
01406     {
01407         return _oList.erase( _tHash(rKey) );
01408     }
01409 
01413     virtual bool insert( const char*& rKey, const T& rValue, bool bReplace = true )
01414         throw( DWFException )
01415     {
01416         return _oList.insert( _tHash(rKey), rValue, bReplace );
01417     }
01418 
01419 private:
01420 
01421     H                        _tHash;
01422     DWFSkipList<uint32_t, T> _oList;
01423 
01424 private:
01425 
01426     //
01427     // Not Implemented
01428     //
01429     DWFCharKeyHashList( const DWFCharKeyHashList& );
01430     DWFCharKeyHashList& operator=( const DWFCharKeyHashList& );
01431 };
01432 
01436 
01452 template< class T, class H = tDWFFNV1A32HashKernel<const wchar_t> >
01453 class DWFWCharKeyHashList   : public DWFCoreMemory
01454 {
01455 
01456 private:
01457 
01458     typedef typename DWFSkipList<uint32_t, T>::Iterator  tListIterator;
01459     
01460 public:
01461 
01467     class Iterator : public DWFCoreMemory
01468                    , public DWFIterator<T>
01469     {
01470         
01471     public:
01472 
01479         Iterator( tListIterator* pIterator )
01480             throw()
01481             : _pIterator( pIterator )
01482         {;}
01483 
01489         virtual ~Iterator()
01490             throw()
01491         {
01492             DWFCORE_FREE_OBJECT( _pIterator );
01493         }
01494 
01495         virtual void reset()
01496             throw()
01497         {
01498             _pIterator->reset();
01499         }
01500 
01501         virtual bool valid()
01502             throw()
01503         {
01504             return _pIterator->valid();
01505         }
01506 
01507         virtual bool next()
01508             throw()
01509         {
01510             return _pIterator->next();
01511         }
01512             
01513         virtual T& get()
01514             throw()
01515         {
01516             return _pIterator->value();
01517         }
01518 
01519     private:
01520 
01521         tListIterator* _pIterator;
01522     };    
01523 
01524 public:
01525 
01531     DWFWCharKeyHashList()
01532         throw()
01533     {;}
01534 
01540     virtual ~DWFWCharKeyHashList()
01541         throw()
01542     {;}
01543 
01547     virtual void clear()
01548         throw()
01549     {
01550         //
01551         // clear base
01552         //
01553         _oList.clear();
01554     }
01555 
01559     virtual size_t size() const
01560         throw()
01561     {
01562         return _oList.size();
01563     }
01564 
01568     virtual Iterator* iterator()
01569         throw()
01570     {
01571         return DWFCORE_ALLOC_OBJECT( Iterator(_oList.iterator()) );
01572     }
01573 
01577     virtual Iterator* iterator( const wchar_t*& rKey )
01578         throw()
01579     {
01580         return DWFCORE_ALLOC_OBJECT( Iterator(_oList.iterator(_tHash(rKey))) );
01581     }
01582 
01586     virtual T* find( const wchar_t*& rKey )
01587         throw()
01588     {
01589         return _oList.find( _tHash(rKey) );
01590     }
01591 
01595     virtual bool erase( const wchar_t*& rKey )
01596         throw()
01597     {
01598         return _oList.erase( _tHash(rKey) );
01599     }
01600 
01604     virtual bool insert( const wchar_t*& rKey, const T& rValue, bool bReplace = true )
01605         throw( DWFException )
01606     {
01607         return _oList.insert( _tHash(rKey), rValue, bReplace );
01608     }
01609 
01610 private:
01611 
01612     H                        _tHash;
01613     DWFSkipList<uint32_t, T> _oList;
01614 
01615 private:
01616 
01617     //
01618     // Not Implemented
01619     //
01620     DWFWCharKeyHashList( const DWFWCharKeyHashList& );
01621     DWFWCharKeyHashList& operator=( const DWFWCharKeyHashList& );
01622 };
01623 
01624 
01641 template<class PK, class SK, class V, 
01642          class PE = tDWFCompareEqual<PK>, class SE = tDWFCompareEqual<SK>, 
01643          class PL = tDWFCompareLess<PK>, class SL = tDWFCompareLess<SK>, 
01644          class PZ = tDWFDefinedEmpty<PK>, class SZ = tDWFDefinedEmpty<SK> >
01645 class DWFChainedSkipList    : public DWFCoreMemory
01646 {
01647 
01648     typedef typename DWFSkipList<SK, V, SE, SL, SZ>::Iterator _tChainIterator;
01649     typedef typename DWFSkipList<PK, DWFSkipList<SK, V, SE, SL, SZ>*, PE, PL, PZ>::Iterator _tListIterator;
01650 
01651 public:
01652 
01658     class Iterator : public DWFSkipList<SK, V, SE, SL, SZ>::Iterator
01659     {
01660         public:
01661 
01662             Iterator( _tChainIterator* piChain )
01663                 throw()
01664                 : _piList( NULL )
01665                 , _piChain( piChain )
01666             {;}
01667 
01668         //
01669         // The MSVC 7.0 pre-processor cannot resolve the difference
01670         // between      typedef typename _tChainIterator 
01671         // and          typedef typename _tListIterator
01672         // so this hack becomes necessary to prevent the constructor
01673         // appearing to be declared twice.
01674         //
01675 #if     defined( _DWFCORE_WIN32_SYSTEM ) && ( _MSC_VER <= 1300 )
01676                         Iterator( _tListIterator* piList, int )
01677 #else
01684             Iterator( _tListIterator* piList )
01685 #endif
01686                 throw()
01687                 : _piList( piList )
01688                 , _piChain( NULL )
01689             {
01690                 if (piList && (piList->valid()))
01691                 {
01692                     _piChain = piList->value()->iterator();
01693                 }
01694             }
01695 
01701             virtual ~Iterator()
01702                 throw()
01703             {
01704                 if (_piChain)
01705                 {
01706                     DWFCORE_FREE_OBJECT( _piChain );
01707                 }
01708                 else if (_piList)
01709                 {
01710                     DWFCORE_FREE_OBJECT( _piList );
01711                 }
01712             }
01713 
01714             void reset()
01715                 throw()
01716             {
01717                     //
01718                     // always work on composite iterator first
01719                     //
01720                 if (_piList)
01721                 {
01722                     //
01723                     // reset
01724                     //
01725                     _piList->reset();
01726 
01727                         //
01728                         // free any intermediate chain iterator
01729                         //
01730                     if (_piChain)
01731                     {
01732                         DWFCORE_FREE_OBJECT( _piChain );
01733                         _piChain = NULL;
01734                     }
01735                 }
01736                     //
01737                     // we are only a chain iterator
01738                     //
01739                 else if (_piChain)
01740                 {
01741                     _piChain->reset();
01742                 }
01743             }
01744 
01745             bool valid()
01746                 throw()
01747             {
01748                     //
01749                     // always work on composite iterator first
01750                     //
01751                 if (_piList && _piList->valid())
01752                 {
01753                         //
01754                         // the intermediate chain iterator is not valid
01755                         // move on to the next one
01756                         //
01757                     if (_piChain && (_piChain->valid() == false))
01758                     {
01759                         DWFCORE_FREE_OBJECT( _piChain );
01760                         _piChain = NULL;
01761 
01762                             //
01763                             // get the next intermediate iterator
01764                             //
01765                         if (_piList->next())
01766                         {
01767                             _piChain = _piList->value()->iterator();
01768                         }
01769                     }
01770 
01771                     //
01772                     // if _piChain is NULL at this point, 
01773                     // there are no more chained iterators
01774                     //
01775                 }
01776 
01777                 return (_piChain ? _piChain->valid() : false);
01778             }
01779 
01780             bool next()
01781                 throw()
01782             {
01783                     //
01784                     // this pointer should always be accurate
01785                     //
01786                 if (_piChain)
01787                 {
01788                         //
01789                         // in this case, if next() is false,
01790                         // we need to try and get the next intermediate iterator
01791                         //
01792                     if (_piList && (_piChain->next() == false))
01793                     {
01794                         DWFCORE_FREE_OBJECT( _piChain );
01795                         _piChain = NULL;
01796 
01797                             //
01798                             // get the next intermediate iterator
01799                             //
01800                         if (_piList->next())
01801                         {
01802                             _piChain = _piList->value()->iterator();
01803                         }
01804                     }
01805 
01806                     if (_piChain)
01807                     {
01808                         return _piChain->valid();
01809                     }
01810                 }
01811 
01812                 return false;
01813             }
01814             
01815             SK& key()
01816                 throw( DWFException )
01817             {
01818                 if (_piChain)
01819                 {
01820                     return _piChain->key();
01821                 }
01822                 else
01823                 {
01824                     _DWFCORE_THROW( DWFDoesNotExistException, L"No more elements" );
01825                 }
01826             }
01827 
01828             V& value()
01829                 throw( DWFException )
01830             {
01831                 if (_piChain)
01832                 {
01833                     return _piChain->value();
01834                 }
01835                 else
01836                 {
01837                     _DWFCORE_THROW( DWFDoesNotExistException, L"No more elements" );
01838                 }
01839             }
01840 
01841         private:
01842 
01843             _tListIterator*     _piList;
01844             _tChainIterator*    _piChain;
01845         };
01846 
01847 public:
01848 
01854     DWFChainedSkipList()
01855         throw()
01856     {;}
01857 
01863     virtual ~DWFChainedSkipList()
01864         throw()
01865     {
01866         _tListIterator* piChain = _oChains.iterator();
01867 
01868             if (piChain)
01869             {
01870             for (;piChain->valid(); piChain->next())
01871             {
01872                 DWFCORE_FREE_OBJECT( piChain->value() );
01873             }
01874             
01875             DWFCORE_FREE_OBJECT( piChain );
01876             }
01877     }
01878 
01882     virtual void clear()
01883         throw()
01884     {
01885         _tListIterator* piChain = _oChains.iterator();
01886             if (piChain)
01887             {
01888             for (;piChain->valid(); piChain->next())
01889             {
01890                 piChain->value()->clear();
01891             }
01892             DWFCORE_FREE_OBJECT( piChain );
01893             }
01894         
01895         _oChains.clear();
01896     }
01897 
01905     virtual size_t size()
01906         throw()
01907     {
01908         size_t nCount = 0;
01909         _tListIterator* piChain = _oChains.iterator();
01910         
01911             if (piChain)
01912             {
01913             for (;piChain->valid(); piChain->next())
01914             {
01915                 nCount += piChain->value()->size();
01916             }
01917             DWFCORE_FREE_OBJECT( piChain );
01918         }
01919 
01920         return nCount;
01921     }
01922 
01929     virtual size_t size( const PK& rPKey )
01930         throw()
01931     {
01932         DWFSkipList<SK, V, SE, SL, SZ>** ppChain = _oChains.find( rPKey );
01933 
01934         return (ppChain ? (*ppChain)->size() : 0);
01935     }
01936 
01940     virtual Iterator* iterator()
01941         throw()
01942     {
01943             //
01944             // see above
01945             //
01946 #if     defined( _DWFCORE_WIN32_SYSTEM ) && ( _MSC_VER <= 1300 )
01947         return DWFCORE_ALLOC_OBJECT( Iterator(_oChains.iterator(), 0) );
01948 #else
01949         return DWFCORE_ALLOC_OBJECT( Iterator(_oChains.iterator()) );
01950 #endif
01951     }
01952 
01964     virtual Iterator* iterator( const PK& rPKey )
01965         throw()
01966     {
01967         DWFSkipList<SK, V, SE, SL, SZ>** ppChain = _oChains.find( rPKey );
01968 
01969         return (ppChain ? DWFCORE_ALLOC_OBJECT(Iterator((*ppChain)->iterator())) : NULL);
01970     }
01971 
01984     virtual Iterator* iterator( const PK& rPKey, const SK& rSKey )
01985         throw()
01986     {
01987         DWFSkipList<SK, V, SE, SL, SZ>** ppChain = _oChains.find( rPKey );
01988 
01989         return (ppChain ? DWFCORE_ALLOC_OBJECT(Iterator((*ppChain)->iterator(rSKey))) : NULL);
01990     }
01991 
02000     virtual V* find( const PK& rPKey, const SK& rSKey )
02001         throw()
02002     {
02003         DWFSkipList<SK, V, SE, SL, SZ>** ppChain = _oChains.find( rPKey );
02004 
02005         return (ppChain ? (*ppChain)->find(rSKey) : NULL);
02006     }
02007 
02015     virtual bool erase( const PK& rPKey )
02016         throw()
02017     {
02018         DWFSkipList<SK, V, SE, SL, SZ>** ppChain = _oChains.find( rPKey );
02019 
02020         //
02021         // forward the call
02022         //
02023         bool bErased = _oChains.erase( rPKey );
02024 
02025         if (*ppChain)
02026         {
02027             DWFCORE_FREE_OBJECT( *ppChain );
02028         }
02029 
02030         return bErased;
02031     }
02032 
02041     virtual bool erase( const PK& rPKey, const SK& rSKey )
02042         throw()
02043     {
02044         DWFSkipList<SK, V, SE, SL, SZ>** ppChain = _oChains.find( rPKey );
02045 
02046         return (ppChain ? (*ppChain)->erase(rSKey) : false);
02047     }
02048         
02049 
02062     virtual bool insert( const PK& rPKey, const SK& rSKey, const V& rValue, bool bReplace = true )
02063         throw( DWFException )
02064     {
02065         DWFSkipList<SK, V, SE, SL, SZ>** ppChain = _oChains.find( rPKey );
02066 
02067             //
02068             // add element into chain
02069             //
02070         if (ppChain)
02071         {
02072             return (*ppChain)->insert( rSKey, rValue, bReplace );
02073         }
02074             //
02075             // new chain
02076             //
02077         else
02078         {
02079             DWFSkipList<SK, V, SE, SL, SZ>* pNewChain = DWFCORE_ALLOC_OBJECT( (DWFSkipList<SK, V, SE, SL, SZ>) );
02080             
02081             if (pNewChain == NULL)
02082             {
02083                 _DWFCORE_THROW( DWFMemoryException, L"Failed to allocate chain" );
02084             }
02085 
02086             _oChains.insert( rPKey, pNewChain );
02087 
02088             return pNewChain->insert( rSKey, rValue, bReplace );
02089         }
02090     }
02091 
02092 private:
02093 
02094     DWFSkipList<PK, DWFSkipList<SK, V, SE, SL, SZ>*, PE, PL, PZ> _oChains;
02095 
02096 private:
02097 
02098     //
02099     // Not Implemented
02100     //
02101     DWFChainedSkipList( const DWFChainedSkipList& );
02102     DWFChainedSkipList& operator=( const DWFChainedSkipList& );
02103 };
02104 
02115 template<class V>
02116 class DWFCharKeyChainedSkipList : public DWFChainedSkipList<const char*, const char*, V, tDWFCharCompareEqual, tDWFCharCompareEqual, tDWFCharCompareLess, tDWFCharCompareLess>
02117 {
02118 public:
02119 
02120     DWFCharKeyChainedSkipList() throw() {;}
02121     virtual ~DWFCharKeyChainedSkipList() throw() {;}
02122 
02123 private:
02124 
02125     DWFCharKeyChainedSkipList( const DWFCharKeyChainedSkipList& );
02126     DWFCharKeyChainedSkipList& operator=( const DWFCharKeyChainedSkipList& );
02127 };
02128 
02139 template<class V>
02140 class DWFWCharKeyChainedSkipList : public DWFChainedSkipList<const wchar_t*, const wchar_t*, V, tDWFWCharCompareEqual, tDWFWCharCompareEqual, tDWFWCharCompareLess, tDWFWCharCompareLess>
02141 {
02142 public:
02143 
02144     DWFWCharKeyChainedSkipList() throw() {;}
02145     virtual ~DWFWCharKeyChainedSkipList() throw() {;}
02146 
02147 private:
02148 
02149     DWFWCharKeyChainedSkipList( const DWFWCharKeyChainedSkipList& );
02150     DWFWCharKeyChainedSkipList& operator=( const DWFWCharKeyChainedSkipList& );
02151 };
02152 
02163 template<class V>
02164 class DWFStringKeyChainedSkipList : public DWFChainedSkipList<DWFString, DWFString, V, 
02165                                                              tDWFCompareEqual<DWFString>, tDWFCompareEqual<DWFString>,
02166                                                              tDWFCompareLess<DWFString>, tDWFCompareLess<DWFString>,
02167                                                              tDWFStringDefinedEmpty, tDWFStringDefinedEmpty>
02168 {
02169 public:
02170 
02171     DWFStringKeyChainedSkipList() throw() {;}
02172     virtual ~DWFStringKeyChainedSkipList() throw() {;}
02173 
02174 private:
02175 
02176     DWFStringKeyChainedSkipList( const DWFStringKeyChainedSkipList& );
02177     DWFStringKeyChainedSkipList& operator=( const DWFStringKeyChainedSkipList& );
02178 };
02179 
02180 }
02181 
02182 
02183 #endif
02184 

Generated on Tue May 17 12:05:10 2005 for Autodesk DWF Core Library by  doxygen 1.4.1