#include "stdafx.h" #include "CustomMap.h" CustomMap::CustomMap() { m_NodePool = NULL; m_NodePoolSize = 0; m_NodePoolIndex = 0; m_HashSize = 1024; m_HashTable = (SCustomMapNode**) malloc(m_HashSize * sizeof(SCustomMapNode)); clear(); } CustomMap::~CustomMap() { for( int i = 0;i < m_NodePoolSize; i += 1 ) { free(m_NodePool[i]); } free(m_NodePool); free(m_HashTable); } void CustomMap::clear() { // reset the pool index m_NodePoolIndex = 0; // clear the hash table memset(m_HashTable, 0, m_HashSize * sizeof(SCustomMapNode)); } SCustomMapNode* CustomMap::find(const ChunkPos &Key) { unsigned int Hash = (Key.x & 0x00000001f) | (Key.z << 5); // hopefully this will produce a good hash for a 1024 entry table unsigned int Index = Hash & (m_HashSize-1); SCustomMapNode* Node = m_HashTable[Index]; while( Node && Node->Hash != Hash ) { Node = Node->Next; } return Node; } int CustomMap::end() { return m_NodePoolIndex; } SCustomMapNode* CustomMap::get(int index) { return m_NodePool[index]; } void CustomMap::insert(const ChunkPos &Key, bool Value) { // see if this key already exists SCustomMapNode* Node = find(Key); if( !Node ) { // do we have any space in the pool if( m_NodePoolIndex >= m_NodePoolSize ) { resize(); } // grab the next node from the pool Node = m_NodePool[m_NodePoolIndex]; m_NodePoolIndex++; } else { Node->second = Value; return; } // create the new node; unsigned int Hash = (Key.x & 0x00000001f) | (Key.z << 5); // hopefully this will produce a good hash for a 1024 entry table unsigned int Index = Hash & (m_HashSize-1); Node->Hash = Hash; Node->first = Key; Node->second = Value; Node->Next = NULL; // are any nodes in this hash index if( !m_HashTable[Index] ) { m_HashTable[Index] = Node; } else { // loop to the last node in the hash list SCustomMapNode* OldNode = m_HashTable[Index]; while( OldNode->Next ) { OldNode = OldNode->Next; } // link the old last node to the new one OldNode->Next = Node; } } void CustomMap::resize() { int OldPoolSize = m_NodePoolSize; m_NodePoolSize += 512; SCustomMapNode **NodePool; if( m_NodePool ) { NodePool = (SCustomMapNode**) realloc(m_NodePool, m_NodePoolSize * sizeof(SCustomMapNode)); } else { NodePool = (SCustomMapNode**) malloc(m_NodePoolSize * sizeof(SCustomMapNode)); } for( int i = 0;i < m_NodePoolSize - OldPoolSize;i += 1 ) { NodePool[i + OldPoolSize] = (SCustomMapNode*) malloc(sizeof(SCustomMapNode)); } m_NodePool = NodePool; }