hxglobalmgr_imp.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:10k
- /* ***** BEGIN LICENSE BLOCK *****
- * Version: RCSL 1.0/RPSL 1.0
- *
- * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file, are
- * subject to the current version of the RealNetworks Public Source License
- * Version 1.0 (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the RealNetworks Community Source License Version 1.0
- * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
- * in which case the RCSL will apply. You may also obtain the license terms
- * directly from RealNetworks. You may not use this file except in
- * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
- * applicable to this file, the RCSL. Please see the applicable RPSL or
- * RCSL for the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the portions
- * it created.
- *
- * This file, and the files included with this file, is distributed and made
- * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- #include "hxglobalmgr_imp.h"
- #include "hxassert.h"
- #include "hxthread.h"
- class HXGlobalMap
- {
- public:
- HXGlobalMap();
- ~HXGlobalMap();
-
- void Add(const int* pContext, GlobalID id, GlobalType pObj,
- HXGlobalDestroyFunc fpDestroy);
- void Remove(GlobalID id);
- void RemoveAll(const int* pContext);
- GlobalPtr Get(GlobalID id) const;
- BOOL IsMember(GlobalID id) const;
- private:
- class MapNode
- {
- public:
- MapNode();
- MapNode(const int* pContext, GlobalID id, GlobalType pObj,
- HXGlobalDestroyFunc fpDestroy);
- ~MapNode();
-
- MapNode* GetNext() const { return m_pNext; }
- void SetNext(MapNode* pNext) { m_pNext = pNext; }
- const int* Context() const { return m_pContext;}
- GlobalID ID() const { return m_id; }
- GlobalPtr ObjPtr() { return &m_pObj; }
- private:
- MapNode* m_pNext;
- const int* m_pContext;
- GlobalID m_id;
- GlobalType m_pObj;
- HXGlobalDestroyFunc m_fpDestroy;
- };
- unsigned int GetBucket(GlobalID id) const;
- void ResizeIfNeeded();
- MapNode* FindNode(GlobalID id, MapNode** ppLastNode) const;
- void AddNode(MapNode* pNewNode);
- int m_bucketIndex;
- int m_bucketCount;
- MapNode* m_pBuckets;
- int m_elementCount;
- static const int zm_bucketCounts[];
- };
- // List of primes that are approximately double the
- // previous prime
- const int HXGlobalMap::zm_bucketCounts[] =
- {
- 3, 5, 11, 23, 53, 97, 193, 389,
- 769, 1543, 3079, 6151, 12289,
- 24593, 49157, 98317, 196613,
- 393241, 786433, 1572869,
- 3145739, 6291469, 12582917
- };
- HXGlobalMap::HXGlobalMap()
- : m_bucketIndex(0)
- , m_bucketCount(0)
- , m_pBuckets(0)
- , m_elementCount(0)
- {
- m_bucketCount = zm_bucketCounts[m_bucketIndex];
- m_pBuckets = new MapNode[m_bucketCount];
- HX_ASSERT(m_pBuckets != NULL );
- }
- HXGlobalMap::~HXGlobalMap()
- {
- for (int i = 0; i < m_bucketCount; i++)
- {
- MapNode* pCur = m_pBuckets[i].GetNext();
- while (pCur)
- {
- MapNode* pNext = pCur->GetNext();
- delete pCur;
- pCur = pNext;
- }
- }
- delete [] m_pBuckets;
- m_pBuckets = 0;
- m_bucketIndex = 0;
- m_elementCount = 0;
- }
- void
- HXGlobalMap::Add(const int* pContext, GlobalID id, GlobalType pObj,
- HXGlobalDestroyFunc fpDestroy)
- {
- AddNode(new MapNode(pContext, id, pObj, fpDestroy));
- m_elementCount++;
- ResizeIfNeeded();
- }
- void
- HXGlobalMap::Remove(GlobalID id)
- {
- MapNode* pLastNode = 0;
- MapNode* pCurNode = FindNode(id, &pLastNode);
- if (pCurNode)
- {
- pLastNode->SetNext(pCurNode->GetNext());
- delete pCurNode;
- m_elementCount--;
- ResizeIfNeeded();
- }
- }
- GlobalPtr
- HXGlobalMap::Get(GlobalID id) const
- {
- MapNode* pNode = FindNode(id, 0);
- if (pNode)
- {
- return pNode->ObjPtr();
- }
- return NULL;
- }
- BOOL
- HXGlobalMap::IsMember(GlobalID id) const
- {
- return (FindNode(id, 0) != 0);
- }
- void
- HXGlobalMap::RemoveAll(const int* pContext)
- {
- for (int i = 0; i < m_bucketCount; i++)
- {
- MapNode* pLast = &m_pBuckets[i];
- MapNode* pCur = pLast->GetNext();
-
- while (pCur)
- {
- if (pCur->Context() == pContext)
- {
- MapNode* pNext = pCur->GetNext();
- delete pCur;
- m_elementCount--;
- pLast->SetNext(pNext);
- pCur = pNext;
- }
- else
- {
- pLast = pCur;
- pCur = pCur->GetNext();
- }
- }
- }
- ResizeIfNeeded();
- }
- unsigned int HXGlobalMap::GetBucket(GlobalID id) const
- {
- unsigned int unRetVal = ((unsigned int)id) % m_bucketCount;
- HX_ASSERT( unRetVal < m_bucketCount && unRetVal>=0 );
- return unRetVal;
- }
- void
- HXGlobalMap::ResizeIfNeeded()
- {
- MapNode* pOldBuckets = 0;
- int oldBucketCount = m_bucketCount;
- if ((m_elementCount > (m_bucketCount << 1)) &&
- (m_bucketIndex < ((int)(sizeof(zm_bucketCounts) / sizeof(int)))))
- {
- // Grow the map if the number of elements is
- // larger than 2 times the bucket count
-
- m_bucketIndex++;
- m_bucketCount = zm_bucketCounts[m_bucketIndex];
-
- pOldBuckets = m_pBuckets; // Save old map
- m_pBuckets = new MapNode[m_bucketCount];
- }
- else if ((m_elementCount < (m_bucketCount >> 2)) &&
- (m_bucketIndex > 0))
- {
-
- // Shrink the map if the number of elements is
- // smaller than 1/4th the bucket count
-
- pOldBuckets = m_pBuckets; // Save old map
-
- m_bucketIndex--;
-
- m_bucketCount = zm_bucketCounts[m_bucketIndex];
- m_pBuckets = new MapNode[m_bucketCount];
- }
-
- if (pOldBuckets)
- {
- // Transfer the nodes from the old buckets to
- // the new buckets
-
- for (int i = 0; i < oldBucketCount; i++)
- {
- MapNode* pCurNode = pOldBuckets[i].GetNext();
-
- while(pCurNode)
- {
- // Get the pointer to the next node before
- // we add the node since the AddNode() will
- // clobber it's next pointer
- MapNode* pNextNode = pCurNode->GetNext();
-
- AddNode(pCurNode);
-
- // Move onto the next node
- pCurNode = pNextNode;
- }
- }
-
- delete [] pOldBuckets;
- }
- }
- HXGlobalMap::MapNode*
- HXGlobalMap::FindNode(GlobalID id, MapNode** ppLastNode) const
- {
- MapNode* pRet = 0;
- int bucket = GetBucket(id);
- MapNode* pLastNode = &(m_pBuckets[bucket]);
- MapNode* pCurNode = pLastNode->GetNext();
- while(!pRet && pCurNode)
- {
- if (pCurNode->ID() == id)
- pRet = pCurNode;
- else
- {
- pLastNode = pCurNode;
- pCurNode = pCurNode->GetNext();
- }
- }
- if (ppLastNode)
- *ppLastNode = pLastNode;
- return pRet;
- }
- void
- HXGlobalMap::AddNode(MapNode* pNewNode)
- {
- int bucket = GetBucket(pNewNode->ID());
- pNewNode->SetNext(m_pBuckets[bucket].GetNext());
- m_pBuckets[bucket].SetNext(pNewNode);
- }
- HXGlobalMap::MapNode::MapNode()
- : m_pNext(NULL)
- , m_pContext(NULL)
- , m_id(NULL)
- , m_pObj(NULL)
- , m_fpDestroy(NULL)
- {
- }
- HXGlobalMap::MapNode::MapNode(const int* pContext,
- GlobalID id,
- GlobalType pObj,
- HXGlobalDestroyFunc fpDestroy)
- : m_pNext(NULL)
- , m_pContext(pContext)
- , m_id(id)
- , m_pObj(pObj)
- , m_fpDestroy(fpDestroy)
- {
- }
- HXGlobalMap::MapNode::~MapNode()
- {
- if (m_pObj && m_fpDestroy)
- {
- m_fpDestroy(m_pObj);
- }
- }
- HXGlobalManagerImp::HXGlobalManagerImp()
- : m_pMap(NULL)
- , m_pMutex(NULL)
- {
- m_pMap = new HXGlobalMap();
- HX_ASSERT(m_pMap);
-
- #if defined(THREADS_SUPPORTED) || defined(_UNIX_THREADS_SUPPORTED)
- HXMutex::MakeMutex(m_pMutex);
- #else
- HXMutex::MakeStubMutex(m_pMutex);
- #endif
- }
- HXGlobalManagerImp::~HXGlobalManagerImp()
- {
- HX_DELETE(m_pMutex);
- HX_DELETE(m_pMap);
- }
- GlobalPtr
- HXGlobalManagerImp::DoAdd(const int* pContext,
- GlobalID id,
- GlobalType pObj,
- HXGlobalDestroyFunc fpDestroy)
-
- {
- m_pMutex->Lock();
- if (!m_pMap->IsMember(id))
- {
- m_pMap->Add(pContext, id, pObj, fpDestroy);
- }
-
- GlobalPtr ptr = m_pMap->Get(id);
- m_pMutex->Unlock();
- return ptr;
- }
- void
- HXGlobalManagerImp::DoRemove(GlobalID id)
- {
- m_pMutex->Lock();
- m_pMap->Remove(id);
- m_pMutex->Unlock();
- }
- GlobalPtr
- HXGlobalManagerImp::DoGet(GlobalID id) const
- {
- m_pMutex->Lock();
- GlobalPtr ptr = m_pMap->Get(id);
- m_pMutex->Unlock();
- return ptr;
- }
- void
- HXGlobalManagerImp::DoShutdown(const int* pContext)
- {
- m_pMutex->Lock();
- m_pMap->RemoveAll(pContext);
-
- m_pMutex->Unlock();
- }