/** * @file GSEPoolHash.cpp * @brief Hash Object Pool Interface Definition * Copyright(c) 2009, Xuchengyong Private * All rights reserved * 文件名称: GSEPoolHash.cpp * 摘 要: 哈希对象池接口定义 * 作 者: 徐成勇 * 版 本: Ver 0.1 * 完成时间: 2009.07.13 * 修改记录: */ #ifndef __GSEPoolHash__CPP__ #define __GSEPoolHash__CPP__ #include "GSEPoolHash.h" #include "GSEPool.cpp" template GSEPoolHash::GSEPoolHash(size_t nMaxSize, size_t nIncSize) throw(GSEException) : GSEPool(nMaxSize, nIncSize) { m_ppkHashComponents = (GSEHashComponent**)GSEMemExternalMalloc(sizeof(GSEHashComponent*) * this->m_nSlotCapacity); if(m_ppkHashComponents == NULL) { throw GSEEXCEPTION("GSEMemExternalMalloc %d GSElHashComponent* Pointer Failed", this->m_nSlotCapacity); } memset(m_ppkHashComponents, 0, sizeof(GSEHashComponent*) * this->m_nSlotCapacity); } template GSEPoolHash::~GSEPoolHash(void) throw(GSEException) { ClearAllComponents(); GSEMemExternalFree(m_ppkHashComponents); m_ppkHashComponents = NULL; } template void GSEPoolHash::First() { if(this->m_nCurEntityCount > 0) { for(size_t index = 0; index < this->m_nSlotCapacity; ++index) { m_pkHashIterator = m_ppkHashComponents[index]; if(m_pkHashIterator) { break; } } assert(m_pkHashIterator); return; } m_pkHashIterator = 0; } template void GSEPoolHash::Next() { if(m_pkHashIterator->pkNext) { m_pkHashIterator = m_pkHashIterator->pkNext; } else { size_t nSlotIndex = ((size_t)(m_pkHashIterator->kKey)) % this->m_nSlotCapacity; for(++nSlotIndex; nSlotIndex < this->m_nSlotCapacity; ++nSlotIndex) { if(m_ppkHashComponents[nSlotIndex]) { m_pkHashIterator = m_ppkHashComponents[nSlotIndex]; return; } } } m_pkHashIterator = NULL; } template bool GSEPoolHash::IsDone() const { return m_pkHashIterator == NULL; } template Value GSEPoolHash::GetCurrent(Key& kKey) throw(GSEException) { if(m_pkHashIterator == NULL) { throw GSEEXCEPTION("Out Of Range"); } kKey = m_pkHashIterator->kKey; return m_pkHashIterator->kValue; } template Value GSEPoolHash::EraseCurrent(Key& kKey) throw(GSEException) { if(m_pkHashIterator == NULL) { throw GSEEXCEPTION("Out Of Range"); } GSEHashComponent* pkHashComponent = m_pkHashIterator->pkNext; size_t nSlotIndex = ((size_t)m_pkHashIterator->kKey) % this->m_nSlotCapacity; if(m_pkHashIterator->pkPrev == NULL) { m_ppkHashComponents[nSlotIndex] = m_pkHashIterator->pkNext; if(m_pkHashIterator->pkNext) { m_pkHashIterator->pkNext->pkPrev = NULL; } } else { m_pkHashIterator->pkPrev->pkNext = m_pkHashIterator->pkNext; if(m_pkHashIterator->pkNext) { m_pkHashIterator->pkNext->pkPrev = m_pkHashIterator->pkPrev; } } kKey = m_pkHashIterator->kKey; Value kValue = m_pkHashIterator->kValue; GSEMemDelete m_pkHashIterator; m_pkHashIterator = NULL; if(pkHashComponent) { m_pkHashIterator = pkHashComponent; } else { for(++nSlotIndex; nSlotIndex < this->m_nSlotCapacity; ++nSlotIndex) { if(m_ppkHashComponents[nSlotIndex]) { m_pkHashIterator = m_ppkHashComponents[nSlotIndex]; break;; } } } --this->m_nCurEntityCount; return kValue; } template Value GSEPoolHash::Find(Key& kKey) { assert(kKey); size_t nSlotIndex = (size_t)kKey % this->m_nSlotCapacity; for(GSEHashComponent* pkHashComponent = m_ppkHashComponents[nSlotIndex]; pkHashComponent; pkHashComponent = pkHashComponent->pkNext) { if(pkHashComponent->kKey == kKey) { return pkHashComponent->kValue; } } return 0; } template void GSEPoolHash::Append(Key kKey, Value kValue) throw(GSEException) { assert(kKey); size_t nSlotIndex = (size_t)kKey % this->m_nSlotCapacity; for(GSEHashComponent* pkHashComponent = m_ppkHashComponents[nSlotIndex]; pkHashComponent; pkHashComponent = pkHashComponent->pkNext) { if(pkHashComponent->kKey == kKey) { pkHashComponent->kValue = kValue; return; } } GSEHashComponent* pkTempHashComponent = GSEMemNew GSEHashComponent(); pkTempHashComponent->kKey = kKey; pkTempHashComponent->kValue = kValue; pkTempHashComponent->pkPrev = NULL; pkTempHashComponent->pkNext = m_ppkHashComponents[nSlotIndex]; if(m_ppkHashComponents[nSlotIndex]) { m_ppkHashComponents[nSlotIndex]->pkPrev = pkTempHashComponent; } m_ppkHashComponents[nSlotIndex] = pkTempHashComponent; ++this->m_nCurEntityCount; } template Value GSEPoolHash::Erase(Key kKey) { assert(kKey); size_t nSlotIndex = (size_t)kKey % this->m_nSlotCapacity; for(GSEHashComponent* pkHashComponent = m_ppkHashComponents[nSlotIndex]; pkHashComponent; pkHashComponent = pkHashComponent->pkNext) { if(pkHashComponent->kKey == kKey) { if(pkHashComponent->pkPrev == NULL) { m_ppkHashComponents[nSlotIndex] = pkHashComponent->pkNext; if(pkHashComponent->pkNext) { pkHashComponent->pkNext->pkPrev = NULL; } } else { pkHashComponent->pkPrev->pkNext = pkHashComponent->pkNext; if(pkHashComponent->pkNext) { pkHashComponent->pkNext->pkPrev = pkHashComponent->pkPrev; } } --this->m_nCurEntityCount; kKey = pkHashComponent->kKey; Value kValue = pkHashComponent->kValue; GSEMemDelete pkHashComponent; return kValue; } } throw GSEEXCEPTION("Not Found"); } template void GSEPoolHash::EraseAll() { ClearAllComponents(); memset(m_ppkHashComponents, 0, sizeof(GSEHashComponent*) * this->m_nSlotCapacity); this->m_nCurEntityCount = 0; } template void GSEPoolHash::ClearAllComponents() throw(GSEException) { for(size_t index = 0; index < this->m_nSlotCapacity; ++index) { for(GSEHashComponent* pkHashComponent = m_ppkHashComponents[index]; pkHashComponent; ) { GSEHashComponent* pkTempHashComponent = pkHashComponent; pkHashComponent = pkTempHashComponent->pkNext; GSEMemDelete pkTempHashComponent; } } } #endif