- 浏览: 180747 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
gaojingsong:
http://gaojingsong.iteye.com/bl ...
java的高精度大数字运算的问题 -
joyjiang:
弱弱的问个问题,如果你有三个域名,www.A.com;www. ...
对于一个SSO的ticket生成的安全性问题的点评 -
zhoujianboy:
zhoulieqing 写道请问,若以后面规则生成ticket ...
对于一个SSO的ticket生成的安全性问题的点评 -
zsxxsz:
这个C++ redis 库其实还是依赖的官方的 hiredis ...
Redis的C++客户端接口 -
陈加伟:
楼主,请问下,我采用该代码,使用时提示我这样的错误undefi ...
Redis的C++客户端接口
原作者是kaman, 我作了一点改进。
#ifndef _IHASHCACHE_H #define _IHASHCACHE_H #include "icache.h" #include "imutexlock.h" #include "ierror.h" #include "iexception.h" template <class IObject, class IKey> class IHashCache; // A class derived from 'ICacheNode', it cooperates with 'IHashCache'. // @Description: // 'IHashCacheNode'是'IHashCache'的结点类型,继承了'ICacheNode'与'IHashCache'配对。 // 可以储存结点有效期和Hash,LRU链等信息。 // @MT-Safe: // Yes / Required. // @Notes: // Equality operator and relation equality operator should be overloaded. // @SeeAlso: // 'IHashCache', 'ICacheNode' template < class IObject, //The key type of this cache. class IKey > class IHashCacheNode : public ICacheNode<IObject, IKey> { public: // Constructor. // @Parameters: // %Object The Object to be stored. // %Key The key assoicated the object. // %nSize The size of the object. // %nTimeToLive The time the object lives in the cache. -1 is permanence. IHashCacheNode (IObject Object, const IKey &Key, long nSize = 0, time_t nTimeToLive = -1); // virtual destructor. virtual ~IHashCacheNode(); // Make a new copy of the object in this cachenode and export it. virtual IObject GetObject(); // Return the key in this cachenode . const IKey &GetKey(); private: // Do the initial work for IHashCache. void Init (const IKey &Key); // Prevent the cachenode from implicit conversion. IHashCacheNode(const IHashCacheNode< IObject,IKey > &right) {}; // Prevent the cachenode from doing equality operation. IHashCacheNode< IObject,IKey > & operator=(const IHashCacheNode< IObject,IKey > &right) {}; public: // The next cachenode in hash table. IHashCacheNode *m_pHashNextNode; // The previous cachenode in hash table. IHashCacheNode *m_pHashPrevNode; // The next cachenode in LRU list(access list). IHashCacheNode *m_pAccessListNextNode; // The previous cachenode in LRU list(access list). IHashCacheNode *m_pAccessListPrevNode; // The accessed time of this cachenode. // @Description: // Increment whenever this cachenode was exported. // When this value equals the adjust rate which user defined, the LRU // list will be adjusted, and this value will be set to zero. int m_nHits; // The context of the object which is stored. IObject m_Object; // The key associated with this cachenode. IKey m_Key; friend class IHashCache<IObject, IKey>; }; template <class IObject, class IKey> IHashCacheNode<IObject,IKey>::IHashCacheNode (IObject Object, const IKey &Key, long nSize, time_t nTimeToLive):ICacheNode<IObject, IKey>(nSize,nTimeToLive) { m_Object = Object; Init( Key ); } template <class IObject, class IKey> IHashCacheNode<IObject,IKey>::~IHashCacheNode() { } template <class IObject, class IKey> void IHashCacheNode<IObject,IKey>::Init (const IKey &Key) { m_Key = Key; m_pHashNextNode = NULL; m_pHashPrevNode = NULL; m_pAccessListNextNode = NULL; m_pAccessListPrevNode = NULL; m_nHits = 0; } template <class IObject, class IKey> const IKey &IHashCacheNode<IObject, IKey>::GetKey() { return m_Key; } template <class IObject, class IKey> IObject IHashCacheNode<IObject, IKey>::GetObject() { return m_Object; } #define IHashCacheNodeType IHashCacheNode<IObject, IKey> // 'IHashCache'类继承了'ICache'类,并实现了相应的存取和筛选算法。 // @Description: // 对于Cache的存取,'IHashCache'采用了散列算法,根据用户所提供的散列函数 // 对新储存的结点进行散列。至于筛选算法,则采用最近最少使用LRU算法,存 // 入CACHE的结点组成一条LRU链,用者可以指定改变LRU结点顺序的结点调用次 // 数。每当CACHE装满或结点过期时,'IHashCache'就会从LRU链头开始删除,以 // 滕出空间放入新结点。 用户还可指定每次删除CACHE时一次性删除的结点数。 // @Usage: // Overide '.Hash()' function. // @Notes: // Equality operator and relation equality operator should be overloaded. // @MT-Safe: // Yes / Required. // @SeeAlso: // 'ICache', IHashCacheNode' template < class IObject, //The key type of this cache. class IKey > class IHashCache: public ICache<IObject, IKey> { public: // Default constructor. IHashCache(); // Constructor with configuring parameters. // @Parameters: // %nMaxMem The max memory (bytes) the cache can use. // %nMaxCacheBlock The number of blocks in the hash table. // %nMaxCacheSize The max number of nodes can be stored. // %nNumToReap The number of node being deleted every time // invoking '.Reap()' // %nAjustRate The time of hiting that will change LRU list. IHashCache( long nMaxMem, int nMaxCacheBlock, int nMaxCacheSize, int nNumToReap, int nAdjustRate ); // Destructor. virtual ~IHashCache(); // Reset IHashCache's parameters. virtual void Set(long nMaxMem, int nMaxCacheBlock, int nMaxCacheSize, int nNumToReap, int nAdjustRate ); // Store an object to the cache with the specified key. bool Store (IObject Object, const IKey &Key, long nUsedMem = 0, time_t nTimeToLive = -1); // Fetch an object according to the key specified. ICache // will return a copy of the object. IObject Fetch (const IKey &Key); // Added by Wooce IObject FetchAndCache(const IKey &Key); // Delete an object from the cache according to the key specified. // @Description: // If the key didn't exist, it wouldn't delete anything and return // true. If the key matched the item in the cache, it would delete // it from the cache and return true. Return false if something wrong // happens. bool Delete (const IKey &Key); // Pure abstract function. // The hash function that the derived class should overload for the // hash algorthim use. virtual unsigned Hash( const IKey &Key ) = 0; // 对Cache中的内容进行遍历。 void TraverseContainer(); // 对LRU链进行遍历。 void TraverseXX(); // 回调函数,在运行TraverseContainer时对每个结点回调,可被继承类重载。 virtual void OnTraverseContainer(IHashCacheNodeType *pNode) {}; // 回调函数,在运行TraverseXX时对每个结点回调,可被继承类重载。 virtual void OnTraverseXX(IHashCacheNodeType *pNode) {}; // Get the count of objects stored in the cache. int GetObjectCount (); protected: //Added by Wooce // If an object not exists in the cache, we can use this function to get the object from other place such as database,etc virtual void GetCacheObject( const IKey &Key,IObject& object )=0; // 跟据指定的KEY在CACHE中找寻相应的结点。 IHashCacheNodeType * SearchNode (const IKey &Key); // 删除CACHE中结点。 int Reap (); // CACHE被装满时返回TRUE。 bool IsFull (); // 对HASH表中KEY对应的行进行锁定。 void ReadLockNodeByKey (const IKey &Key); void WriteLockNodeByKey (const IKey &Key); int TryLockWhenCache(const IKey &Key); // 对HASH表中KEY对应的行进行解锁。 void UnLockNodeByKey (const IKey &Key); // 把结点连到HASH表中。 bool AddNodeToContainer (IHashCacheNodeType *pNode); // 把结点从HASH表中移除。 bool DelNodeFromContainer (IHashCacheNodeType *pNode); // 把结点连入LRU链。 bool AddNodeToXX (IHashCacheNodeType *pNode); // 把结点从HASH表中移除。 bool DelNodeFromXX (IHashCacheNodeType *pNode); // 对整条LRU链进行封锁。 void LockXX (); // 对LRU链进行解锁。 void UnLockXX (); // 调整LRU链。 bool AdjustNodeFromXX (IHashCacheNodeType *pNode); // 结点过期时的处理函数。 bool TimeOutHandler (IHashCacheNodeType *pNode); // 把指定的结点链入IHashCache中. bool StoreNode (IHashCacheNodeType *pNode); // 删除指定结点与IHashCache的链结。 void DeleteNode( IHashCacheNodeType* pNode ); // 增加结点时的回调函数,在结点插入前调用。 virtual void OnInsertNode (IHashCacheNodeType *pNode) {}; // 删除结点时的回调函数,在结点删除前调用。 virtual void OnDeleteNode (IHashCacheNodeType *pNode) {}; // 提取结点时的回调函数,在找到结点且返回之前调用。 virtual void OnFetchNode (ICacheNodeType *pNode) {}; // 增加结点时封锁整个Cache,目的是为了保持Cache中结点数和所用内存空间 // 与实际存入的结点相符合,不会出现结点数虚增,即结点数已增加而结点还在 // 等符插入。 void LockStore(); // LockStore()的解锁操作。 void UnLockStore(); private: // Initialize IHashCache's parameters. void Init( long nMaxMem, int nMaxCacheBlock, int nMaxCacheSize, int nNumToReap, int nAdjustRate ); // 把'IHashCache'中占用的内存去除。 void Destory(); protected: // The maximum memory can be used in the cache. long m_nMaxMem; // The used memory used by the cachenode already in the cache. long m_nUsedMem; // The max cachenode count can be stored in the cache. int m_nCacheSize; // The cachenode count already stored in the cache. int m_nCacheCount; // Max blocks in hash int m_nCacheBlocks; // How many objects should be cleared in one reap action int m_nNumToReap; // Only move the object to the end of access list when it was //hit m_nAdjustRate times int m_nAdjustRate; // The head pointers pointed to the first element in each hash table row. IHashCacheNodeType** m_apCacheHead; // The tail pointers pointed to the last element in each hash table row. IHashCacheNodeType** m_apCacheTail; // The head pointer pointed to the first element of LRU list(access list). IHashCacheNodeType* m_pAccessListHead; // The tail pointer pointed to the last element of LRU list(access list). IHashCacheNodeType* m_pAccessListTail; // An array of locks used for locking a specified row in hash table. // It will be used at the time adjusting the hash table which is no need to // lock the whole cache. IRWLock* m_LockHash; // A lock which locks the whole cache when adjusting LRU list. ILock m_LockAccessList; // A lock used when invoking store function. ILock m_LockStore; }; template <class IObject, class IKey> IHashCache<IObject, IKey>::IHashCache() { m_nMaxMem = 0; m_nUsedMem = 0; m_nCacheSize = 0; m_nCacheCount = 0; m_nCacheBlocks = 0; m_nNumToReap = 0; m_nAdjustRate = 0; m_apCacheHead = NULL; m_apCacheTail = NULL; m_pAccessListHead = NULL; m_pAccessListTail = NULL; m_LockHash = NULL; } template <class IObject, class IKey> IHashCache<IObject, IKey>::IHashCache( long nMaxMem, int nMaxCacheBlock, int nMaxCacheSize, int nNumToReap, int nAdjustRate ) { Init( nMaxMem, nMaxCacheBlock, nMaxCacheSize, nNumToReap, nAdjustRate ); } template <class IObject, class IKey> IHashCache<IObject,IKey>::~IHashCache() { Destory(); } template <class IObject, class IKey> void IHashCache<IObject, IKey>::Init( long nMaxMem, int nMaxCacheBlock, int nMaxCacheSize, int nNumToReap, int nAdjustRate ) { try { m_apCacheHead = m_apCacheTail = NULL; m_LockHash = NULL; XNew( m_apCacheHead , IHashCacheNodeType* [ nMaxCacheBlock ] ); XNew( m_apCacheTail , IHashCacheNodeType* [ nMaxCacheBlock ] ); m_LockHash = new IRWLock [ nMaxCacheBlock ]; if ( m_LockHash == NULL ) throw IException( MEMNOTENOUGH, "Not enough memory" ); } catch (...) { if ( m_apCacheHead != NULL ) delete[] m_apCacheHead; if ( m_apCacheTail != NULL ) delete[] m_apCacheTail; if ( m_LockHash != NULL ) delete[] m_LockHash; throw; } for ( int i=0; i<nMaxCacheBlock; i++ ) m_apCacheHead[ i ] = m_apCacheTail[ i ] = NULL; m_pAccessListHead = NULL; m_pAccessListTail = NULL; m_nMaxMem = nMaxMem; m_nUsedMem = 0; m_nCacheSize = nMaxCacheSize; m_nCacheCount = 0; m_nCacheBlocks = nMaxCacheBlock; m_nNumToReap = nNumToReap; m_nAdjustRate = nAdjustRate; } template <class IObject, class IKey> void IHashCache<IObject, IKey>::Destory() { IHashCacheNodeType *p, *p1; if ( m_apCacheHead != NULL ) { for ( int i=0; i < m_nCacheBlocks ; i++ ) { p = m_apCacheHead[i]; while ( p != NULL ) { p1 = p->m_pHashNextNode; delete p; p = p1; } } delete m_apCacheHead; } if ( m_apCacheTail != NULL ) delete m_apCacheTail; if ( m_LockHash != NULL ) delete[] m_LockHash; } template <class IObject, class IKey> void IHashCache<IObject, IKey>::Set(long nMaxMem, int nMaxCacheBlock, int nMaxCacheSize, int nNumToReap, int nAdjustRate ) { Destory(); Init( nMaxMem, nMaxCacheBlock, nMaxCacheSize, nNumToReap, nAdjustRate ); } template <class IObject, class IKey> bool IHashCache<IObject,IKey>::Store( IObject Object, const IKey& Key, long nUsedMem, time_t nTimeToLive ) { IHashCacheNodeType *pNode; try { XNew( pNode , IHashCacheNodeType( Object, Key, nUsedMem, nTimeToLive ) ); } catch ( IException& e ) { g_Error.Out( L_ALARM, e.GetErrorInfo() ); } return StoreNode( pNode ); } template <class IObject, class IKey> IHashCacheNodeType * IHashCache<IObject, IKey>::SearchNode (const IKey &Key) { int nPos = Hash( Key ) % m_nCacheBlocks; IHashCacheNodeType* pNode = m_apCacheTail[ nPos ]; while ( pNode != NULL ) { if ( pNode->m_Key == Key ) break; else pNode = pNode->m_pHashPrevNode; } if ( pNode == NULL ) //Object not in cache return NULL; return pNode; }; template <class IObject, class IKey> int IHashCache<IObject, IKey>::Reap () { int nDeleted = 0; IDEBUG( g_Error.Out( L_DEBUG, "IHashCache: Begin to reap\n") ); for ( int i=0; i < m_nNumToReap; i++ ) { LockXX(); if ( m_pAccessListHead == NULL ) { UnLockXX(); //** break; } IKey Key = m_pAccessListHead->m_Key; UnLockXX(); if ( Delete( Key ) ) nDeleted++; } IDEBUG( g_Error.Out( L_DEBUG, "ICache: Finished reaping.\n" ) ); return nDeleted; } template <class IObject, class IKey> bool IHashCache<IObject, IKey>::IsFull () { return m_nCacheCount == m_nCacheSize || m_nUsedMem >= m_nMaxMem; }; template <class IObject, class IKey> void IHashCache<IObject, IKey>::ReadLockNodeByKey ( const IKey &Key ) { int nPos = Hash( Key ) % m_nCacheBlocks; m_LockHash[ nPos ].ReadLock(); }; template <class IObject, class IKey> void IHashCache<IObject, IKey>::WriteLockNodeByKey ( const IKey &Key ) { int nPos = Hash( Key ) % m_nCacheBlocks; m_LockHash[ nPos ].WriteLock(); }; template <class IObject, class IKey> void IHashCache<IObject, IKey>::UnLockNodeByKey( const IKey &Key ) { int nPos = Hash( Key ) % m_nCacheBlocks; m_LockHash[ nPos ].Release(); }; template <class IObject, class IKey> int IHashCache<IObject, IKey>::TryLockWhenCache ( const IKey &Key ) { int nPos = Hash( Key ) % m_nCacheBlocks; return m_LockHash[ nPos ].TryWriteLock(); }; template <class IObject, class IKey> bool IHashCache<IObject, IKey>::AddNodeToContainer (IHashCacheNodeType *pNode) { IHashCacheNodeType *pHashNode = (IHashCacheNodeType *)pNode; int nPos = Hash( pHashNode->m_Key ) % m_nCacheBlocks; if ( m_apCacheHead[ nPos ] == NULL ) { m_apCacheHead[ nPos ] = pHashNode; m_apCacheTail[ nPos ] = pHashNode; } else { IHashCacheNodeType* pTail = m_apCacheTail[ nPos ]; pHashNode->m_pHashPrevNode = pTail; //item->m_pHashNextNode = NULL; //ommited pTail->m_pHashNextNode = pHashNode; m_apCacheTail[ nPos ] = pHashNode; } return true; }; template <class IObject, class IKey> bool IHashCache<IObject, IKey>::DelNodeFromContainer (IHashCacheNodeType *pNode) { IHashCacheNodeType *pPrevNode = pNode->m_pHashPrevNode; IHashCacheNodeType *pNextNode = pNode->m_pHashNextNode; int nPos = Hash( pNode->m_Key ) % m_nCacheBlocks; if ( pPrevNode == NULL ) m_apCacheHead[ nPos ] = pNextNode; else pPrevNode->m_pHashNextNode = pNextNode; if ( pNextNode == NULL ) m_apCacheTail[ nPos ] = pPrevNode; else pNextNode->m_pHashPrevNode = pPrevNode; IDEBUG( g_Error.Out( L_DEBUG, "IHashCache: delete node from container.\n") ); return true; }; template <class IObject, class IKey> bool IHashCache<IObject, IKey>::AddNodeToXX (IHashCacheNodeType *pNode) { if ( m_pAccessListHead == NULL ) { m_pAccessListHead = pNode; m_pAccessListTail = pNode; } else { pNode->m_pAccessListPrevNode = m_pAccessListTail; //item->m_pAccessListNextNode = NULL; //ommited m_pAccessListTail->m_pAccessListNextNode = pNode; m_pAccessListTail = pNode; } return true; }; template <class IObject, class IKey> bool IHashCache<IObject, IKey>::DelNodeFromXX (IHashCacheNodeType *pNode) { IHashCacheNodeType* pPrevNode = pNode->m_pAccessListPrevNode; IHashCacheNodeType* pNextNode = pNode->m_pAccessListNextNode; if ( pPrevNode == NULL ) m_pAccessListHead = pNextNode; else pPrevNode->m_pAccessListNextNode = pNextNode; if ( pNextNode == NULL ) m_pAccessListTail = pPrevNode; else pNextNode->m_pAccessListPrevNode = pPrevNode; IDEBUG( g_Error.Out( L_DEBUG, "IHashCache: delete node from XX\n") ); return true; }; template <class IObject, class IKey> void IHashCache<IObject, IKey>::LockXX () { m_LockAccessList.Lock(); }; template <class IObject, class IKey> void IHashCache<IObject, IKey>::UnLockXX () { m_LockAccessList.ReleaseLock(); }; template <class IObject, class IKey> bool IHashCache<IObject, IKey>::AdjustNodeFromXX (IHashCacheNodeType *pNode) { pNode->m_nHits++; //Change the LRU list? if ( (pNode->m_nHits % m_nAdjustRate) == 0 ) { //Move this node to the end of the list LockXX(); if ( m_pAccessListTail != pNode ) { // Remove node IHashCacheNodeType* pPrevNode = pNode->m_pAccessListPrevNode; IHashCacheNodeType* pNextNode = pNode->m_pAccessListNextNode; if ( pPrevNode == NULL ) m_pAccessListHead = pNextNode; else pPrevNode->m_pAccessListNextNode = pNextNode; pNextNode->m_pAccessListPrevNode = pPrevNode; //Append to tail m_pAccessListTail->m_pAccessListNextNode = pNode; pNode->m_pAccessListNextNode = NULL; pNode->m_pAccessListPrevNode = m_pAccessListTail; m_pAccessListTail = pNode; } UnLockXX(); } return true; }; template <class IObject, class IKey> bool IHashCache<IObject, IKey>::TimeOutHandler (IHashCacheNodeType *pNode) { time_t now=time(NULL); if ( pNode->m_nTimeOut!=-1 && pNode->m_nTimeOut<now ) //This object already timeouted, shouldn't be used { DeleteNode( pNode ); IDEBUG( g_Error.Out( L_DEBUG, "ICache: Key Expired, it will be deleted.\n" ) ); return true; } return false; }; template <class IObject, class IKey> void IHashCache<IObject, IKey>::LockStore() { m_LockStore.Lock(); }; template <class IObject, class IKey> void IHashCache<IObject, IKey>::UnLockStore() { m_LockStore.ReleaseLock(); }; template <class IObject, class IKey> void IHashCache<IObject, IKey>::TraverseContainer() { int i; IHashCacheNodeType *pNode; g_Error.Out( L_ALARM, "-----Content of Cache------\n" ); for (i=0; i<m_nCacheBlocks; i++) { m_LockHash[i].WriteLock(); pNode = m_apCacheHead[ i ]; while ( pNode != NULL ) { OnTraverseContainer( pNode ); pNode = pNode->m_pHashNextNode; } m_LockHash[i].Release(); } g_Error.Out( L_ALARM, "\nCache Count = %d , Max Cache Size = %d\n", m_nCacheCount, m_nCacheSize ) ; g_Error.Out( L_ALARM, "----------------------------\n" ) ; } template <class IObject, class IKey> void IHashCache<IObject, IKey>::TraverseXX() { LockXX(); g_Error.Out( L_ALARM, "---------LRU List-------------\n" ) ; IHashCacheNodeType *pNode = m_pAccessListHead; while ( pNode != NULL ) { OnTraverseXX( pNode ); pNode = pNode->m_pAccessListNextNode; } g_Error.Out( L_ALARM, "------------------------------\n" ); UnLockXX(); } template <class IObject, class IKey> IObject IHashCache<IObject,IKey>::Fetch (const IKey &Key) { IObject ResObj; ReadLockNodeByKey( Key ); IHashCacheNodeType *pNode = SearchNode( Key ); if ( pNode == NULL ) { UnLockNodeByKey( Key ); return ResObj; } bool NodeTimeOut = TimeOutHandler( pNode ); if ( NodeTimeOut ) { UnLockNodeByKey( Key ); return ResObj; } OnFetchNode( pNode ); pNode->SetLastAccessTime( time(NULL) ); AdjustNodeFromXX( pNode ); ResObj = pNode->GetObject(); IDEBUG( g_Error.Out( L_DEBUG, "ICache: Fetched the node from cache.\n" ) ); UnLockNodeByKey( Key ); return ResObj; } template <class IObject, class IKey> IObject IHashCache<IObject,IKey>::FetchAndCache(const IKey &Key) { IObject ResObj; ReadLockNodeByKey( Key ); IHashCacheNodeType *pNode = SearchNode( Key ); if( pNode==NULL ) { UnLockNodeByKey(Key); if( TryLockWhenCache(Key)!=0 ) { ReadLockNodeByKey(Key); pNode = SearchNode(Key); } } if ( pNode==NULL ) // Not Existed in the Cache { try { GetCacheObject(Key,ResObj); } catch (IException e ) { UnLockNodeByKey( Key ); throw; } catch ( ... ) { UnLockNodeByKey( Key ); throw; } XNew( pNode , IHashCacheNodeType( ResObj, Key, 0, -1 ) ); LockStore(); if ( IsFull() ) { for ( int i=0; i < m_nNumToReap; i++ ) { LockXX(); if ( m_pAccessListHead == NULL ) { UnLockXX(); //** break; } IHashCacheNodeType *p = m_pAccessListHead; OnDeleteNode( p ); m_nCacheCount--; m_nUsedMem -= p->m_nSize; DelNodeFromXX( p ); UnLockXX(); DelNodeFromContainer( p ); delete p; } if ( IsFull( ) ) //it almost couldn't be full. { //Can't complete the reap operation, can't cache any more object UnLockStore(); UnLockNodeByKey(Key); return ResObj; } } OnInsertNode( pNode ); m_nCacheCount++; m_nUsedMem += pNode->GetSize(); AddNodeToContainer( pNode ); LockXX(); AddNodeToXX( pNode ); UnLockXX(); //ResObj = pNode->GetObject(); IDEBUG( g_Error.Out( L_DEBUG, "ICache: Store a new node to cache.\n" ) ); UnLockStore(); } else { OnFetchNode( pNode ); pNode->SetLastAccessTime( time(NULL) ); AdjustNodeFromXX( pNode ); ResObj = pNode->GetObject(); IDEBUG( g_Error.Out( L_DEBUG, "ICache: Fetched the node from cache.\n" ) ); } UnLockNodeByKey( Key ); return ResObj; } template <class IObject, class IKey> bool IHashCache<IObject,IKey>::Delete (const IKey &Key) { WriteLockNodeByKey( Key ); IHashCacheNodeType *pNode = SearchNode( Key ); if ( pNode == NULL ) { UnLockNodeByKey( Key ); return false; } DeleteNode( pNode ); IDEBUG( g_Error.Out( L_DEBUG, "ICache: Delete a node from cache.\n" ) ); UnLockNodeByKey( Key ); return true; } template <class IObject, class IKey> void IHashCache<IObject, IKey>::DeleteNode( IHashCacheNodeType* pNode ) { OnDeleteNode( pNode ); m_nCacheCount--; m_nUsedMem -= pNode->m_nSize; LockXX(); DelNodeFromXX( pNode ); UnLockXX(); DelNodeFromContainer( pNode ); delete pNode; } template <class IObject, class IKey> bool IHashCache<IObject,IKey>::StoreNode (IHashCacheNodeType *pNode) { IObject ResObj; LockStore(); if ( IsFull() ) { if ( Reap()<=0 ) //Only when the objects to be free are all be freed by other thread. if ( IsFull( ) ) //if reap()<=0 , it almost couldn't be full. { //Can't complete the reap operation, can't cache any more object Delete( pNode->GetKey() ); UnLockStore(); return false; } } WriteLockNodeByKey( pNode->GetKey() ); IHashCacheNodeType *pOldNode = SearchNode( pNode->GetKey() ); if ( pOldNode != NULL ) DeleteNode( pOldNode ); OnInsertNode( pNode ); m_nCacheCount++; m_nUsedMem += pNode->GetSize(); AddNodeToContainer( pNode ); LockXX(); AddNodeToXX( pNode ); UnLockXX(); //ResObj = pNode->GetObject(); IDEBUG( g_Error.Out( L_DEBUG, "ICache: Store a new node to cache.\n" ) ); UnLockNodeByKey( pNode->GetKey() ); UnLockStore(); return true; } template <class IObject, class IKey> int IHashCache<IObject,IKey>::GetObjectCount () { return m_nCacheCount; } #endif
发表评论
-
asio的作者对自己实现的coroutine做的说明
2013-11-05 17:15 2047Keen-eyed Asio users may have ... -
Visual Leak Detector(检测内存泄漏)
2013-10-27 07:59 928项目主页:http://vld.codeplex.com教程: ... -
AMF3协议的C++封装
2012-02-07 10:19 11640新的页游采用AMF3协 ... -
对std::string如何去除前后的空格
2011-03-11 10:59 13820同事原先找了个: std::string trim(stri ... -
用C++编写Oracle OCI的接口库的一个注意事项
2010-10-14 11:13 12962002/09/29 written by Wooce: 比 ... -
Redis的C++客户端接口
2010-05-06 17:49 15561用C++访问Redis的还是比较少,Redis的官方网站上列出 ... -
poco vs Boost
2010-04-06 10:57 4677Wooce Yang收集整理 POCO的优点: 1) 比boo ... -
字符串类的FindInclude(查找字符串是否包含在一个字符集中的字符)的实现优化
2010-02-06 10:58 1371以下是coremail的cyt所写的实现代码: int ISt ... -
我对C++核心类库TAttributeSet在稳定性和效率优化上提出的comment
2009-11-26 21:39 11461. -fnew-abi选项支持空基类优化. 2. ... -
我在2000年时用过的一个C++ CGI库
2009-11-14 12:16 1505也有一些字符串操作和mysql数据库访问和socket操作的封 ... -
Progress商业数据库的访问接口的C++包装
2009-05-04 18:14 1280iprogressdb.h: /* Written ... -
技术聊天记录: 关于TAttributeSet减少lookup的改进方法的讨论
2008-05-24 13:34 1303wooce: 我仔细思考了一下: 1) 如果不能把Serv ...
相关推荐
IT面试常见的题目,对于分布式存储系统中常碰到的故障问题,如何解决,就是采用一致性hash算法
在第一个字节流出ReadStream之前,它将每个请求合并为一个。 要乐观。 不要检查缓存,然后从中获取内容。 尝试从中获取信息,如果我们遇到ENOENT ,请后退。 面对并发时保持正确。 我们竭尽全力确保流程相互等待...
基于共享Cache多核处理器的Hash连接优化.pdf
一个进程在对数据块执行add, remove, search, inspect, read 或者modify之前需要首先获得cache buffers chains latch. 有两条规则跟oracle访问数据块时的cache buffers chains相关. 每一个logical read都会造成一...
好用的Hash工具 abnormal_recovery: 0 boot: cd bootdisk: ide0 cfgstorage: local cores: 1 cpu: core2duo dir: 9882a70378e6 host: host-00900b24b834 ide0: local:vm-disk-1.qcow2,cache=directsync,preallocate=...
搜索引擎应用技术-cache技术,hash算法
dns cache hash 基于哈希表的高速DNS缓存实现
一致性hash应用于负载均衡算法,本实现由C++语言开发。 一致性hash算法提出了在动态变化的Cache环境中,判定哈希算法好坏的四个定义: 1、平衡性(Balance)2、单调性(Monotonicity) 3、分散性(Spread)4、负载(Load)
比如你有 N 个 cache 服务器(后面简称 cache ),那么如何将一个对象 object 映射到 N 个 cache 上呢,你很可能会采用类似下面的通用方法计算 object 的 hash 值,然后均匀的映射到到 N 个 cache ; hash(object)%N
Cache-, Hash- and Space-Efficient Bloom FiltersFelix Putze, Peter Sanders, Johannes Singler {putze,sanders,singler}@ira.uka.deFakultät für Informatik, Universität Karlsruhe, GermanyAbstract. A ...
一个帮助包转换,当优化被禁用时防止缓存包内容 - 当调试被启用或 BundleTable.EnableOptimizations 为 false 时。 在 Nuget 上获取它! Install-Package System.Web.Optimization.HashCache 电梯演讲 当您在调试...
比如你有 N 个 cache 服务器(后面简称 cache ),那么如何将一个对象 object 映射到 N 个 cache 上呢,你很可能会采用类似下面的通用方法计算 object 的 hash 值,然后均匀的映射到到 N 个 cache ; hash(object)%N...
* 试想,增加一台服务器,同一个key经过hash之后,与服务器取模的结果和没增加之前的结果肯定不一样,这就导致了,之前保存的数据丢失 * * 一致性哈希算法 * 优点:在分布式的cache缓存中,其中一台宕机,迁移...
sql语句按照hash的算法,产生hash 值,这里,我们可以把hash值当做一个PK值,然后根据这个值去寻找library cache相同的hash 值。如果有则应用这个hash所对应的执行计划。如果没有则再生成一个新的执行计划。
编译OpenCV4.2时,所有的cache文件。例如5de6044cad9398549e57bc46fc13908d-opencv_videoio_ffmpeg.dll
缓存 在持续集成构建之间缓存文件和文件夹,以加快构建执行速度。...上传缓存文件/文件夹 ci-cache set --name cache-key --content cache-folder --hash-file version.lock如果hash-file已更改,则仅重新上
Initializes the color cache with hash_bits bits for the keys. Returns false in case of memory error.
Hutool 是一个 Java 工具包类库,它可以对文件、流、加密解密、转码、正则、线程、XML等JDK方法进行封装,组成各种 Utils 工具类。 Hutool 即是 Hu(谐音“糊涂”) + tool,前者致敬作者 “前任公司”,后者为工具...
背景我想要一个可以用 MD5 哈希字符串命名事物的库。 它会要求很多相同的散列,而且它需要很快。用法 var Hache = require ( 'hache' ) ;var hache = new Hache ( 'md5' ) ;var hash = hache . encode ( 'random...
#match_hash_in_cmake_cache "OCV_DOWNLOAD_ADE_HASH_3rdparty_ade_v0_1_2d_zip" #match_hash_in_cmake_cache "OCV_DOWNLOAD_FFMPEG_HASH_3rdparty_ffmpeg_opencv_videoio_ffmpeg_dll" #do_copy "opencv_videoio_...