// Include #include "gamesrv.h" #include "ItemCountPool.h" // Local definitions // Global data cItemCountPool* cItemCountPool::mpItemCountPool = NULL; // ItemCountCmpIndex Prototype int WINAPI ItemCountCmpIndex(void* arg1, void* arg2) { return ((PerItemCount*)arg1)->index - ((PerItemCount*)arg2)->index; } // ItemCountCmpValue Prototype int WINAPI ItemCountCmpValue(void* arg1, void* arg2) { return ((PerItemCount*)arg1)->index - (*(long*)arg2); } // cItemCountPool Constructor cItemCountPool::cItemCountPool( ) { // Global Variable mpItemCountPool = this; // Pool Usage Pointer mNonPagedPoolUsage = NULL; } // ~cItemCountPool Destructor. cItemCountPool::~cItemCountPool(void) { // cItemCountPool¸¦ ÇØÁ¦. Shutdown(); // Global Variable mpItemCountPool = NULL; } // Shutdown Method void cItemCountPool::Shutdown() { PerItemCount* temp; // Pool Usage Shutdown - NonPagedPoolUsage while ( mNonPagedPoolUsage != NULL ) { temp = mNonPagedPoolUsage; mNonPagedPoolUsage = (PerItemCount*)mNonPagedPoolUsage->next; MEMORY_POOL->FreeNode( (void**)&temp ); } } // SearchItemCount Method PerItemCount* cItemCountPool::SearchItemCount(ItemCountRoot* root, long index) { return (PerItemCount*)MEMORY_POOL->SearchNode( root, &index, &ItemCountCmpValue ); } // UpdateItemCount Method PerItemCount* cItemCountPool::UpdateItemCount(ItemCountRoot* root, long index, short number, short count) { PerItemCount* perItemCount = (PerItemCount*)MEMORY_POOL->SearchNode( root, &index, &ItemCountCmpValue ); if ( perItemCount != NULL ) { if ( number >= INVENTORY_EQUIP_BEGIN && number <= INVENTORY_EQUIP_END ) { perItemCount->equip += count; } else if ( number >= INVENTORY_BAG_BEGIN && number <= INVENTORY_BAG_END_QUEST ) { perItemCount->bag += count; } else { perItemCount->etc += count; } perItemCount->sum += count; if ( perItemCount->sum > 0 ) { return perItemCount; } else { if ( perItemCount->sum < 0 ) { NETWORK2->PostServerEvent( "ERROR cItemCountPool::UpdateItemCount:Index(=%d), Bag(=%d), Sum(=%d)" ,perItemCount->index ,perItemCount->bag ,perItemCount->sum ); } ReleaseItemCount( root, perItemCount ); return NULL; } } else { perItemCount = GetItemCount( root, index, number, count ); return perItemCount; } } // GetItemCount Method - ¼±Çü¸®½ºÆ®ÀÇ HEAD¸¦ ³Ñ°ÜÁØ´Ù. // ReleaseItemCount¿Í ÇÔ²² LIFO¸¦ ÀÌ·é´Ù. LIFO´Â Context Switching¸¦ ÃÖ¼ÒÈ­ Çϱâ À§ÇØ »ç¿ë PerItemCount* cItemCountPool::GetItemCount(ItemCountRoot* root, long index, short number, short count) { PerItemCount* perItemCount = (PerItemCount*)MEMORY_POOL->GetPool( (PerNode**)&mNonPagedPoolUsage, sizeof(PerItemCount) ); if ( perItemCount ) { perItemCount->index = index; // ItemCount Key(Index) if ( number >= INVENTORY_EQUIP_BEGIN && number <= INVENTORY_EQUIP_END ) { perItemCount->equip += count; } else if ( number >= INVENTORY_BAG_BEGIN && number <= INVENTORY_BAG_END_QUEST ) { perItemCount->bag += count; } else { perItemCount->etc += count; } perItemCount->sum = count; // BST-¿¬°á½Ãµµ. if ( MEMORY_POOL->AttachBst( &root->root, perItemCount, ItemCountCmpIndex ) ) { MEMORY_POOL->AttachPool( (PerNode**)&root->pool, perItemCount ); return perItemCount; // ¿¬°á¼º°ø. } else { MEMORY_POOL->AttachPool( (PerNode**)&mNonPagedPoolUsage, perItemCount ); return NULL; // ¿¬°á½ÇÆÐ. } } return perItemCount; } // ReleaseItemCount Method - ¼±Çü¸®½ºÆ®ÀÇ HEAD·Î ȸ¼öÇÑ´Ù. // GetItemCount¿Í ÇÔ²² LIFO¸¦ ÀÌ·é´Ù. LIFO´Â Context Switching¸¦ ÃÖ¼ÒÈ­ Çϱâ À§ÇØ »ç¿ë void cItemCountPool::ReleaseItemCount(ItemCountRoot* root, PerItemCount* perItemCount) { perItemCount->index = 0; perItemCount->equip = 0; perItemCount->bag = 0; perItemCount->etc = 0; perItemCount->sum = 0; // BST - ¿¬°áÁ¾·á. MEMORY_POOL->DetachBst( (PerNode**)&root->root, (PerNode*)perItemCount ); // ÆäÀÌÁö µÈ Ç® »ç¿ë·®À» Â÷°¨. MEMORY_POOL->DetachPool( (PerNode**)&root->pool, (PerNode*)perItemCount ); // ÆäÀÌÁö ¾ÈµÈ Ç® »ç¿ë·®À» Áõ°¨. MEMORY_POOL->ReleasePool( (PerNode**)&mNonPagedPoolUsage, (PerNode*)perItemCount ); }