19#include "soui_mem_wrapper.h"
23#pragma warning(disable: 4702)
24#pragma warning(disable: 4512)
25#pragma warning(disable: 4290)
26#pragma warning(disable: 4127)
27#pragma warning(disable: 4571)
39#define SThrow(expr) SASSERT(expr)
40#define SASSERT_VALID(x)
43#define SASSUME(expr) do { SASSERT(expr); } while(0)
54#define SUNUSED(x) (void)x;
60#define _SCATCHALL() __pragma(warning(push)) __pragma(warning(disable: 4571)) catch( ... ) __pragma(warning(pop))
64#pragma pack(push,_S_PACKING)
71typedef __SPOSITION* SPOSITION;
80 static const int _Min=INT_MIN;
81 static const int _Max=INT_MAX;
85class SLimits<unsigned int >
88 static const unsigned int _Min=0;
89 static const unsigned int _Max=UINT_MAX;
96 static const long _Min=LONG_MIN;
97 static const long _Max=LONG_MAX;
101class SLimits<unsigned long >
104 static const unsigned long _Min=0;
105 static const unsigned long _Max=ULONG_MAX;
109class SLimits<long long>
112 static const long long _Min=LLONG_MIN;
113 static const long long _Max=LLONG_MAX;
117class SLimits<unsigned long long>
120 static const unsigned long long _Min=0;
121 static const unsigned long long _Max=ULLONG_MAX;
126inline HRESULT SAdd(T* ptResult, T tLeft, T tRight)
128 if(SLimits<T>::_Max-tLeft < tRight)
132 *ptResult= tLeft + tRight;
138inline HRESULT SMultiply(T* ptResult, T tLeft, T tRight)
146 if(SLimits<T>::_Max/tLeft < tRight)
150 *ptResult= tLeft * tRight;
156inline HRESULT SMultiply(
int *piResult,
int iLeft,
int iRight)
158 int64_t i64Result=
static_cast<int64_t
>(iLeft) *
static_cast<int64_t
>(iRight);
159 if(i64Result>INT_MAX || i64Result < INT_MIN)
163 *piResult=
static_cast<int >(i64Result);
168inline HRESULT SMultiply(
unsigned int *piResult,
unsigned int iLeft,
unsigned int iRight)
170 uint64_t i64Result=
static_cast<uint64_t
>(iLeft) *
static_cast<uint64_t
>(iRight);
171 if(i64Result>UINT_MAX)
175 *piResult=
static_cast<unsigned int >(i64Result);
180inline HRESULT SMultiply(
long *piResult,
long iLeft,
long iRight)
182 int64_t i64Result=
static_cast<int64_t
>(iLeft) *
static_cast<int64_t
>(iRight);
183 if(i64Result>LONG_MAX || i64Result < LONG_MIN)
187 *piResult=
static_cast<long>(i64Result);
192inline HRESULT SMultiply(
unsigned long *piResult,
unsigned long iLeft,
unsigned long iRight)
194 uint64_t i64Result=
static_cast<uint64_t
>(iLeft) *
static_cast<uint64_t
>(iRight);
195 if(i64Result>ULONG_MAX)
199 *piResult=
static_cast<unsigned long >(i64Result);
216 static SPlex* Create(SPlex*& head,
size_t nMax,
size_t cbElement);
220 void FreeDataChain();
223inline SPlex* SPlex::Create( SPlex*& pHead,
size_t nMax,
size_t nElementSize )
228 SASSERT( nElementSize > 0 );
231 if( FAILED(SMultiply(&nBytes, nMax, nElementSize)) ||
232 FAILED(SAdd(&nBytes, nBytes,
sizeof(SPlex))) )
236 pPlex =
static_cast< SPlex*
>( soui_mem_wrapper::SouiMalloc( nBytes ) );
242 pPlex->pNext = pHead;
248inline void SPlex::FreeDataChain()
253 while( pPlex != NULL )
257 pNext = pPlex->pNext;
258 soui_mem_wrapper::SouiFree( pPlex );
263template<
typename T >
264class CElementTraitsBase
267 typedef const T& INARGTYPE;
268 typedef T& OUTARGTYPE;
270 static void CopyElements( T* pDest,
const T* pSrc,
size_t nElements )
272 for(
size_t iElement = 0; iElement < nElements; iElement++ )
274 pDest[iElement] = pSrc[iElement];
278 static void RelocateElements( T* pDest, T* pSrc,
size_t nElements )
283 memmove_s( pDest, nElements*
sizeof( T ), pSrc, nElements*
sizeof( T ));
287template<
typename T >
288class CDefaultHashTraits
291 static ULONG Hash(
const T& element )
293 return( ULONG( ULONG_PTR( element ) ) );
297template<
typename T >
298class CDefaultCompareTraits
301 static bool CompareElements(
const T& element1,
const T& element2 )
303 return( (element1 == element2) != 0 );
306 static int CompareElementsOrdered(
const T& element1,
const T& element2 )
308 if( element1 < element2 )
312 else if( element1 == element2 )
318 SASSERT( element1 > element2 );
324template<
typename T >
325class CDefaultElementTraits :
326 public CElementTraitsBase< T >,
327 public CDefaultHashTraits< T >,
328 public CDefaultCompareTraits< T >
332template<
typename T >
333class CElementTraits :
334 public CDefaultElementTraits< T >
339class CElementTraits< GUID > :
340 public CElementTraitsBase< GUID >
343 static ULONG Hash( INARGTYPE guid )
345 const DWORD* pdwData =
reinterpret_cast< const DWORD*
>( &guid );
347 return( pdwData[0]^pdwData[1]^pdwData[2]^pdwData[3] );
350 static bool CompareElements( INARGTYPE element1, INARGTYPE element2 )
352 return memcmp(&element1,&element2,
sizeof(INARGTYPE)) == 0 ;
355 static int CompareElementsOrdered( INARGTYPE element1, INARGTYPE element2 )
357 const DWORD* pdwData1 =
reinterpret_cast< const DWORD*
>( &element1 );
358 const DWORD* pdwData2 =
reinterpret_cast< const DWORD*
>( &element2 );
360 for(
int iDWORD = 3; iDWORD >= 0; iDWORD-- )
362 if( pdwData1[iDWORD] > pdwData2[iDWORD] )
366 else if( pdwData1[iDWORD] < pdwData2[iDWORD] )
377template<
typename T >
378class SStringRefElementTraits :
379 public CElementTraitsBase< T >
382 static ULONG Hash(
typename CElementTraitsBase<T>::INARGTYPE str )
386 const typename T::XCHAR* pch = str;
388 SENSURE( pch != NULL );
392 nHash = (nHash<<5)+nHash+(*pch);
399 static bool CompareElements(
typename CElementTraitsBase<T>::INARGTYPE element1,
typename CElementTraitsBase<T>::INARGTYPE element2 )
401 return( element1 == element2 );
404 static int CompareElementsOrdered(
typename CElementTraitsBase<T>::INARGTYPE str1,
typename CElementTraitsBase<T>::INARGTYPE str2 )
406 return( str1.Compare( str2 ) );
410template<
typename T >
411class CPrimitiveElementTraits :
412 public CDefaultElementTraits< T >
416 typedef T& OUTARGTYPE;
419#define _DECLARE_PRIMITIVE_TRAITS( T ) \
421 class CElementTraits< T > : \
422 public CPrimitiveElementTraits< T > \
426_DECLARE_PRIMITIVE_TRAITS(
unsigned char )
427_DECLARE_PRIMITIVE_TRAITS(
unsigned short )
428_DECLARE_PRIMITIVE_TRAITS(
unsigned int )
429_DECLARE_PRIMITIVE_TRAITS(
unsigned long )
431_DECLARE_PRIMITIVE_TRAITS(
signed char )
432_DECLARE_PRIMITIVE_TRAITS(
char )
433_DECLARE_PRIMITIVE_TRAITS(
short )
434_DECLARE_PRIMITIVE_TRAITS(
int )
435_DECLARE_PRIMITIVE_TRAITS(
long )
437_DECLARE_PRIMITIVE_TRAITS(
float )
438_DECLARE_PRIMITIVE_TRAITS(
double )
439_DECLARE_PRIMITIVE_TRAITS(
bool )
440#ifdef _NATIVE_WCHAR_T_DEFINED
441_DECLARE_PRIMITIVE_TRAITS(
wchar_t )
443_DECLARE_PRIMITIVE_TRAITS(
void* )
445template<
typename E,
class ETraits = CElementTraits< E > >
449 typedef typename ETraits::INARGTYPE INARGTYPE;
450 typedef typename ETraits::OUTARGTYPE OUTARGTYPE;
454 SArray(
const SArray &src);
456 size_t GetCount()
const;
457 bool IsEmpty()
const;
458 bool SetCount(
size_t nNewSize,
int nGrowBy = -1 );
463 const E& GetAt(
size_t iElement )
const;
464 void SetAt(
size_t iElement, INARGTYPE element );
465 E& GetAt(
size_t iElement );
467 const E* GetData()
const;
470 void SetAtGrow(
size_t iElement, INARGTYPE element );
474 size_t Add( INARGTYPE element );
475 size_t Append(
const SArray< E, ETraits >& aSrc );
476 void Copy(
const SArray< E, ETraits >& aSrc );
478 const E& operator[](
size_t iElement )
const;
479 E& operator[](
size_t iElement );
481 SArray< E, ETraits > & operator = (
const SArray< E, ETraits >& src);
483 void InsertAt(
size_t iElement, INARGTYPE element,
size_t nCount = 1 );
484 void InsertArrayAt(
size_t iStart,
const SArray< E, ETraits >* paNew );
485 void RemoveAt(
size_t iElement,
size_t nCount = 1 );
487 int Find(
const E & target)
const;
489 void AssertValid()
const;
493 bool GrowBuffer(
size_t nNewSize );
503 static void CallConstructors( E* pElements,
size_t nElements );
504 static void CallDestructors( E* pElements,
size_t nElements );
511template<
typename E,
class ETraits >
512SArray< E, ETraits > & SArray<E, ETraits>::operator=(
const SArray< E, ETraits >& src)
518template<
typename E,
class ETraits >
519int SArray<E, ETraits>::Find(
const E & target)
const
521 for(UINT i=0;i<GetCount();i++)
523 if(GetAt(i) == target)
return (
int)i;
529template<
typename E,
class ETraits >
530inline size_t SArray< E, ETraits >::GetCount()
const
535template<
typename E,
class ETraits >
536inline bool SArray< E, ETraits >::IsEmpty()
const
538 return( m_nSize == 0 );
541template<
typename E,
class ETraits >
542inline void SArray< E, ETraits >::RemoveAll()
547template<
typename E,
class ETraits >
548inline const E& SArray< E, ETraits >::GetAt(
size_t iElement )
const
550 SASSERT( iElement < m_nSize );
551 if(iElement >= m_nSize)
552 SThrow(E_INVALIDARG);
554 return( m_pData[iElement] );
557template<
typename E,
class ETraits >
558inline void SArray< E, ETraits >::SetAt(
size_t iElement, INARGTYPE element )
560 SASSERT( iElement < m_nSize );
561 if(iElement >= m_nSize)
562 SThrow(E_INVALIDARG);
564 m_pData[iElement] = element;
567template<
typename E,
class ETraits >
568inline E& SArray< E, ETraits >::GetAt(
size_t iElement )
570 SASSERT( iElement < m_nSize );
571 if(iElement >= m_nSize)
572 SThrow(E_INVALIDARG);
574 return( m_pData[iElement] );
577template<
typename E,
class ETraits >
578inline const E* SArray< E, ETraits >::GetData()
const
583template<
typename E,
class ETraits >
584inline E* SArray< E, ETraits >::GetData()
589template<
typename E,
class ETraits >
590inline size_t SArray< E, ETraits >::Add()
595 bool bSuccess=SetCount( m_nSize+1 );
598 SThrow( E_OUTOFMEMORY );
604#pragma push_macro("new")
607template<
typename E,
class ETraits >
608inline size_t SArray< E, ETraits >::Add( INARGTYPE element )
613 if( iElement >= m_nMaxSize )
615 bool bSuccess = GrowBuffer( iElement+1 );
618 SThrow( E_OUTOFMEMORY );
621 ::new( m_pData+iElement ) E( element );
627#pragma pop_macro("new")
629template<
typename E,
class ETraits >
630inline const E& SArray< E, ETraits >::operator[](
size_t iElement )
const
632 SASSERT( iElement < m_nSize );
633 if(iElement >= m_nSize)
634 SThrow(E_INVALIDARG);
636 return( m_pData[iElement] );
639template<
typename E,
class ETraits >
640inline E& SArray< E, ETraits >::operator[](
size_t iElement )
642 SASSERT( iElement < m_nSize );
643 if(iElement >= m_nSize)
644 SThrow(E_INVALIDARG);
646 return( m_pData[iElement] );
649template<
typename E,
class ETraits >
650SArray< E, ETraits >::SArray() :
658template<
typename E,
class ETraits >
659SArray< E, ETraits >::SArray(
const SArray< E, ETraits > & src) :
668template<
typename E,
class ETraits >
669SArray< E, ETraits >::~SArray()
671 if( m_pData != NULL )
673 CallDestructors( m_pData, m_nSize );
674 soui_mem_wrapper::SouiFree( m_pData );
678template<
typename E,
class ETraits >
679bool SArray< E, ETraits >::GrowBuffer(
size_t nNewSize )
681 if( nNewSize > m_nMaxSize )
683 if( m_pData == NULL )
685 size_t nAllocSize = size_t( m_nGrowBy ) > nNewSize ? size_t( m_nGrowBy ) : nNewSize ;
686 m_pData =
static_cast< E*
>( soui_mem_wrapper::SouiCalloc( nAllocSize,
sizeof( E ) ) );
687 if( m_pData == NULL )
691 m_nMaxSize = nAllocSize;
696 size_t nGrowBy = m_nGrowBy;
702 nGrowBy = (nGrowBy < 4) ? 4 : ((nGrowBy > 1024) ? 1024 : nGrowBy);
705 if( nNewSize < (m_nMaxSize+nGrowBy) )
706 nNewMax = m_nMaxSize+nGrowBy;
710 SASSERT( nNewMax >= m_nMaxSize );
712 SASSERT( nNewMax <= SIZE_T_MAX/
sizeof( E ) );
714 E* pNewData =
static_cast< E*
>( soui_mem_wrapper::SouiCalloc( nNewMax,
sizeof( E ) ) );
715 if( pNewData == NULL )
721 ETraits::RelocateElements( pNewData, m_pData, m_nSize );
724 soui_mem_wrapper::SouiFree( m_pData );
726 m_nMaxSize = nNewMax;
733template<
typename E,
class ETraits >
734bool SArray< E, ETraits >::SetCount(
size_t nNewSize,
int nGrowBy )
746 if( m_pData != NULL )
748 CallDestructors( m_pData, m_nSize );
749 soui_mem_wrapper::SouiFree( m_pData );
755 else if( nNewSize <= m_nMaxSize )
758 if( nNewSize > m_nSize )
761 CallConstructors( m_pData+m_nSize, nNewSize-m_nSize );
763 else if( m_nSize > nNewSize )
766 CallDestructors( m_pData+nNewSize, m_nSize-nNewSize );
774 bSuccess = GrowBuffer( nNewSize );
781 SASSERT( nNewSize > m_nSize );
782 CallConstructors( m_pData+m_nSize, nNewSize-m_nSize );
790template<
typename E,
class ETraits >
791size_t SArray< E, ETraits >::Append(
const SArray< E, ETraits >& aSrc )
794 SASSERT(
this != &aSrc );
796 size_t nOldSize = m_nSize;
797 bool bSuccess=SetCount( m_nSize+aSrc.m_nSize );
800 SThrow( E_OUTOFMEMORY );
803 ETraits::CopyElements( m_pData+nOldSize, aSrc.m_pData, aSrc.m_nSize );
808template<
typename E,
class ETraits >
809void SArray< E, ETraits >::Copy(
const SArray< E, ETraits >& aSrc )
812 SASSERT(
this != &aSrc );
814 bool bSuccess=SetCount( aSrc.m_nSize );
817 SThrow( E_OUTOFMEMORY );
820 ETraits::CopyElements( m_pData, aSrc.m_pData, aSrc.m_nSize );
823template<
typename E,
class ETraits >
824void SArray< E, ETraits >::FreeExtra()
828 if( m_nSize != m_nMaxSize )
832 SASSUME( m_nSize <= (SIZE_T_MAX/
sizeof( E )) );
837 pNewData = (E*)soui_mem_wrapper::SouiCalloc( m_nSize,
sizeof( E ) );
838 if( pNewData == NULL )
844 ETraits::RelocateElements( pNewData, m_pData, m_nSize );
848 soui_mem_wrapper::SouiFree( m_pData );
850 m_nMaxSize = m_nSize;
854template<
typename E,
class ETraits >
855void SArray< E, ETraits >::SetAtGrow(
size_t iElement, INARGTYPE element )
861 if( iElement >= m_nSize )
863 bool bSuccess=SetCount( iElement+1, -1 );
866 SThrow( E_OUTOFMEMORY );
872 m_pData[iElement] = element;
883template<
typename E,
class ETraits >
884void SArray< E, ETraits >::InsertAt(
size_t iElement, INARGTYPE element,
size_t nElements )
887 SASSERT( nElements > 0 );
889 if( iElement >= m_nSize )
892 bool bSuccess=SetCount( iElement+nElements, -1 );
895 SThrow( E_OUTOFMEMORY );
901 size_t nOldSize = m_nSize;
902 bool bSuccess=SetCount( m_nSize+nElements, -1 );
905 SThrow( E_OUTOFMEMORY );
908 CallDestructors( m_pData+nOldSize, nElements );
910 ETraits::RelocateElements( m_pData+(iElement+nElements), m_pData+iElement,
913 CallConstructors(m_pData + iElement, nElements);
917 SASSERT( (iElement+nElements) <= m_nSize );
918 for(
size_t iNewElement = iElement; iNewElement < (iElement+nElements); iNewElement++ )
920 m_pData[iNewElement] = element;
924template<
typename E,
class ETraits >
925void SArray< E, ETraits >::RemoveAt(
size_t iElement,
size_t nElements )
928 SASSERT( (iElement+nElements) <= m_nSize );
930 size_t newCount = iElement+nElements;
931 if ((newCount < iElement) || (newCount < nElements) || (newCount > m_nSize))
932 SThrow(E_INVALIDARG);
935 size_t nMoveCount = m_nSize-(newCount);
936 CallDestructors( m_pData+iElement, nElements );
939 ETraits::RelocateElements( m_pData+iElement, m_pData+(newCount),
942 m_nSize -= nElements;
945template<
typename E,
class ETraits >
946void SArray< E, ETraits >::InsertArrayAt(
size_t iStartElement,
947 const SArray< E, ETraits >* paNew )
949 SASSERT_VALID(
this );
950 SENSURE( paNew != NULL );
951 SASSERT_VALID( paNew );
953 if( paNew->GetCount() > 0 )
955 InsertAt( iStartElement, paNew->GetAt( 0 ), paNew->GetCount() );
956 for(
size_t iElement = 0; iElement < paNew->GetCount(); iElement++ )
958 SetAt( iStartElement+iElement, paNew->GetAt( iElement ) );
964template<
typename E,
class ETraits >
965void SArray< E, ETraits >::AssertValid()
const
967 if( m_pData == NULL )
969 SASSUME( m_nSize == 0 );
970 SASSUME( m_nMaxSize == 0 );
974 SASSUME( m_nSize <= m_nMaxSize );
979#pragma push_macro("new")
982template<
typename E,
class ETraits >
983void SArray< E, ETraits >::CallConstructors( E* pElements,
size_t nElements )
986 for (iElement = 0; iElement < nElements; iElement++)
988 ::new(pElements + iElement) E;
992#pragma pop_macro("new")
994template<
typename E,
class ETraits >
995void SArray< E, ETraits >::CallDestructors( E* pElements,
size_t nElements )
999 for(
size_t iElement = 0; iElement < nElements; iElement++ )
1001 pElements[iElement].~E();
1006template<
typename E,
class ETraits = CElementTraits< E > >
1010 typedef typename ETraits::INARGTYPE INARGTYPE;
1017 CNode():m_pNext(NULL), m_pPrev(NULL)
1020 CNode( INARGTYPE element ) :
1021 m_element( element ),m_pNext(NULL),m_pPrev(NULL)
1034 CNode(
const CNode& );
1038 SList( UINT nBlockSize = 10 );
1039 SList(
const SList& src);
1043 size_t GetCount()
const;
1044 bool IsEmpty()
const;
1046 SList& operator=(
const SList& src);
1047 void Copy(
const SList & src);
1050 const E& GetHead()
const;
1052 const E& GetTail()
const;
1056 void RemoveHeadNoReturn();
1057 void RemoveTailNoReturn();
1059 SPOSITION AddHead();
1060 SPOSITION AddHead( INARGTYPE element );
1061 void AddHeadList(
const SList< E, ETraits >* plNew );
1062 SPOSITION AddTail();
1063 SPOSITION AddTail( INARGTYPE element );
1064 void AddTailList(
const SList< E, ETraits >* plNew );
1068 SPOSITION GetHeadPosition()
const;
1069 SPOSITION GetTailPosition()
const;
1070 SPOSITION Next(SPOSITION pos)
const;
1071 SPOSITION Prev(SPOSITION pos)
const;
1072 E& GetNext( SPOSITION& pos );
1073 const E& GetNext( SPOSITION& pos )
const;
1074 E& GetPrev( SPOSITION& pos );
1075 const E& GetPrev( SPOSITION& pos )
const;
1077 E& GetAt( SPOSITION pos );
1078 const E& GetAt( SPOSITION pos )
const;
1079 void SetAt( SPOSITION pos, INARGTYPE element );
1080 void RemoveAt( SPOSITION pos );
1082 SPOSITION InsertBefore( SPOSITION pos, INARGTYPE element );
1083 SPOSITION InsertAfter( SPOSITION pos, INARGTYPE element );
1085 SPOSITION Find( INARGTYPE element, SPOSITION posStartAfter = NULL )
const;
1086 SPOSITION FindIndex(
size_t iElement )
const;
1088 void MoveToHead( SPOSITION pos );
1089 void MoveToTail( SPOSITION pos );
1090 void SwapElements( SPOSITION pos1, SPOSITION pos2 );
1091 void Swap(SList< E, ETraits > &src);
1094 void AssertValid()
const;
1108 CNode* NewNode( CNode* pPrev, CNode* pNext );
1109 CNode* NewNode( INARGTYPE element, CNode* pPrev, CNode* pNext );
1110 void FreeNode( CNode* pNode );
1114template<
typename E,
class ETraits >
1115inline size_t SList< E, ETraits >::GetCount()
const
1117 return( m_nElements );
1120template<
typename E,
class ETraits >
1121inline bool SList< E, ETraits >::IsEmpty()
const
1123 return( m_nElements == 0 );
1126template<
typename E,
class ETraits >
1127inline E& SList< E, ETraits >::GetHead()
1129 SENSURE( m_pHead != NULL );
1130 return( m_pHead->m_element );
1133template<
typename E,
class ETraits >
1134inline const E& SList< E, ETraits >::GetHead()
const
1136 SENSURE( m_pHead != NULL );
1137 return( m_pHead->m_element );
1140template<
typename E,
class ETraits >
1141inline E& SList< E, ETraits >::GetTail()
1143 SENSURE( m_pTail != NULL );
1144 return( m_pTail->m_element );
1147template<
typename E,
class ETraits >
1148inline const E& SList< E, ETraits >::GetTail()
const
1150 SENSURE( m_pTail != NULL );
1151 return( m_pTail->m_element );
1154template<
typename E,
class ETraits >
1155inline SPOSITION SList< E, ETraits >::GetHeadPosition()
const
1157 return( SPOSITION( m_pHead ) );
1160template<
typename E,
class ETraits >
1161inline SPOSITION SList< E, ETraits >::GetTailPosition()
const
1163 return( SPOSITION( m_pTail ) );
1166template<
typename E,
class ETraits >
1167inline SPOSITION SList< E, ETraits >::Next( SPOSITION pos )
const
1171 SENSURE( pos != NULL );
1172 pNode = (CNode*)pos;
1173 return SPOSITION( pNode->m_pNext );
1176template<
typename E,
class ETraits >
1177inline SPOSITION SList< E, ETraits >::Prev( SPOSITION pos )
const
1181 SENSURE( pos != NULL );
1182 pNode = (CNode*)pos;
1183 return SPOSITION( pNode->m_pPrev );
1187template<
typename E,
class ETraits >
1188inline E& SList< E, ETraits >::GetNext( SPOSITION& pos )
1192 SENSURE( pos != NULL );
1193 pNode = (CNode*)pos;
1194 pos = SPOSITION( pNode->m_pNext );
1196 return( pNode->m_element );
1200template<
typename E,
class ETraits >
1201inline const E& SList< E, ETraits >::GetNext( SPOSITION& pos )
const
1205 SENSURE( pos != NULL );
1206 pNode = (CNode*)pos;
1207 pos = SPOSITION( pNode->m_pNext );
1209 return( pNode->m_element );
1212template<
typename E,
class ETraits >
1213inline E& SList< E, ETraits >::GetPrev( SPOSITION& pos )
1217 SENSURE( pos != NULL );
1218 pNode = (CNode*)pos;
1219 pos = SPOSITION( pNode->m_pPrev );
1221 return( pNode->m_element );
1224template<
typename E,
class ETraits >
1225inline const E& SList< E, ETraits >::GetPrev( SPOSITION& pos )
const
1229 SASSERT( pos != NULL );
1230 pNode = (CNode*)pos;
1231 pos = SPOSITION( pNode->m_pPrev );
1233 return( pNode->m_element );
1236template<
typename E,
class ETraits >
1237inline E& SList< E, ETraits >::GetAt( SPOSITION pos )
1239 SENSURE( pos != NULL );
1240 CNode* pNode = (CNode*)pos;
1241 return( pNode->m_element );
1244template<
typename E,
class ETraits >
1245inline const E& SList< E, ETraits >::GetAt( SPOSITION pos )
const
1247 SENSURE( pos != NULL );
1248 CNode* pNode = (CNode*)pos;
1249 return( pNode->m_element );
1252template<
typename E,
class ETraits >
1253inline void SList< E, ETraits >::SetAt( SPOSITION pos, INARGTYPE element )
1255 SENSURE( pos != NULL );
1256 CNode* pNode = (CNode*)pos;
1257 pNode->m_element = element;
1260template<
typename E,
class ETraits >
1261SList< E, ETraits >::SList( UINT nBlockSize ) :
1267 m_nBlockSize(nBlockSize)
1269 SASSERT( nBlockSize > 0 );
1272template<
typename E,
class ETraits >
1273inline SList< E, ETraits >::SList(
const SList<E,ETraits> &src) :
1279 m_nBlockSize(src.m_nBlockSize)
1284template<
typename E,
class ETraits >
1285void SList< E, ETraits >::Copy(
const SList<E,ETraits> &src)
1288 SPOSITION pos=src.GetHeadPosition();
1291 const E &t=src.GetNext(pos);
1296template<
typename E,
class ETraits >
1297SList< E, ETraits > & SList< E, ETraits >::operator = (
const SList< E, ETraits > & src)
1303template<
typename E,
class ETraits >
1304void SList< E, ETraits >::RemoveAll()
1306 while( m_nElements > 0 )
1308 CNode* pKill = m_pHead;
1309 SENSURE( pKill != NULL );
1311 m_pHead = m_pHead->m_pNext;
1315 SASSUME( m_nElements == 0 );
1320 if( m_pBlocks != NULL )
1322 m_pBlocks->FreeDataChain();
1327template<
typename E,
class ETraits >
1328SList< E, ETraits >::~SList()
1331 SASSUME( m_nElements == 0 );
1335template<
typename E,
class ETraits >
1336void SList< E, ETraits >::GetFreeNode()
1338 if( m_pFree == NULL )
1343 pPlex = SPlex::Create( m_pBlocks, m_nBlockSize,
sizeof( CNode ) );
1346 SThrow( E_OUTOFMEMORY );
1348 pNode = (CNode*)pPlex->data();
1349 pNode += m_nBlockSize-1;
1350 for(
int iBlock = m_nBlockSize-1; iBlock >= 0; iBlock-- )
1352 pNode->m_pNext = m_pFree;
1357 SASSUME( m_pFree != NULL );
1360#pragma push_macro("new")
1362template<
typename E,
class ETraits >
1363typename SList< E, ETraits >::CNode* SList< E, ETraits >::NewNode( CNode* pPrev, CNode* pNext )
1367 CNode* pNewNode = m_pFree;
1368 CNode* pNextFree = m_pFree->m_pNext;
1370 ::new( pNewNode ) CNode;
1372 m_pFree = pNextFree;
1373 pNewNode->m_pPrev = pPrev;
1374 pNewNode->m_pNext = pNext;
1376 SASSUME( m_nElements > 0 );
1381template<
typename E,
class ETraits >
1382typename SList< E, ETraits >::CNode* SList< E, ETraits >::NewNode( INARGTYPE element, CNode* pPrev,
1387 CNode* pNewNode = m_pFree;
1388 CNode* pNextFree = m_pFree->m_pNext;
1390 ::new( pNewNode ) CNode( element );
1392 m_pFree = pNextFree;
1393 pNewNode->m_pPrev = pPrev;
1394 pNewNode->m_pNext = pNext;
1396 SASSUME( m_nElements > 0 );
1401#pragma pop_macro("new")
1403template<
typename E,
class ETraits >
1404void SList< E, ETraits >::FreeNode( CNode* pNode )
1407 pNode->m_pNext = m_pFree;
1409 SASSUME( m_nElements > 0 );
1411 if( m_nElements == 0 )
1417template<
typename E,
class ETraits >
1418SPOSITION SList< E, ETraits >::AddHead()
1420 CNode* pNode = NewNode( NULL, m_pHead );
1421 if( m_pHead != NULL )
1423 m_pHead->m_pPrev = pNode;
1431 return( SPOSITION( pNode ) );
1434template<
typename E,
class ETraits >
1435SPOSITION SList< E, ETraits >::AddHead( INARGTYPE element )
1439 pNode = NewNode( element, NULL, m_pHead );
1441 if( m_pHead != NULL )
1443 m_pHead->m_pPrev = pNode;
1451 return( SPOSITION( pNode ) );
1454template<
typename E,
class ETraits >
1455SPOSITION SList< E, ETraits >::AddTail()
1457 CNode* pNode = NewNode( m_pTail, NULL );
1458 if( m_pTail != NULL )
1460 m_pTail->m_pNext = pNode;
1468 return( SPOSITION( pNode ) );
1471template<
typename E,
class ETraits >
1472SPOSITION SList< E, ETraits >::AddTail( INARGTYPE element )
1476 pNode = NewNode( element, m_pTail, NULL );
1478 if( m_pTail != NULL )
1480 m_pTail->m_pNext = pNode;
1488 return( SPOSITION( pNode ) );
1491template<
typename E,
class ETraits >
1492void SList< E, ETraits >::AddHeadList(
const SList< E, ETraits >* plNew )
1494 SENSURE( plNew != NULL );
1496 SPOSITION pos = plNew->GetTailPosition();
1497 while( pos != NULL )
1499 INARGTYPE element = plNew->GetPrev( pos );
1504template<
typename E,
class ETraits >
1505void SList< E, ETraits >::AddTailList(
const SList< E, ETraits >* plNew )
1507 SENSURE( plNew != NULL );
1509 SPOSITION pos = plNew->GetHeadPosition();
1510 while( pos != NULL )
1512 INARGTYPE element = plNew->GetNext( pos );
1517template<
typename E,
class ETraits >
1518E SList< E, ETraits >::RemoveHead()
1520 SENSURE( m_pHead != NULL );
1522 CNode* pNode = m_pHead;
1523 E element( pNode->m_element );
1525 m_pHead = pNode->m_pNext;
1526 if( m_pHead != NULL )
1528 m_pHead->m_pPrev = NULL;
1539template<
typename E,
class ETraits >
1540void SList< E, ETraits >::RemoveHeadNoReturn()
1542 SENSURE( m_pHead != NULL );
1544 CNode* pNode = m_pHead;
1546 m_pHead = pNode->m_pNext;
1547 if( m_pHead != NULL )
1549 m_pHead->m_pPrev = NULL;
1558template<
typename E,
class ETraits >
1559E SList< E, ETraits >::RemoveTail()
1561 SENSURE( m_pTail != NULL );
1563 CNode* pNode = m_pTail;
1565 E element( pNode->m_element );
1567 m_pTail = pNode->m_pPrev;
1568 if( m_pTail != NULL )
1570 m_pTail->m_pNext = NULL;
1581template<
typename E,
class ETraits >
1582void SList< E, ETraits >::RemoveTailNoReturn()
1584 SENSURE( m_pTail != NULL );
1586 CNode* pNode = m_pTail;
1588 m_pTail = pNode->m_pPrev;
1589 if( m_pTail != NULL )
1591 m_pTail->m_pNext = NULL;
1600template<
typename E,
class ETraits >
1601SPOSITION SList< E, ETraits >::InsertBefore( SPOSITION pos, INARGTYPE element )
1603 SASSERT_VALID(
this);
1606 return AddHead( element );
1609 CNode* pOldNode = (CNode*)pos;
1610 CNode* pNewNode = NewNode( element, pOldNode->m_pPrev, pOldNode );
1612 if( pOldNode->m_pPrev != NULL )
1614 pOldNode->m_pPrev->m_pNext = pNewNode;
1618 SASSERT( pOldNode == m_pHead );
1621 pOldNode->m_pPrev = pNewNode;
1623 return( SPOSITION( pNewNode ) );
1626template<
typename E,
class ETraits >
1627SPOSITION SList< E, ETraits >::InsertAfter( SPOSITION pos, INARGTYPE element )
1629 SASSERT_VALID(
this);
1632 return AddTail( element );
1635 CNode* pOldNode = (CNode*)pos;
1636 CNode* pNewNode = NewNode( element, pOldNode, pOldNode->m_pNext );
1638 if( pOldNode->m_pNext != NULL )
1640 pOldNode->m_pNext->m_pPrev = pNewNode;
1644 SASSERT( pOldNode == m_pTail );
1647 pOldNode->m_pNext = pNewNode;
1649 return( SPOSITION( pNewNode ) );
1652template<
typename E,
class ETraits >
1653void SList< E, ETraits >::RemoveAt( SPOSITION pos )
1655 SASSERT_VALID(
this);
1656 SENSURE( pos != NULL );
1658 CNode* pOldNode = (CNode*)pos;
1661 if( pOldNode == m_pHead )
1663 m_pHead = pOldNode->m_pNext;
1667 pOldNode->m_pPrev->m_pNext = pOldNode->m_pNext;
1669 if( pOldNode == m_pTail )
1671 m_pTail = pOldNode->m_pPrev;
1675 pOldNode->m_pNext->m_pPrev = pOldNode->m_pPrev;
1677 FreeNode( pOldNode );
1680template<
typename E,
class ETraits >
1681SPOSITION SList< E, ETraits >::FindIndex(
size_t iElement )
const
1683 SASSERT_VALID(
this);
1685 if( iElement >= m_nElements )
1691 CNode* pNode = m_pHead;
1692 for(
size_t iSearch = 0; iSearch < iElement; iSearch++ )
1694 pNode = pNode->m_pNext;
1697 return( SPOSITION( pNode ) );
1700template<
typename E,
class ETraits >
1701void SList< E, ETraits >::MoveToHead( SPOSITION pos )
1703 SENSURE( pos != NULL );
1705 CNode* pNode =
static_cast< CNode*
>( pos );
1707 if( pNode == m_pHead )
1713 if( pNode->m_pNext == NULL )
1715 SASSERT( pNode == m_pTail );
1716 m_pTail = pNode->m_pPrev;
1720 pNode->m_pNext->m_pPrev = pNode->m_pPrev;
1723 SASSERT( pNode->m_pPrev != NULL );
1724 pNode->m_pPrev->m_pNext = pNode->m_pNext;
1726 m_pHead->m_pPrev = pNode;
1727 pNode->m_pNext = m_pHead;
1728 pNode->m_pPrev = NULL;
1732template<
typename E,
class ETraits >
1733void SList< E, ETraits >::MoveToTail( SPOSITION pos )
1735 SENSURE( pos != NULL );
1736 CNode* pNode =
static_cast< CNode*
>( pos );
1738 if( pNode == m_pTail )
1744 if( pNode->m_pPrev == NULL )
1746 SENSURE( pNode == m_pHead );
1747 m_pHead = pNode->m_pNext;
1751 pNode->m_pPrev->m_pNext = pNode->m_pNext;
1754 pNode->m_pNext->m_pPrev = pNode->m_pPrev;
1756 m_pTail->m_pNext = pNode;
1757 pNode->m_pPrev = m_pTail;
1758 pNode->m_pNext = NULL;
1762template<
typename E,
class ETraits >
1763void SList< E, ETraits >::Swap(SList<E,ETraits> &src)
1765 CNode* pHead = m_pHead;
1766 CNode* pTail = m_pTail;
1767 size_t nElements = m_nElements;
1768 SPlex* pBlocks = m_pBlocks;
1769 CNode* pFree = m_pFree;
1770 UINT nBlockSize = m_nBlockSize;
1772 m_pHead = src.m_pHead;
1773 m_pTail = src.m_pTail;
1774 m_nElements = src.m_nElements;
1775 m_pBlocks = src.m_pBlocks;
1776 m_pFree = src.m_pFree;
1777 m_nBlockSize = src.m_nBlockSize;
1779 src.m_pHead = pHead;
1780 src.m_pTail = pTail;
1781 src.m_nElements = nElements;
1782 src.m_pBlocks = pBlocks;
1783 src.m_pFree = pFree;
1784 src.m_nBlockSize = nBlockSize;
1787template<
typename E,
class ETraits >
1788void SList< E, ETraits >::SwapElements( SPOSITION pos1, SPOSITION pos2 )
1790 SASSERT( pos1 != NULL );
1791 SASSERT( pos2 != NULL );
1799 CNode* pNode1 =
static_cast< CNode*
>( pos1 );
1800 CNode* pNode2 =
static_cast< CNode*
>( pos2 );
1801 if( pNode2->m_pNext == pNode1 )
1804 CNode* pNodeTemp = pNode1;
1808 if( pNode1->m_pNext == pNode2 )
1811 pNode2->m_pPrev = pNode1->m_pPrev;
1812 if( pNode1->m_pPrev != NULL )
1814 pNode1->m_pPrev->m_pNext = pNode2;
1818 SASSUME( m_pHead == pNode1 );
1821 pNode1->m_pNext = pNode2->m_pNext;
1822 if( pNode2->m_pNext != NULL )
1824 pNode2->m_pNext->m_pPrev = pNode1;
1828 SASSUME( m_pTail == pNode2 );
1831 pNode2->m_pNext = pNode1;
1832 pNode1->m_pPrev = pNode2;
1839 pNodeTemp = pNode1->m_pPrev;
1840 pNode1->m_pPrev = pNode2->m_pPrev;
1841 pNode2->m_pPrev = pNodeTemp;
1843 pNodeTemp = pNode1->m_pNext;
1844 pNode1->m_pNext = pNode2->m_pNext;
1845 pNode2->m_pNext = pNodeTemp;
1847 if( pNode1->m_pNext != NULL )
1849 pNode1->m_pNext->m_pPrev = pNode1;
1853 SASSUME( m_pTail == pNode2 );
1856 if( pNode1->m_pPrev != NULL )
1858 pNode1->m_pPrev->m_pNext = pNode1;
1862 SASSUME( m_pHead == pNode2 );
1865 if( pNode2->m_pNext != NULL )
1867 pNode2->m_pNext->m_pPrev = pNode2;
1871 SASSUME( m_pTail == pNode1 );
1874 if( pNode2->m_pPrev != NULL )
1876 pNode2->m_pPrev->m_pNext = pNode2;
1880 SASSUME( m_pHead == pNode1 );
1886template<
typename E,
class ETraits >
1887SPOSITION SList< E, ETraits >::Find( INARGTYPE element, SPOSITION posStartAfter )
const
1889 SASSERT_VALID(
this);
1891 CNode* pNode = (CNode*)posStartAfter;
1898 pNode = pNode->m_pNext;
1901 for( ; pNode != NULL; pNode = pNode->m_pNext )
1903 if( ETraits::CompareElements( pNode->m_element, element ) )
1904 return( SPOSITION( pNode ) );
1911template<
typename E,
class ETraits >
1912void SList< E, ETraits >::AssertValid()
const
1917 SASSUME(m_pHead == NULL);
1918 SASSUME(m_pTail == NULL);
1927template<
typename K,
typename V,
class KTraits = CElementTraits< K >,
class VTraits = CElementTraits< V > >
1931 typedef typename KTraits::INARGTYPE KINARGTYPE;
1932 typedef typename KTraits::OUTARGTYPE KOUTARGTYPE;
1933 typedef typename VTraits::INARGTYPE VINARGTYPE;
1934 typedef typename VTraits::OUTARGTYPE VOUTARGTYPE;
1940 CPair( KINARGTYPE key ) :
1955 CNode( KINARGTYPE key, UINT nHash ) :
1962 UINT GetHash()
const
1973 SMap( UINT nBins = 17,
float fOptimalLoad = 0.75f,
1974 float fLoThreshold = 0.25f,
float fHiThreshold = 2.25f, UINT nBlockSize = 10 );
1977 SMap& operator=(
const SMap& src);
1979 void Copy(
const SMap & src);
1981 size_t GetCount()
const;
1982 bool IsEmpty()
const;
1984 bool Lookup( KINARGTYPE key, VOUTARGTYPE value )
const;
1985 const CPair* Lookup( KINARGTYPE key )
const;
1986 CPair* Lookup( KINARGTYPE key );
1987 V& operator[]( KINARGTYPE key ) ;
1988 const V& operator[]( KINARGTYPE key )
const;
1990 SPOSITION SetAt( KINARGTYPE key, VINARGTYPE value );
1991 void SetValueAt( SPOSITION pos, VINARGTYPE value );
1993 bool RemoveKey( KINARGTYPE key );
1995 void RemoveAtPos( SPOSITION pos );
1997 SPOSITION GetStartPosition()
const;
1998 void GetNextAssoc( SPOSITION& pos, KOUTARGTYPE key, VOUTARGTYPE value )
const;
1999 const CPair* GetNext( SPOSITION& pos )
const;
2000 CPair* GetNext( SPOSITION& pos );
2001 const K& GetNextKey( SPOSITION& pos )
const;
2002 const V& GetNextValue( SPOSITION& pos )
const;
2003 V& GetNextValue( SPOSITION& pos );
2004 void GetAt( SPOSITION pos, KOUTARGTYPE key, VOUTARGTYPE value )
const;
2005 CPair* GetAt( SPOSITION pos );
2006 const CPair* GetAt( SPOSITION pos )
const;
2007 const K& GetKeyAt( SPOSITION pos )
const;
2008 const V& GetValueAt( SPOSITION pos )
const;
2009 V& GetValueAt( SPOSITION pos );
2011 UINT GetHashTableSize()
const;
2012 bool InitHashTable( UINT nBins,
bool bAllocNow =
true );
2013 void EnableAutoRehash();
2014 void DisableAutoRehash();
2015 void Rehash( UINT nBins = 0 );
2016 void SetOptimalLoad(
float fOptimalLoad,
float fLoThreshold,
float fHiThreshold,
2017 bool bRehashNow =
false );
2020 void AssertValid()
const;
2028 float m_fOptimalLoad;
2029 float m_fLoThreshold;
2030 float m_fHiThreshold;
2031 size_t m_nHiRehashThreshold;
2032 size_t m_nLoRehashThreshold;
2039 bool IsLocked()
const;
2040 UINT PickSize(
size_t nElements )
const;
2041 CNode* NewNode( KINARGTYPE key, UINT iBin, UINT nHash );
2042 void FreeNode( CNode* pNode );
2044 CNode* GetNode( KINARGTYPE key, UINT& iBin, UINT& nHash, CNode*& pPrev )
const;
2045 CNode* CreateNode( KINARGTYPE key, UINT iBin, UINT nHash ) ;
2046 void RemoveNode( CNode* pNode, CNode* pPrev );
2047 CNode* FindNextNode( CNode* pNode )
const;
2048 void UpdateRehashThresholds();
2052template<
typename K,
typename V,
class KTraits,
class VTraits >
2053inline size_t SMap< K, V, KTraits, VTraits >::GetCount()
const
2055 return( m_nElements );
2058template<
typename K,
typename V,
class KTraits,
class VTraits >
2059inline bool SMap< K, V, KTraits, VTraits >::IsEmpty()
const
2061 return( m_nElements == 0 );
2064template<
typename K,
typename V,
class KTraits,
class VTraits >
2065inline V& SMap< K, V, KTraits, VTraits >::operator[]( KINARGTYPE key )
2072 pNode = GetNode( key, iBin, nHash, pPrev );
2075 pNode = CreateNode( key, iBin, nHash );
2078 return( pNode->m_value );
2081template<
typename K,
typename V,
class KTraits,
class VTraits >
2082inline const V& SMap< K, V, KTraits, VTraits >::operator[]( KINARGTYPE key )
const
2089 pNode = GetNode( key, iBin, nHash, pPrev );
2091 return( pNode->m_value );
2095template<
typename K,
typename V,
class KTraits,
class VTraits >
2096inline UINT SMap< K, V, KTraits, VTraits >::GetHashTableSize()
const
2101template<
typename K,
typename V,
class KTraits,
class VTraits >
2102inline void SMap< K, V, KTraits, VTraits >::GetAt( SPOSITION pos, KOUTARGTYPE key, VOUTARGTYPE value )
const
2104 SENSURE( pos != NULL );
2106 CNode* pNode =
static_cast< CNode*
>( pos );
2109 value = pNode->m_value;
2112template<
typename K,
typename V,
class KTraits,
class VTraits >
2113inline typename SMap< K, V, KTraits, VTraits >::CPair* SMap< K, V, KTraits, VTraits >::GetAt( SPOSITION pos )
2115 SASSERT( pos != NULL );
2117 return(
static_cast< CPair*
>( pos ) );
2120template<
typename K,
typename V,
class KTraits,
class VTraits >
2121inline const typename SMap< K, V, KTraits, VTraits >::CPair* SMap< K, V, KTraits, VTraits >::GetAt( SPOSITION pos )
const
2123 SASSERT( pos != NULL );
2125 return(
static_cast< const CPair*
>( pos ) );
2128template<
typename K,
typename V,
class KTraits,
class VTraits >
2129inline const K& SMap< K, V, KTraits, VTraits >::GetKeyAt( SPOSITION pos )
const
2131 SENSURE( pos != NULL );
2133 CNode* pNode = (CNode*)pos;
2135 return( pNode->m_key );
2138template<
typename K,
typename V,
class KTraits,
class VTraits >
2139inline const V& SMap< K, V, KTraits, VTraits >::GetValueAt( SPOSITION pos )
const
2141 SENSURE( pos != NULL );
2143 CNode* pNode = (CNode*)pos;
2145 return( pNode->m_value );
2148template<
typename K,
typename V,
class KTraits,
class VTraits >
2149inline V& SMap< K, V, KTraits, VTraits >::GetValueAt( SPOSITION pos )
2151 SENSURE( pos != NULL );
2153 CNode* pNode = (CNode*)pos;
2155 return( pNode->m_value );
2158template<
typename K,
typename V,
class KTraits,
class VTraits >
2159inline void SMap< K, V, KTraits, VTraits >::DisableAutoRehash()
2164template<
typename K,
typename V,
class KTraits,
class VTraits >
2165inline void SMap< K, V, KTraits, VTraits >::EnableAutoRehash()
2167 SASSUME( m_nLockCount > 0 );
2171template<
typename K,
typename V,
class KTraits,
class VTraits >
2172inline bool SMap< K, V, KTraits, VTraits >::IsLocked()
const
2174 return( m_nLockCount != 0 );
2177template<
typename K,
typename V,
class KTraits,
class VTraits >
2178UINT SMap< K, V, KTraits, VTraits >::PickSize(
size_t nElements )
const
2181 static const UINT s_anPrimes[] =
2183 17, 23, 29, 37, 41, 53, 67, 83, 103, 131, 163, 211, 257, 331, 409, 521, 647, 821,
2184 1031, 1291, 1627, 2053, 2591, 3251, 4099, 5167, 6521, 8209, 10331,
2185 13007, 16411, 20663, 26017, 32771, 41299, 52021, 65537, 82571, 104033,
2186 131101, 165161, 208067, 262147, 330287, 416147, 524309, 660563,
2187 832291, 1048583, 1321139, 1664543, 2097169, 2642257, 3329023, 4194319,
2188 5284493, 6658049, 8388617, 10568993, 13316089, UINT_MAX
2191 size_t nBins = (size_t)(nElements/m_fOptimalLoad);
2192 UINT nBinsEstimate = UINT( UINT_MAX < nBins ? UINT_MAX : nBins );
2196 while( nBinsEstimate > s_anPrimes[iPrime] )
2201 if( s_anPrimes[iPrime] == UINT_MAX )
2203 return( nBinsEstimate );
2207 return( s_anPrimes[iPrime] );
2211template<
typename K,
typename V,
class KTraits,
class VTraits >
2212typename SMap< K, V, KTraits, VTraits >::CNode* SMap< K, V, KTraits, VTraits >::CreateNode(
2213 KINARGTYPE key, UINT iBin, UINT nHash )
2217 if( m_ppBins == NULL )
2221 bSuccess = InitHashTable( m_nBins );
2224 SThrow( E_OUTOFMEMORY );
2228 pNode = NewNode( key, iBin, nHash );
2233template<
typename K,
typename V,
class KTraits,
class VTraits >
2234SPOSITION SMap< K, V, KTraits, VTraits >::GetStartPosition()
const
2241 for( UINT iBin = 0; iBin < m_nBins; iBin++ )
2243 if( m_ppBins[iBin] != NULL )
2245 return( SPOSITION( m_ppBins[iBin] ) );
2253template<
typename K,
typename V,
class KTraits,
class VTraits >
2254SPOSITION SMap< K, V, KTraits, VTraits >::SetAt( KINARGTYPE key, VINARGTYPE value )
2261 pNode = GetNode( key, iBin, nHash, pPrev );
2264 pNode = CreateNode( key, iBin, nHash );
2267 pNode->m_value = value;
2276 pNode->m_value = value;
2279 return( SPOSITION( pNode ) );
2282template<
typename K,
typename V,
class KTraits,
class VTraits >
2283void SMap< K, V, KTraits, VTraits >::SetValueAt( SPOSITION pos, VINARGTYPE value )
2285 SASSERT( pos != NULL );
2287 CNode* pNode =
static_cast< CNode*
>( pos );
2289 pNode->m_value = value;
2292template<
typename K,
typename V,
class KTraits,
class VTraits >
2293SMap< K, V, KTraits, VTraits >::SMap( UINT nBins,
float fOptimalLoad,
2294 float fLoThreshold,
float fHiThreshold, UINT nBlockSize ) :
2298 m_fOptimalLoad( fOptimalLoad ),
2299 m_fLoThreshold( fLoThreshold ),
2300 m_fHiThreshold( fHiThreshold ),
2301 m_nHiRehashThreshold( UINT_MAX ),
2302 m_nLoRehashThreshold( 0 ),
2304 m_nBlockSize( nBlockSize ),
2308 SASSERT( nBins > 0 );
2309 SASSERT( nBlockSize > 0 );
2311 SetOptimalLoad( fOptimalLoad, fLoThreshold, fHiThreshold,
false );
2314template<
typename K,
typename V,
class KTraits,
class VTraits >
2315SMap< K, V, KTraits, VTraits >::SMap(
const SMap< K, V, KTraits, VTraits > & src) :
2318 m_nBins(src.m_nBins),
2319 m_fOptimalLoad(src.m_fOptimalLoad),
2320 m_fLoThreshold(src.m_fLoThreshold),
2321 m_fHiThreshold(src.m_fHiThreshold),
2322 m_nHiRehashThreshold(src.m_nHiRehashThreshold),
2323 m_nLoRehashThreshold(src.m_nLoRehashThreshold),
2325 m_nBlockSize(src.m_nBlockSize),
2329 SetOptimalLoad(m_fOptimalLoad, m_fLoThreshold, m_fHiThreshold,
false);
2333template<
typename K,
typename V,
class KTraits,
class VTraits >
2334void SMap< K, V, KTraits, VTraits >::Copy(
const SMap< K, V, KTraits, VTraits > & src)
2337 SPOSITION pos = src.GetStartPosition();
2340 const SMap< K, V, KTraits, VTraits >::CPair * p = src.GetNext(pos);
2341 this->SetAt(p->m_key, p->m_value);
2345template<
typename K,
typename V,
class KTraits,
class VTraits >
2346SMap< K, V, KTraits, VTraits >& SMap< K, V, KTraits, VTraits >::operator=(
const SMap< K, V, KTraits, VTraits > & src)
2353template<
typename K,
typename V,
class KTraits,
class VTraits >
2354void SMap< K, V, KTraits, VTraits >::SetOptimalLoad(
float fOptimalLoad,
float fLoThreshold,
2355 float fHiThreshold,
bool bRehashNow )
2357 SASSERT( fOptimalLoad > 0 );
2358 SASSERT( (fLoThreshold >= 0) && (fLoThreshold < fOptimalLoad) );
2359 SASSERT( fHiThreshold > fOptimalLoad );
2361 m_fOptimalLoad = fOptimalLoad;
2362 m_fLoThreshold = fLoThreshold;
2363 m_fHiThreshold = fHiThreshold;
2365 UpdateRehashThresholds();
2367 if( bRehashNow && ((m_nElements > m_nHiRehashThreshold) ||
2368 (m_nElements < m_nLoRehashThreshold)) )
2370 Rehash( PickSize( m_nElements ) );
2374template<
typename K,
typename V,
class KTraits,
class VTraits >
2375void SMap< K, V, KTraits, VTraits >::UpdateRehashThresholds()
2377 m_nHiRehashThreshold = size_t( m_fHiThreshold*m_nBins );
2378 m_nLoRehashThreshold = size_t( m_fLoThreshold*m_nBins );
2379 if( m_nLoRehashThreshold < 17 )
2381 m_nLoRehashThreshold = 0;
2385template<
typename K,
typename V,
class KTraits,
class VTraits >
2386bool SMap< K, V, KTraits, VTraits >::InitHashTable( UINT nBins,
bool bAllocNow )
2388 SASSUME( m_nElements == 0 );
2389 SASSERT( nBins > 0 );
2391 if( m_ppBins != NULL )
2393 soui_mem_wrapper::SouiFree(m_ppBins);
2400 m_ppBins = (CNode**)soui_mem_wrapper::SouiMalloc(nBins*
sizeof(CNode*));
2401 if( m_ppBins == NULL )
2406 SENSURE( UINT_MAX /
sizeof( CNode* ) >= nBins );
2407 memset( m_ppBins, 0,
sizeof( CNode* )*nBins );
2411 UpdateRehashThresholds();
2416template<
typename K,
typename V,
class KTraits,
class VTraits >
2417void SMap< K, V, KTraits, VTraits >::RemoveAll()
2419 DisableAutoRehash();
2420 if( m_ppBins != NULL )
2422 for( UINT iBin = 0; iBin < m_nBins; iBin++ )
2426 pNext = m_ppBins[iBin];
2427 while( pNext != NULL )
2432 pNext = pNext->m_pNext;
2438 soui_mem_wrapper::SouiFree(m_ppBins);
2444 InitHashTable( PickSize( m_nElements ),
false );
2451template<
typename K,
typename V,
class KTraits,
class VTraits >
2452SMap< K, V, KTraits, VTraits >::~SMap()
2457#pragma push_macro("new")
2460template<
typename K,
typename V,
class KTraits,
class VTraits >
2461typename SMap< K, V, KTraits, VTraits >::CNode* SMap< K, V, KTraits, VTraits >::NewNode(
2462 KINARGTYPE key, UINT iBin, UINT nHash )
2466 if( m_pFree == NULL )
2471 pPlex = SPlex::Create( m_pBlocks, m_nBlockSize,
sizeof( CNode ) );
2474 SThrow( E_OUTOFMEMORY );
2476 pNode = (CNode*)pPlex->data();
2477 pNode += m_nBlockSize-1;
2478 for(
int iBlock = m_nBlockSize-1; iBlock >= 0; iBlock-- )
2480 pNode->m_pNext = m_pFree;
2485 SENSURE(m_pFree != NULL );
2487 m_pFree = pNewNode->m_pNext;
2491 ::new( pNewNode ) CNode( key, nHash );
2501 pNewNode->m_pNext = m_ppBins[iBin];
2502 m_ppBins[iBin] = pNewNode;
2504 if( (m_nElements > m_nHiRehashThreshold) && !IsLocked() )
2506 Rehash( PickSize( m_nElements ) );
2512#pragma pop_macro("new")
2514template<
typename K,
typename V,
class KTraits,
class VTraits >
2515void SMap< K, V, KTraits, VTraits >::FreeNode( CNode* pNode )
2517 SENSURE( pNode != NULL );
2520 pNode->m_pNext = m_pFree;
2523 SASSUME( m_nElements > 0 );
2526 if( (m_nElements < m_nLoRehashThreshold) && !IsLocked() )
2528 Rehash( PickSize( m_nElements ) );
2531 if( m_nElements == 0 )
2537template<
typename K,
typename V,
class KTraits,
class VTraits >
2538void SMap< K, V, KTraits, VTraits >::FreePlexes()
2541 if( m_pBlocks != NULL )
2543 m_pBlocks->FreeDataChain();
2548template<
typename K,
typename V,
class KTraits,
class VTraits >
2549typename SMap< K, V, KTraits, VTraits >::CNode* SMap< K, V, KTraits, VTraits >::GetNode(
2550 KINARGTYPE key, UINT& iBin, UINT& nHash, CNode*& pPrev )
const
2554 nHash = KTraits::Hash( key );
2555 iBin = nHash%m_nBins;
2557 if( m_ppBins == NULL )
2564 for( CNode* pNode = m_ppBins[iBin]; pNode != NULL; pNode = pNode->m_pNext )
2566 if( (pNode->GetHash() == nHash) && KTraits::CompareElements( pNode->m_key, key ) )
2577template<
typename K,
typename V,
class KTraits,
class VTraits >
2578bool SMap< K, V, KTraits, VTraits >::Lookup( KINARGTYPE key, VOUTARGTYPE value )
const
2585 pNode = GetNode( key, iBin, nHash, pPrev );
2591 value = pNode->m_value;
2596template<
typename K,
typename V,
class KTraits,
class VTraits >
2597const typename SMap< K, V, KTraits, VTraits >::CPair* SMap< K, V, KTraits, VTraits >::Lookup( KINARGTYPE key )
const
2604 pNode = GetNode( key, iBin, nHash, pPrev );
2609template<
typename K,
typename V,
class KTraits,
class VTraits >
2610typename SMap< K, V, KTraits, VTraits >::CPair* SMap< K, V, KTraits, VTraits >::Lookup( KINARGTYPE key )
2617 pNode = GetNode( key, iBin, nHash, pPrev );
2622template<
typename K,
typename V,
class KTraits,
class VTraits >
2623bool SMap< K, V, KTraits, VTraits >::RemoveKey( KINARGTYPE key )
2631 pNode = GetNode( key, iBin, nHash, pPrev );
2637 RemoveNode( pNode, pPrev );
2642template<
typename K,
typename V,
class KTraits,
class VTraits >
2643void SMap< K, V, KTraits, VTraits >::RemoveNode( CNode* pNode, CNode* pPrev )
2645 SENSURE( pNode != NULL );
2647 UINT iBin = pNode->GetHash() % m_nBins;
2651 SASSUME( m_ppBins[iBin] == pNode );
2652 m_ppBins[iBin] = pNode->m_pNext;
2656 SASSERT( pPrev->m_pNext == pNode );
2657 pPrev->m_pNext = pNode->m_pNext;
2662template<
typename K,
typename V,
class KTraits,
class VTraits >
2663void SMap< K, V, KTraits, VTraits >::RemoveAtPos( SPOSITION pos )
2665 SENSURE( pos != NULL );
2667 CNode* pNode =
static_cast< CNode*
>( pos );
2668 CNode* pPrev = NULL;
2669 UINT iBin = pNode->GetHash() % m_nBins;
2671 SASSUME( m_ppBins[iBin] != NULL );
2672 if( pNode == m_ppBins[iBin] )
2678 pPrev = m_ppBins[iBin];
2679 while( pPrev->m_pNext != pNode )
2681 pPrev = pPrev->m_pNext;
2682 SASSERT( pPrev != NULL );
2685 RemoveNode( pNode, pPrev );
2688template<
typename K,
typename V,
class KTraits,
class VTraits >
2689void SMap< K, V, KTraits, VTraits >::Rehash( UINT nBins )
2691 CNode** ppBins = NULL;
2695 nBins = PickSize( m_nElements );
2698 if( nBins == m_nBins )
2703 if( m_ppBins == NULL )
2706 InitHashTable( nBins,
false );
2711 ppBins = (CNode**)soui_mem_wrapper::SouiMalloc(nBins*
sizeof(CNode*));
2717 SENSURE( UINT_MAX /
sizeof( CNode* ) >= nBins );
2718 memset( ppBins, 0, nBins*
sizeof( CNode* ) );
2722 for( UINT iSrcBin = 0; iSrcBin < m_nBins; iSrcBin++ )
2726 pNode = m_ppBins[iSrcBin];
2727 while( pNode != NULL )
2732 pNext = pNode->m_pNext;
2733 iDestBin = pNode->GetHash()%nBins;
2734 pNode->m_pNext = ppBins[iDestBin];
2735 ppBins[iDestBin] = pNode;
2741 soui_mem_wrapper::SouiFree(m_ppBins);
2745 UpdateRehashThresholds();
2748template<
typename K,
typename V,
class KTraits,
class VTraits >
2749void SMap< K, V, KTraits, VTraits >::GetNextAssoc( SPOSITION& pos, KOUTARGTYPE key,
2750 VOUTARGTYPE value )
const
2755 SASSUME( m_ppBins != NULL );
2756 SENSURE( pos != NULL );
2758 pNode = (CNode*)pos;
2759 pNext = FindNextNode( pNode );
2761 pos = SPOSITION( pNext );
2763 value = pNode->m_value;
2766template<
typename K,
typename V,
class KTraits,
class VTraits >
2767const typename SMap< K, V, KTraits, VTraits >::CPair* SMap< K, V, KTraits, VTraits >::GetNext( SPOSITION& pos )
const
2772 SASSUME( m_ppBins != NULL );
2773 SASSERT( pos != NULL );
2775 pNode = (CNode*)pos;
2776 pNext = FindNextNode( pNode );
2778 pos = SPOSITION( pNext );
2783template<
typename K,
typename V,
class KTraits,
class VTraits >
2784typename SMap< K, V, KTraits, VTraits >::CPair* SMap< K, V, KTraits, VTraits >::GetNext(
2787 SASSUME( m_ppBins != NULL );
2788 SASSERT( pos != NULL );
2790 CNode* pNode =
static_cast< CNode*
>( pos );
2791 CNode* pNext = FindNextNode( pNode );
2793 pos = SPOSITION( pNext );
2798template<
typename K,
typename V,
class KTraits,
class VTraits >
2799const K& SMap< K, V, KTraits, VTraits >::GetNextKey( SPOSITION& pos )
const
2804 SASSUME( m_ppBins != NULL );
2805 SENSURE( pos != NULL );
2807 pNode = (CNode*)pos;
2808 pNext = FindNextNode( pNode );
2810 pos = SPOSITION( pNext );
2812 return( pNode->m_key );
2815template<
typename K,
typename V,
class KTraits,
class VTraits >
2816const V& SMap< K, V, KTraits, VTraits >::GetNextValue( SPOSITION& pos )
const
2821 SASSUME( m_ppBins != NULL );
2822 SENSURE( pos != NULL );
2824 pNode = (CNode*)pos;
2825 pNext = FindNextNode( pNode );
2827 pos = SPOSITION( pNext );
2829 return( pNode->m_value );
2832template<
typename K,
typename V,
class KTraits,
class VTraits >
2833V& SMap< K, V, KTraits, VTraits >::GetNextValue( SPOSITION& pos )
2838 SASSUME( m_ppBins != NULL );
2839 SENSURE( pos != NULL );
2841 pNode = (CNode*)pos;
2842 pNext = FindNextNode( pNode );
2844 pos = SPOSITION( pNext );
2846 return( pNode->m_value );
2849template<
typename K,
typename V,
class KTraits,
class VTraits >
2850typename SMap< K, V, KTraits, VTraits >::CNode* SMap< K, V, KTraits, VTraits >::FindNextNode( CNode* pNode )
const
2860 if( pNode->m_pNext != NULL )
2862 pNext = pNode->m_pNext;
2869 iBin = (pNode->GetHash()%m_nBins)+1;
2870 while( (pNext == NULL) && (iBin < m_nBins) )
2872 if( m_ppBins[iBin] != NULL )
2874 pNext = m_ppBins[iBin];
2885template<
typename K,
typename V,
class KTraits,
class VTraits >
2886void SMap< K, V, KTraits, VTraits >::AssertValid()
const
2888 SASSUME( m_nBins > 0 );
2890 SASSERT( IsEmpty() || (m_ppBins != NULL) );
2898template<
typename K,
typename V,
class KTraits = CElementTraits< K >,
class VTraits = CElementTraits< V > >
2902 typedef typename KTraits::INARGTYPE KINARGTYPE;
2903 typedef typename KTraits::OUTARGTYPE KOUTARGTYPE;
2904 typedef typename VTraits::INARGTYPE VINARGTYPE;
2905 typedef typename VTraits::OUTARGTYPE VOUTARGTYPE;
2913 CPair( KINARGTYPE key, VINARGTYPE value ) :
2945 CNode( KINARGTYPE key, VINARGTYPE value ) :
2946 CPair( key, value ),
2948 m_eColor( RB_BLACK )
2961 size_t m_nBlockSize;
2967 bool IsNil(CNode *p)
const ;
2968 void SetNil(CNode **p) ;
2970 CNode* NewNode( KINARGTYPE key, VINARGTYPE value );
2971 void FreeNode(CNode* pNode) ;
2972 void RemovePostOrder(CNode* pNode) ;
2973 CNode* LeftRotate(CNode* pNode) ;
2974 CNode* RightRotate(CNode* pNode) ;
2975 void SwapNode(CNode* pDest, CNode* pSrc) ;
2976 CNode* InsertImpl( KINARGTYPE key, VINARGTYPE value );
2977 void RBDeleteFixup(CNode* pNode) ;
2978 bool RBDelete(CNode* pZ) ;
2989 void VerifyIntegrity(
const CNode *pNode,
int nCurrBlackDepth,
int &nBlackDepth)
const ;
2992 void VerifyIntegrity()
const ;
2997 CNode* Minimum(CNode* pNode)
const ;
2998 CNode* Maximum(CNode* pNode)
const ;
2999 CNode* Predecessor( CNode* pNode )
const ;
3000 CNode* Successor(CNode* pNode)
const ;
3001 CNode* RBInsert( KINARGTYPE key, VINARGTYPE value ) ;
3002 CNode* Find(KINARGTYPE key)
const ;
3003 CNode* FindPrefix( KINARGTYPE key )
const ;
3006 explicit SRBTree(
size_t nBlockSize = 10);
3010 void RemoveAt(SPOSITION pos) ;
3012 size_t GetCount()
const ;
3013 bool IsEmpty()
const ;
3015 SPOSITION FindFirstKeyAfter( KINARGTYPE key )
const ;
3017 SPOSITION GetHeadPosition()
const ;
3018 SPOSITION GetTailPosition()
const ;
3019 void GetNextAssoc( SPOSITION& pos, KOUTARGTYPE key, VOUTARGTYPE value )
const;
3020 const CPair* GetNext(SPOSITION& pos)
const ;
3021 CPair* GetNext(SPOSITION& pos) ;
3022 const CPair* GetPrev(SPOSITION& pos)
const ;
3023 CPair* GetPrev(SPOSITION& pos) ;
3024 const K& GetNextKey(SPOSITION& pos)
const ;
3025 const V& GetNextValue(SPOSITION& pos)
const ;
3026 V& GetNextValue(SPOSITION& pos) ;
3028 CPair* GetAt( SPOSITION pos ) ;
3029 const CPair* GetAt( SPOSITION pos )
const ;
3030 void GetAt(SPOSITION pos, KOUTARGTYPE key, VOUTARGTYPE value)
const;
3031 const K& GetKeyAt(SPOSITION pos)
const;
3032 const V& GetValueAt(SPOSITION pos)
const;
3033 V& GetValueAt(SPOSITION pos);
3034 void SetValueAt(SPOSITION pos, VINARGTYPE value);
3038 SRBTree(
const SRBTree& ) ;
3039 SRBTree& operator=(
const SRBTree& ) ;
3042template<
typename K,
typename V,
class KTraits,
class VTraits >
3043inline bool SRBTree< K, V, KTraits, VTraits >::IsNil(CNode *p)
const
3045 return ( p == m_pNil );
3048template<
typename K,
typename V,
class KTraits,
class VTraits >
3049inline void SRBTree< K, V, KTraits, VTraits >::SetNil(CNode **p)
3051 SENSURE( p != NULL );
3055template<
typename K,
typename V,
class KTraits,
class VTraits >
3056SRBTree< K, V, KTraits, VTraits >::SRBTree(
size_t nBlockSize ) :
3059m_nBlockSize( nBlockSize ),
3064 SASSERT( nBlockSize > 0 );
3067template<
typename K,
typename V,
class KTraits,
class VTraits >
3068SRBTree< K, V, KTraits, VTraits >::~SRBTree()
3073 soui_mem_wrapper::SouiFree(m_pNil);
3077template<
typename K,
typename V,
class KTraits,
class VTraits >
3078void SRBTree< K, V, KTraits, VTraits >::RemoveAll()
3080 if (!IsNil(m_pRoot))
3081 RemovePostOrder(m_pRoot);
3083 m_pBlocks->FreeDataChain();
3089template<
typename K,
typename V,
class KTraits,
class VTraits >
3090size_t SRBTree< K, V, KTraits, VTraits >::GetCount()
const
3095template<
typename K,
typename V,
class KTraits,
class VTraits >
3096bool SRBTree< K, V, KTraits, VTraits >::IsEmpty()
const
3098 return( m_nCount == 0 );
3101template<
typename K,
typename V,
class KTraits,
class VTraits >
3102SPOSITION SRBTree< K, V, KTraits, VTraits >::FindFirstKeyAfter( KINARGTYPE key )
const
3104 return( FindPrefix( key ) );
3107template<
typename K,
typename V,
class KTraits,
class VTraits >
3108void SRBTree< K, V, KTraits, VTraits >::RemoveAt(SPOSITION pos)
3110 SASSERT(pos != NULL);
3111 RBDelete(
static_cast<CNode*
>(pos));
3114template<
typename K,
typename V,
class KTraits,
class VTraits >
3115SPOSITION SRBTree< K, V, KTraits, VTraits >::GetHeadPosition()
const
3117 return( Minimum( m_pRoot ) );
3120template<
typename K,
typename V,
class KTraits,
class VTraits >
3121SPOSITION SRBTree< K, V, KTraits, VTraits >::GetTailPosition()
const
3123 return( Maximum( m_pRoot ) );
3126template<
typename K,
typename V,
class KTraits,
class VTraits >
3127void SRBTree< K, V, KTraits, VTraits >::GetNextAssoc( SPOSITION& pos, KOUTARGTYPE key, VOUTARGTYPE value )
const
3129 SASSERT(pos != NULL);
3130 CNode* pNode =
static_cast< CNode*
>(pos);
3133 value = pNode->m_value;
3135 pos = Successor(pNode);
3138template<
typename K,
typename V,
class KTraits,
class VTraits >
3139const typename SRBTree< K, V, KTraits, VTraits >::CPair* SRBTree< K, V, KTraits, VTraits >::GetNext(SPOSITION& pos)
const
3141 SASSERT(pos != NULL);
3142 CNode* pNode =
static_cast< CNode*
>(pos);
3143 pos = Successor(pNode);
3147template<
typename K,
typename V,
class KTraits,
class VTraits >
3148typename SRBTree< K, V, KTraits, VTraits >::CPair* SRBTree< K, V, KTraits, VTraits >::GetNext(SPOSITION& pos)
3150 SASSERT(pos != NULL);
3151 CNode* pNode =
static_cast< CNode*
>(pos);
3152 pos = Successor(pNode);
3156template<
typename K,
typename V,
class KTraits,
class VTraits >
3157const typename SRBTree< K, V, KTraits, VTraits >::CPair* SRBTree< K, V, KTraits, VTraits >::GetPrev(SPOSITION& pos)
const
3159 SASSERT(pos != NULL);
3160 CNode* pNode =
static_cast< CNode*
>(pos);
3161 pos = Predecessor(pNode);
3166template<
typename K,
typename V,
class KTraits,
class VTraits >
3167typename SRBTree< K, V, KTraits, VTraits >::CPair* SRBTree< K, V, KTraits, VTraits >::GetPrev(SPOSITION& pos)
3169 SASSERT(pos != NULL);
3170 CNode* pNode =
static_cast< CNode*
>(pos);
3171 pos = Predecessor(pNode);
3176template<
typename K,
typename V,
class KTraits,
class VTraits >
3177const K& SRBTree< K, V, KTraits, VTraits >::GetNextKey(SPOSITION& pos)
const
3179 SASSERT(pos != NULL);
3180 CNode* pNode =
static_cast<CNode*
>(pos);
3181 pos = Successor(pNode);
3183 return pNode->m_key;
3186template<
typename K,
typename V,
class KTraits,
class VTraits >
3187const V& SRBTree< K, V, KTraits, VTraits >::GetNextValue(SPOSITION& pos)
const
3189 SASSERT(pos != NULL);
3190 CNode* pNode =
static_cast<CNode*
>(pos);
3191 pos = Successor(pNode);
3193 return pNode->m_value;
3196template<
typename K,
typename V,
class KTraits,
class VTraits >
3197V& SRBTree< K, V, KTraits, VTraits >::GetNextValue(SPOSITION& pos)
3199 SASSERT(pos != NULL);
3200 CNode* pNode =
static_cast<CNode*
>(pos);
3201 pos = Successor(pNode);
3203 return pNode->m_value;
3206template<
typename K,
typename V,
class KTraits,
class VTraits >
3207typename SRBTree< K, V, KTraits, VTraits >::CPair* SRBTree< K, V, KTraits, VTraits >::GetAt( SPOSITION pos )
3209 SASSERT( pos != NULL );
3211 return(
static_cast< CPair*
>( pos ) );
3214template<
typename K,
typename V,
class KTraits,
class VTraits >
3215const typename SRBTree< K, V, KTraits, VTraits >::CPair* SRBTree< K, V, KTraits, VTraits >::GetAt( SPOSITION pos )
const
3217 SASSERT( pos != NULL );
3219 return(
static_cast< const CPair*
>( pos ) );
3222template<
typename K,
typename V,
class KTraits,
class VTraits >
3223void SRBTree< K, V, KTraits, VTraits >::GetAt(SPOSITION pos, KOUTARGTYPE key, VOUTARGTYPE value)
const
3225 SENSURE( pos != NULL );
3226 key =
static_cast<CNode*
>(pos)->m_key;
3227 value =
static_cast<CNode*
>(pos)->m_value;
3230template<
typename K,
typename V,
class KTraits,
class VTraits >
3231const K& SRBTree< K, V, KTraits, VTraits >::GetKeyAt(SPOSITION pos)
const
3233 SENSURE( pos != NULL );
3234 return static_cast<CNode*
>(pos)->m_key;
3237template<
typename K,
typename V,
class KTraits,
class VTraits >
3238const V& SRBTree< K, V, KTraits, VTraits >::GetValueAt(SPOSITION pos)
const
3240 SENSURE( pos != NULL );
3241 return static_cast<CNode*
>(pos)->m_value;
3244template<
typename K,
typename V,
class KTraits,
class VTraits >
3245V& SRBTree< K, V, KTraits, VTraits >::GetValueAt(SPOSITION pos)
3247 SENSURE( pos != NULL );
3248 return static_cast<CNode*
>(pos)->m_value;
3251template<
typename K,
typename V,
class KTraits,
class VTraits >
3252void SRBTree< K, V, KTraits, VTraits >::SetValueAt(SPOSITION pos, VINARGTYPE value)
3254 SENSURE( pos != NULL );
3255 static_cast<CNode*
>(pos)->m_value = value;
3258#pragma push_macro("new")
3261template<
typename K,
typename V,
class KTraits,
class VTraits >
3262typename SRBTree< K, V, KTraits, VTraits >::CNode* SRBTree< K, V, KTraits, VTraits >::NewNode( KINARGTYPE key, VINARGTYPE value )
3264 if( m_pFree == NULL )
3268 m_pNil =
reinterpret_cast<CNode *
>(soui_mem_wrapper::SouiMalloc(
sizeof( CNode )));
3271 SThrow( E_OUTOFMEMORY );
3273 memset(m_pNil, 0x00,
sizeof(CNode));
3274 m_pNil->m_eColor = CNode::RB_BLACK;
3275 m_pNil->m_pParent = m_pNil->m_pLeft = m_pNil->m_pRight = m_pNil;
3279 SPlex* pPlex = SPlex::Create( m_pBlocks, m_nBlockSize,
sizeof( CNode ) );
3282 SThrow( E_OUTOFMEMORY );
3284 CNode* pNode =
static_cast< CNode*
>( pPlex->data() );
3285 pNode += m_nBlockSize-1;
3286 for( INT_PTR iBlock = m_nBlockSize-1; iBlock >= 0; iBlock-- )
3288 pNode->m_pLeft = m_pFree;
3293 SASSUME( m_pFree != NULL );
3295 CNode* pNewNode = m_pFree;
3296 ::new( pNewNode ) CNode( key, value );
3298 m_pFree = m_pFree->m_pLeft;
3299 pNewNode->m_eColor = CNode::RB_RED;
3300 SetNil(&pNewNode->m_pLeft);
3301 SetNil(&pNewNode->m_pRight);
3302 SetNil(&pNewNode->m_pParent);
3305 SASSUME( m_nCount > 0 );
3309#pragma pop_macro("new")
3311template<
typename K,
typename V,
class KTraits,
class VTraits >
3312void SRBTree< K, V, KTraits, VTraits >::FreeNode(CNode* pNode)
3314 SENSURE( pNode != NULL );
3316 pNode->m_pLeft = m_pFree;
3318 SASSUME( m_nCount > 0 );
3322template<
typename K,
typename V,
class KTraits,
class VTraits >
3323void SRBTree< K, V, KTraits, VTraits >::RemovePostOrder(CNode* pNode)
3327 RemovePostOrder(pNode->m_pLeft);
3328 RemovePostOrder(pNode->m_pRight);
3332template<
typename K,
typename V,
class KTraits,
class VTraits >
3333typename SRBTree< K, V, KTraits, VTraits >::CNode* SRBTree< K, V, KTraits, VTraits >::LeftRotate(CNode* pNode)
3335 SASSERT(pNode != NULL);
3339 CNode* pRight = pNode->m_pRight;
3340 pNode->m_pRight = pRight->m_pLeft;
3341 if (!IsNil(pRight->m_pLeft))
3342 pRight->m_pLeft->m_pParent = pNode;
3344 pRight->m_pParent = pNode->m_pParent;
3345 if (IsNil(pNode->m_pParent))
3347 else if (pNode == pNode->m_pParent->m_pLeft)
3348 pNode->m_pParent->m_pLeft = pRight;
3350 pNode->m_pParent->m_pRight = pRight;
3352 pRight->m_pLeft = pNode;
3353 pNode->m_pParent = pRight;
3358template<
typename K,
typename V,
class KTraits,
class VTraits >
3359typename SRBTree< K, V, KTraits, VTraits >::CNode* SRBTree< K, V, KTraits, VTraits >::RightRotate(CNode* pNode)
3361 SASSERT(pNode != NULL);
3365 CNode* pLeft = pNode->m_pLeft;
3366 pNode->m_pLeft = pLeft->m_pRight;
3367 if (!IsNil(pLeft->m_pRight))
3368 pLeft->m_pRight->m_pParent = pNode;
3370 pLeft->m_pParent = pNode->m_pParent;
3371 if (IsNil(pNode->m_pParent))
3373 else if (pNode == pNode->m_pParent->m_pRight)
3374 pNode->m_pParent->m_pRight = pLeft;
3376 pNode->m_pParent->m_pLeft = pLeft;
3378 pLeft->m_pRight = pNode;
3379 pNode->m_pParent = pLeft;
3383template<
typename K,
typename V,
class KTraits,
class VTraits >
3384typename SRBTree< K, V, KTraits, VTraits >::CNode* SRBTree< K, V, KTraits, VTraits >::Find(KINARGTYPE key)
const
3387 CNode* pNode = m_pRoot;
3388 while( !IsNil(pNode) && (pKey == NULL) )
3390 int nCompare = KTraits::CompareElementsOrdered( key, pNode->m_key );
3399 pNode = pNode->m_pLeft;
3403 pNode = pNode->m_pRight;
3413#pragma warning(push)
3414#pragma warning(disable:4127)
3418 CNode* pPrev = Predecessor( pKey );
3419 if( (pPrev != NULL) && KTraits::CompareElements( key, pPrev->m_key ) )
3432template<
typename K,
typename V,
class KTraits,
class VTraits >
3433typename SRBTree< K, V, KTraits, VTraits >::CNode* SRBTree< K, V, KTraits, VTraits >::FindPrefix( KINARGTYPE key )
const
3436 CNode* pParent = NULL;
3438 CNode* pNode = m_pRoot;
3439 while( !IsNil(pNode) && (pKey == NULL) )
3442 int nCompare = KTraits::CompareElementsOrdered( key, pNode->m_key );
3447 else if( nCompare < 0 )
3449 pNode = pNode->m_pLeft;
3453 pNode = pNode->m_pRight;
3463 CNode* pNext = Successor( pKey );
3464 if ((pNext != NULL) && KTraits::CompareElements( key, pNext->m_key ))
3474 else if (pParent != NULL)
3478 int nCompare = KTraits::CompareElementsOrdered( key, pParent->m_key );
3485 SASSERT( nCompare > 0 );
3486 pKey = Successor( pParent );
3493template<
typename K,
typename V,
class KTraits,
class VTraits >
3494void SRBTree< K, V, KTraits, VTraits >::SwapNode(CNode* pDest, CNode* pSrc)
3496 SENSURE( pDest != NULL );
3497 SENSURE( pSrc != NULL );
3499 pDest->m_pParent = pSrc->m_pParent;
3500 if (pSrc->m_pParent->m_pLeft == pSrc)
3502 pSrc->m_pParent->m_pLeft = pDest;
3506 pSrc->m_pParent->m_pRight = pDest;
3509 pDest->m_pRight = pSrc->m_pRight;
3510 pDest->m_pLeft = pSrc->m_pLeft;
3511 pDest->m_eColor = pSrc->m_eColor;
3512 pDest->m_pRight->m_pParent = pDest;
3513 pDest->m_pLeft->m_pParent = pDest;
3515 if (m_pRoot == pSrc)
3521template<
typename K,
typename V,
class KTraits,
class VTraits >
3522typename SRBTree< K, V, KTraits, VTraits >::CNode* SRBTree< K, V, KTraits, VTraits >::InsertImpl( KINARGTYPE key, VINARGTYPE value )
3524 CNode* pNew = NewNode( key, value );
3527 CNode* pX = m_pRoot;
3532 if( KTraits::CompareElementsOrdered( key, pX->m_key ) <= 0 )
3538 pNew->m_pParent = pY;
3543 else if( KTraits::CompareElementsOrdered( key, pY->m_key ) <= 0 )
3546 pY->m_pRight = pNew;
3551template<
typename K,
typename V,
class KTraits,
class VTraits >
3552void SRBTree< K, V, KTraits, VTraits >::RBDeleteFixup(CNode* pNode)
3554 SENSURE( pNode != NULL );
3559 while (( pX != m_pRoot ) && ( pX->m_eColor == CNode::RB_BLACK ))
3561 if (pX == pX->m_pParent->m_pLeft)
3563 pW = pX->m_pParent->m_pRight;
3564 if (pW->m_eColor == CNode::RB_RED)
3566 pW->m_eColor = CNode::RB_BLACK;
3567 pW->m_pParent->m_eColor = CNode::RB_RED;
3568 LeftRotate(pX->m_pParent);
3569 pW = pX->m_pParent->m_pRight;
3571 if (pW->m_pLeft->m_eColor == CNode::RB_BLACK && pW->m_pRight->m_eColor == CNode::RB_BLACK)
3573 pW->m_eColor = CNode::RB_RED;
3578 if (pW->m_pRight->m_eColor == CNode::RB_BLACK)
3580 pW->m_pLeft->m_eColor = CNode::RB_BLACK;
3581 pW->m_eColor = CNode::RB_RED;
3583 pW = pX->m_pParent->m_pRight;
3585 pW->m_eColor = pX->m_pParent->m_eColor;
3586 pX->m_pParent->m_eColor = CNode::RB_BLACK;
3587 pW->m_pRight->m_eColor = CNode::RB_BLACK;
3588 LeftRotate(pX->m_pParent);
3594 pW = pX->m_pParent->m_pLeft;
3595 if (pW->m_eColor == CNode::RB_RED)
3597 pW->m_eColor = CNode::RB_BLACK;
3598 pW->m_pParent->m_eColor = CNode::RB_RED;
3599 RightRotate(pX->m_pParent);
3600 pW = pX->m_pParent->m_pLeft;
3602 if (pW->m_pRight->m_eColor == CNode::RB_BLACK && pW->m_pLeft->m_eColor == CNode::RB_BLACK)
3604 pW->m_eColor = CNode::RB_RED;
3609 if (pW->m_pLeft->m_eColor == CNode::RB_BLACK)
3611 pW->m_pRight->m_eColor = CNode::RB_BLACK;
3612 pW->m_eColor = CNode::RB_RED;
3614 pW = pX->m_pParent->m_pLeft;
3616 pW->m_eColor = pX->m_pParent->m_eColor;
3617 pX->m_pParent->m_eColor = CNode::RB_BLACK;
3618 pW->m_pLeft->m_eColor = CNode::RB_BLACK;
3619 RightRotate(pX->m_pParent);
3625 pX->m_eColor = CNode::RB_BLACK;
3629template<
typename K,
typename V,
class KTraits,
class VTraits >
3630bool SRBTree< K, V, KTraits, VTraits >::RBDelete(CNode* pZ)
3637 if (IsNil(pZ->m_pLeft) || IsNil(pZ->m_pRight))
3642 if (!IsNil(pY->m_pLeft))
3647 pX->m_pParent = pY->m_pParent;
3649 if (IsNil(pY->m_pParent))
3651 else if (pY == pY->m_pParent->m_pLeft)
3652 pY->m_pParent->m_pLeft = pX;
3654 pY->m_pParent->m_pRight = pX;
3656 if (pY->m_eColor == CNode::RB_BLACK)
3662 if (m_pRoot != NULL)
3663 SetNil(&m_pRoot->m_pParent);
3670template<
typename K,
typename V,
class KTraits,
class VTraits >
3671typename SRBTree< K, V, KTraits, VTraits >::CNode* SRBTree< K, V, KTraits, VTraits >::Minimum(CNode* pNode)
const
3673 if (pNode == NULL || IsNil(pNode))
3678 CNode* pMin = pNode;
3679 while (!IsNil(pMin->m_pLeft))
3681 pMin = pMin->m_pLeft;
3687template<
typename K,
typename V,
class KTraits,
class VTraits >
3688typename SRBTree< K, V, KTraits, VTraits >::CNode* SRBTree< K, V, KTraits, VTraits >::Maximum(CNode* pNode)
const
3690 if (pNode == NULL || IsNil(pNode))
3695 CNode* pMax = pNode;
3696 while (!IsNil(pMax->m_pRight))
3698 pMax = pMax->m_pRight;
3704template<
typename K,
typename V,
class KTraits,
class VTraits >
3705typename SRBTree< K, V, KTraits, VTraits >::CNode* SRBTree< K, V, KTraits, VTraits >::Predecessor( CNode* pNode )
const
3711 if( !IsNil(pNode->m_pLeft) )
3713 return( Maximum( pNode->m_pLeft ) );
3716 CNode* pParent = pNode->m_pParent;
3717 CNode* pLeft = pNode;
3718 while( !IsNil(pParent) && (pLeft == pParent->m_pLeft) )
3721 pParent = pParent->m_pParent;
3731template<
typename K,
typename V,
class KTraits,
class VTraits >
3732typename SRBTree< K, V, KTraits, VTraits >::CNode* SRBTree< K, V, KTraits, VTraits >::Successor(CNode* pNode)
const
3734 if ( pNode == NULL )
3738 if ( !IsNil(pNode->m_pRight) )
3740 return Minimum(pNode->m_pRight);
3743 CNode* pParent = pNode->m_pParent;
3744 CNode* pRight = pNode;
3745 while ( !IsNil(pParent) && (pRight == pParent->m_pRight) )
3748 pParent = pParent->m_pParent;
3758template<
typename K,
typename V,
class KTraits,
class VTraits >
3759typename SRBTree< K, V, KTraits, VTraits >::CNode* SRBTree< K, V, KTraits, VTraits >::RBInsert( KINARGTYPE key, VINARGTYPE value )
3761 CNode* pNewNode = InsertImpl( key, value );
3763 CNode* pX = pNewNode;
3764 pX->m_eColor = CNode::RB_RED;
3766 while (pX != m_pRoot && pX->m_pParent->m_eColor == CNode::RB_RED)
3768 if (pX->m_pParent == pX->m_pParent->m_pParent->m_pLeft)
3770 pY = pX->m_pParent->m_pParent->m_pRight;
3771 if (pY != NULL && pY->m_eColor == CNode::RB_RED)
3773 pX->m_pParent->m_eColor = CNode::RB_BLACK;
3774 pY->m_eColor = CNode::RB_BLACK;
3775 pX->m_pParent->m_pParent->m_eColor = CNode::RB_RED;
3776 pX = pX->m_pParent->m_pParent;
3780 if (pX == pX->m_pParent->m_pRight)
3785 pX->m_pParent->m_eColor = CNode::RB_BLACK;
3786 pX->m_pParent->m_pParent->m_eColor = CNode::RB_RED;
3787 RightRotate(pX->m_pParent->m_pParent);
3792 pY = pX->m_pParent->m_pParent->m_pLeft;
3793 if (pY != NULL && pY->m_eColor == CNode::RB_RED)
3795 pX->m_pParent->m_eColor = CNode::RB_BLACK;
3796 pY->m_eColor = CNode::RB_BLACK;
3797 pX->m_pParent->m_pParent->m_eColor = CNode::RB_RED;
3798 pX = pX->m_pParent->m_pParent;
3802 if (pX == pX->m_pParent->m_pLeft)
3807 pX->m_pParent->m_eColor = CNode::RB_BLACK;
3808 pX->m_pParent->m_pParent->m_eColor = CNode::RB_RED;
3809 LeftRotate(pX->m_pParent->m_pParent);
3814 m_pRoot->m_eColor = CNode::RB_BLACK;
3815 SetNil(&m_pRoot->m_pParent);
3822template<
typename K,
typename V,
class KTraits,
class VTraits >
3823void SRBTree< K, V, KTraits, VTraits >::VerifyIntegrity(
const CNode *pNode,
int nCurrBlackDepth,
int &nBlackDepth)
const
3825 bool bCheckForBlack =
false;
3828 if (pNode->m_eColor == CNode::RB_RED)
3829 bCheckForBlack =
true;
3833 SASSERT(pNode->m_pLeft != NULL);
3834 if (!IsNil(pNode->m_pLeft))
3839 SASSERT(pNode->m_pLeft->m_eColor == CNode::RB_BLACK);
3842 VerifyIntegrity(pNode->m_pLeft, nCurrBlackDepth, nBlackDepth);
3845 SASSERT(pNode->m_pRight != NULL);
3846 if (!IsNil(pNode->m_pRight))
3851 SASSERT(pNode->m_pRight->m_eColor == CNode::RB_BLACK);
3854 VerifyIntegrity(pNode->m_pRight, nCurrBlackDepth, nBlackDepth);
3857 SASSERT( pNode->m_pParent != NULL );
3858 SASSERT( ( IsNil(pNode->m_pParent) ) ||
3859 ( pNode->m_pParent->m_pLeft == pNode ) ||
3860 ( pNode->m_pParent->m_pRight == pNode ) );
3864 if (nBlackDepth == 0)
3866 nBlackDepth = nCurrBlackDepth;
3870 SASSERT(nBlackDepth == nCurrBlackDepth);
3875template<
typename K,
typename V,
class KTraits,
class VTraits >
3876void SRBTree< K, V, KTraits, VTraits >::VerifyIntegrity()
const
3878 if ((m_pRoot == NULL) || (IsNil(m_pRoot)))
3881 SASSUME(m_pRoot->m_eColor == CNode::RB_BLACK);
3882 int nBlackDepth = 0;
3883 VerifyIntegrity(m_pRoot, 0, nBlackDepth);
3888template<
typename K,
typename V,
class KTraits = CElementTraits< K >,
class VTraits = CElementTraits< V > >
3890 public SRBTree< K, V, KTraits, VTraits >
3893 explicit SRBMap(
size_t nBlockSize = 10 ) ;
3896 bool Lookup(
typename SRBTree< K, V, KTraits, VTraits >::KINARGTYPE key,
typename SRBTree< K, V, KTraits, VTraits >::VOUTARGTYPE value )
const ;
3897 const typename SRBMap< K, V, KTraits, VTraits >::CPair* Lookup(
typename SRBTree< K, V, KTraits, VTraits >::KINARGTYPE key )
const ;
3898 typename SRBMap< K, V, KTraits, VTraits >::CPair* Lookup(
typename SRBTree< K, V, KTraits, VTraits >::KINARGTYPE key ) ;
3900 SPOSITION SetAt(
typename SRBTree< K, V, KTraits, VTraits >::KINARGTYPE key,
typename SRBTree< K, V, KTraits, VTraits >::VINARGTYPE value)
3902 typename SRBTree< K, V, KTraits, VTraits >::CPair* pNode = SRBTree< K, V, KTraits, VTraits >::Find(key);
3905 return (SPOSITION)SRBTree< K, V, KTraits, VTraits >::RBInsert(key, value);
3909 pNode->m_value = value;
3911 return (SPOSITION)pNode;
3915 bool RemoveKey(
typename SRBTree< K, V, KTraits, VTraits >::KINARGTYPE key ) ;
3920template<
typename K,
typename V,
class KTraits,
class VTraits >
3921SRBMap< K, V, KTraits, VTraits >::SRBMap(
size_t nBlockSize ) :
3922SRBTree< K, V, KTraits, VTraits >( nBlockSize )
3926template<
typename K,
typename V,
class KTraits,
class VTraits >
3927SRBMap< K, V, KTraits, VTraits >::~SRBMap()
3931template<
typename K,
typename V,
class KTraits,
class VTraits >
3932const typename SRBMap< K, V, KTraits, VTraits >::CPair* SRBMap< K, V, KTraits, VTraits >::Lookup(
typename SRBTree< K, V, KTraits, VTraits >::KINARGTYPE key )
const
3934 return SRBTree< K, V, KTraits, VTraits >::Find(key);
3937template<
typename K,
typename V,
class KTraits,
class VTraits >
3938typename SRBMap< K, V, KTraits, VTraits >::CPair* SRBMap< K, V, KTraits, VTraits >::Lookup(
typename SRBTree< K, V, KTraits, VTraits >::KINARGTYPE key )
3940 return SRBTree< K, V, KTraits, VTraits >::Find(key);
3943template<
typename K,
typename V,
class KTraits,
class VTraits >
3944bool SRBMap< K, V, KTraits, VTraits >::Lookup(
typename SRBTree< K, V, KTraits, VTraits >::KINARGTYPE key,
typename SRBTree< K, V, KTraits, VTraits >::VOUTARGTYPE value )
const
3946 const typename SRBTree< K, V, KTraits, VTraits >::CNode* pLookup = SRBTree< K, V, KTraits, VTraits >::Find( key );
3947 if( pLookup == NULL )
3950 value = pLookup->m_value;
3954template<
typename K,
typename V,
class KTraits,
class VTraits >
3955bool SRBMap< K, V, KTraits, VTraits >::RemoveKey(
typename SRBTree< K, V, KTraits, VTraits >::KINARGTYPE key )
3957 SPOSITION pos = (SPOSITION)Lookup( key );
3960 SRBTree< K, V, KTraits, VTraits >::RemoveAt( pos );