OpenBarnyard
 
Loading...
Searching...
No Matches
THashTable.cpp
Go to the documentation of this file.
1#include "ToshiPCH.h"
2#include "THashTable.h"
3
4//-----------------------------------------------------------------------------
5// Enables memory debugging.
6// Note: Should be the last include!
7//-----------------------------------------------------------------------------
9
11
12THashTable::t_ItemCompareFunc THashTable::DefaultItemCompareFunc = []( const void* a_pMem1, const void* a_pMem2, TSIZE a_iSize ) {
13 return TUtil::MemCompare( a_pMem1, a_pMem2, a_iSize ) == 0;
14};
15
16THashTable::t_ItemHashFunc THashTable::DefaultItemHashFunc = []( const void* a_pMem, TSIZE a_iSize, TUINT32 a_uiMaxValue ) {
17 const TBYTE* pBuffer = TREINTERPRETCAST( const TBYTE*, a_pMem );
18 TUINT32 uiHash = 0;
19
20 while ( a_iSize != 0 )
21 {
22 uiHash = ( uiHash * 0x10 ) + *pBuffer++;
23 if ( ( uiHash & 0xF0000000 ) != 0 )
24 {
25 uiHash = uiHash ^ ( uiHash & 0xF0000000 ) >> 24 ^ ( uiHash & 0xF0000000 );
26 }
27 a_iSize--;
28 }
29
30 return uiHash - ( uiHash / a_uiMaxValue ) * a_uiMaxValue;
31};
32
34{
35 m_iBucketSize = 0;
36 m_iItemSize = 0;
37 m_iItemCount = 0;
38 m_iItemCountTotal = 0;
39 m_iHashNodeCount = 0;
40 m_iHashNodeCountTotal = 0;
41 m_pHashToBucketId = TNULL;
42 m_pBuckets = TNULL;
43 m_pItems = TNULL;
44 m_ItemHashFunc = TNULL;
45 m_ItemCompareFunc = TNULL;
46}
47
52
54{
55 delete[] m_pHashToBucketId;
56 m_pHashToBucketId = TNULL;
57}
58
60{
62
63 delete[] m_pBuckets;
64 m_pBuckets = TNULL;
65
66 TFree( m_pItems );
67 m_pItems = TNULL;
68}
69
71{
72 TASSERT( 0 != m_iItemSize );
73
74 if ( TNULL == GetHashToBucketIds() )
75 return TNULL;
76
77 THashTable::Bucket* pFoundBucket = Find( a_pData );
78 return ( pFoundBucket ) ? pFoundBucket : Append( a_pData );
79}
80
82{
83 TASSERT( 0 != m_iItemSize );
84 TINT* pBuckets = GetHashToBucketIds();
85
86 if ( pBuckets != TNULL )
87 {
88 TUINT32 uiHash = m_ItemHashFunc( a_pData, m_iItemSize, m_iBucketSize );
89 TINT iBucket = pBuckets[ uiHash ];
90
91 while ( iBucket != INVALID_BUCKET_ID )
92 {
93 Bucket& item = m_pBuckets[ iBucket ];
94
95 if ( m_ItemCompareFunc( a_pData, m_pItems + m_iItemSize * item.iItemIndex, m_iItemSize ) )
96 return &item;
97
98 iBucket = item.iNextBucketId;
99 }
100 }
101
102 return TNULL;
103}
104
106{
107 TASSERT( 0 != m_iItemSize );
108
109 if ( m_pHashToBucketId != TNULL )
110 {
111 TASSERT( !( ( m_iHashNodeCount == m_iHashNodeCountTotal ) || ( m_iItemCount == m_iItemCountTotal ) ) );
112
113 if ( !( ( m_iHashNodeCount == m_iHashNodeCountTotal ) || ( m_iItemCount == m_iItemCountTotal ) ) )
114 {
115 TUINT32 uiHash = m_ItemHashFunc( a_pData, m_iItemSize, m_iBucketSize );
116
117 m_pBuckets[ m_iHashNodeCountTotal ].iNextBucketId = m_pHashToBucketId[ uiHash ];
118 m_pBuckets[ m_iHashNodeCountTotal ].iItemIndex = m_iItemCount;
119
120 TUtil::MemCopy( m_pItems + m_iItemCount * m_iItemSize, a_pData, m_iItemSize );
121
122 m_pHashToBucketId[ uiHash ] = m_iHashNodeCountTotal;
123
124 m_iItemCount++;
125 m_iHashNodeCountTotal++;
126
127 return &m_pBuckets[ m_iHashNodeCountTotal ];
128 }
129 }
130
131 return TNULL;
132}
133
134TBOOL THashTable::Create( TINT a_iItemCountTotal, TINT a_iItemSize, TINT a_iBucketSize, TINT a_iHashNodeCount )
135{
136 if ( m_pHashToBucketId == TNULL )
137 {
138 if ( a_iHashNodeCount < a_iItemCountTotal )
139 {
140 a_iHashNodeCount = a_iItemCountTotal;
141 }
142
143 m_iBucketSize = a_iBucketSize;
144 m_iItemSize = a_iItemSize;
145 m_iItemCount = 0;
146 m_iItemCountTotal = a_iItemCountTotal;
147 m_iHashNodeCount = a_iHashNodeCount;
148 m_pHashToBucketId = new TINT[ m_iBucketSize ];
149 m_pBuckets = new Bucket[ m_iHashNodeCount ];
150 m_pItems = TSTATICCAST( TBYTE, TMemalign( m_iItemSize * m_iItemCountTotal, 16 ) );
151
152 SetItemHashFunction( DefaultItemHashFunc );
153 SetItemCompareFunction( DefaultItemCompareFunc );
154
155 for ( TINT i = 0; i < m_iBucketSize; i++ )
156 {
157 m_pHashToBucketId[ i ] = INVALID_BUCKET_ID;
158 }
159
160 return TTRUE;
161 }
162
163 return TFALSE;
164}
165
void * TMemalign(TSIZE a_uiAlignment, TSIZE a_uiSize, Toshi::TMemory::MemBlock *a_pMemBlock)
Allocates aligned memory from a specific memory block.
Definition TMemory.cpp:1020
void TFree(void *a_pMem)
Frees previously allocated memory.
Definition TMemory.cpp:1054
#define TASSERT(X,...)
Definition Defines.h:138
#define TSTATICCAST(POINTERTYPE, VALUE)
Definition Defines.h:69
#define TREINTERPRETCAST(TYPE, VALUE)
Definition Defines.h:68
#define TOSHI_NAMESPACE_START
Definition Defines.h:47
#define TOSHI_NAMESPACE_END
Definition Defines.h:50
size_t TSIZE
Definition Typedefs.h:9
#define TNULL
Definition Typedefs.h:23
uint32_t TUINT32
Definition Typedefs.h:13
int TINT
Definition Typedefs.h:7
#define TFALSE
Definition Typedefs.h:24
#define TTRUE
Definition Typedefs.h:25
bool TBOOL
Definition Typedefs.h:6
uint8_t TBYTE
Definition Typedefs.h:19
void SetItemHashFunction(t_ItemHashFunc a_HashCompareFunc)
Definition THashTable.h:36
void Destroy()
Bucket * Find(void *a_pData)
TUINT32(*)(const void *a_pMem, TSIZE a_iSize, TUINT32 a_uiMaxValue) t_ItemHashFunc
Definition THashTable.h:17
void DeleteBucketMemory()
Bucket * Insert(void *a_pData)
TBOOL(*)(const void *a_pMem1, const void *a_pMem2, TSIZE a_iSize) t_ItemCompareFunc
Definition THashTable.h:16
Bucket * Append(void *a_pData)
void SetItemCompareFunction(t_ItemCompareFunc a_HashCompareFunc)
Definition THashTable.h:35
TINT * GetHashToBucketIds() const
Definition THashTable.h:23
static constexpr TINT INVALID_BUCKET_ID
Definition THashTable.h:14
TBOOL Create(TINT a_iItemCountTotal, TINT a_iItemSize, TINT a_iBucketSize, TINT a_iHashNodeCount)
static void * MemCopy(void *dst, const void *src, TSIZE size)
Definition TUtil.h:90
static TINT MemCompare(const void *ptr1, const void *ptr2, TSIZE size)
Definition TUtil.h:92