mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-31 06:07:37 +01:00
107 lines
3.8 KiB
C++
107 lines
3.8 KiB
C++
/*****************************************************************************/
|
|
/* IndexMap.h Copyright (c) Ladislav Zezula 2019 */
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Interface of index-based map for CascLib. This is a map type created */
|
|
/* on top of an array of contant-size objects, that is already sorted. */
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Date Ver Who Comment */
|
|
/* -------- ---- --- ------- */
|
|
/* 29.04.19 1.00 Lad The first version of Index.h */
|
|
/*****************************************************************************/
|
|
|
|
#ifndef __CASC_INDEX_MAP_H__
|
|
#define __CASC_INDEX_MAP_H__
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Structures
|
|
|
|
class CASC_INDEX_MAP
|
|
{
|
|
public:
|
|
|
|
int Create(size_t MaxItems, size_t ObjectLength_, size_t KeyLength_, size_t KeyOffset_)
|
|
{
|
|
DWORD IndexBitSize = 8;
|
|
|
|
// Determine the index size
|
|
if(MaxItems >= 0x10000)
|
|
IndexBitSize = 16;
|
|
if(MaxItems >= 0x100000)
|
|
IndexBitSize = 20;
|
|
|
|
// Save the values
|
|
IndexTableSize = (1 << IndexBitSize);
|
|
IndexTableMask = IndexTableSize - 1;
|
|
ObjectLength = ObjectLength_;
|
|
KeyOffset = KeyOffset_;
|
|
KeyLength = KeyLength_;
|
|
|
|
// Allocate the new index object
|
|
IndexTable = CASC_ALLOC(void *, IndexTableSize);
|
|
if(IndexTable != NULL)
|
|
{
|
|
memset(IndexTable, 0, IndexTableSize * sizeof(void *));
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
void * FindObject(void * pvKey)
|
|
{
|
|
LPBYTE StartObject;
|
|
DWORD StartIndex;
|
|
|
|
// Verify pointer to the map
|
|
if(IndexTable != NULL)
|
|
{
|
|
// Retrieve the index from the key
|
|
StartIndex = KeyToIndex(pvKey);
|
|
StartObject = (LPBYTE)IndexTable[StartIndex];
|
|
if(StartObject == NULL)
|
|
return NULL;
|
|
|
|
// Enumerate the array as long as the index matches
|
|
do
|
|
{
|
|
// Compare the key
|
|
if(!memcmp(StartObject + KeyOffset, pvKey, KeyLength))
|
|
return StartObject;
|
|
|
|
// Key mismatch -> go next object
|
|
StartObject = StartObject + ObjectLength;
|
|
}
|
|
while(KeyToIndex(StartObject + KeyOffset) == StartIndex);
|
|
}
|
|
|
|
// Not found
|
|
return NULL;
|
|
}
|
|
|
|
protected:
|
|
|
|
inline DWORD KeyToIndex(void * pvKey)
|
|
{
|
|
return *((PDWORD)pvKey) & IndexTableMask;
|
|
}
|
|
|
|
void ** IndexTable; // Pointer table. Each entry, if non-NULL, contains a pointer to the first object
|
|
// into a sorted array. Search function must then match the entire key.
|
|
// In case of no match, the search process must go to the next-in-array object.
|
|
size_t ObjectLength; // Length of the single object
|
|
size_t KeyOffset; // How far is the key from the begin of the structure (in bytes)
|
|
size_t KeyLength; // Length of the key
|
|
DWORD IndexTableSize; // Size of the IndexTableSize, in bytes
|
|
DWORD IndexTableMask; // Bit mask for conversion from hash to index
|
|
};
|
|
|
|
typedef CASC_INDEX_MAP *PCASC_INDEX_MAP;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Functions
|
|
|
|
bool IndexMap_InsertObject(PCASC_INDEX_MAP pIndexMap, void * pvNewObject, void * pvKey);
|
|
void IndexMap_Free(PCASC_INDEX_MAP pIndexMap);
|
|
|
|
#endif // __CASC_INDEX_MAP_H__
|