- 浏览: 184733 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
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 2097Keen-eyed Asio users may have ... -
Visual Leak Detector(检测内存泄漏)
2013-10-27 07:59 1004项目主页:http://vld.codeplex.com教程: ... -
AMF3协议的C++封装
2012-02-07 10:19 11708新的页游采用AMF3协 ... -
对std::string如何去除前后的空格
2011-03-11 10:59 13909同事原先找了个: std::string trim(stri ... -
用C++编写Oracle OCI的接口库的一个注意事项
2010-10-14 11:13 13592002/09/29 written by Wooce: 比 ... -
Redis的C++客户端接口
2010-05-06 17:49 15628用C++访问Redis的还是比较少,Redis的官方网站上列出 ... -
poco vs Boost
2010-04-06 10:57 4730Wooce Yang收集整理 POCO的优点: 1) 比boo ... -
字符串类的FindInclude(查找字符串是否包含在一个字符集中的字符)的实现优化
2010-02-06 10:58 1406以下是coremail的cyt所写的实现代码: int ISt ... -
我对C++核心类库TAttributeSet在稳定性和效率优化上提出的comment
2009-11-26 21:39 11851. -fnew-abi选项支持空基类优化. 2. ... -
我在2000年时用过的一个C++ CGI库
2009-11-14 12:16 1553也有一些字符串操作和mysql数据库访问和socket操作的封 ... -
Progress商业数据库的访问接口的C++包装
2009-05-04 18:14 1308iprogressdb.h: /* Written ... -
技术聊天记录: 关于TAttributeSet减少lookup的改进方法的讨论
2008-05-24 13:34 1363wooce: 我仔细思考了一下: 1) 如果不能把Serv ...
相关推荐
而为了提高数据访问速度,Oracle 引入了一个重要的内存组件——Buffer Cache(数据高速缓存区)。Buffer Cache 的核心作用在于减少磁盘 I/O 操作,因为相较于磁盘访问,内存访问速度快得多。 **1.1 Buffer Cache ...
总的来说,该研究为多核处理器上的数据库查询优化提供了一个有价值的视角,特别是在处理大数据连接操作时,优化Hash连接的性能对于提升系统整体性能有着显著的作用。通过理解并应用文中提到的多线程执行框架、Radix-...
具体来说,当搜索引擎处理网页时,会根据网页的内容生成一个唯一的Hash值。这个Hash值作为索引的一部分,用于快速定位和检索网页。Hash算法具有快速计算和唯一性的特点,即使对于庞大的数据集,也能迅速找到对应的...
- `NXT_HASH` 和 `PRV_HASH`:分别指向同一HashChain List中的下一个和上一个块地址,构成双向链表结构。 - `NXT_REPL` 和 `PRV_REPL`:分别指向LRU List中的下一个和上一个块地址,用于维护LRU链表。 - `TCH`:表示...
在第一个字节流出ReadStream之前,它将每个请求合并为一个。 要乐观。 不要检查缓存,然后从中获取内容。 尝试从中获取信息,如果我们遇到ENOENT ,请后退。 面对并发时保持正确。 我们竭尽全力确保流程相互等待...
Library cache的管理由Library Cache Manager负责,它是Oracle内存管理器——KGH Heap Manager的一个客户端。Heap Manager负责分配和回收内存,对于shared pool,内存是预分配的,当进程需要内存时,Heap Manager...
#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_...
FlashCache的缓存结构基于集合相联式哈希(Set Associative Hash),它采用固定大小的桶(Bucket)集合,并通过线性探测法在一个桶内查找空位。默认情况下,FlashCache是512路集合相联式,也就是说每个桶可以关联...
在应用中启用Spring Cache,我们需要创建一个配置类,该类使用`@EnableCaching`注解开启缓存功能。同时,为了处理缓存中的对象序列化问题,我们使用Fastjson替换默认的JDK序列化。这通常涉及到创建一个自定义的`...
综上所述,"redis-cluster和spring集成,基于cache注解" 的项目是一个使用 Spring Cache 集成 Redis 集群的实例,旨在通过注解的方式简化缓存管理,提高应用性能。开发者可以通过导入提供的项目,快速了解和实践这一...
在这一过程中,CMake会将配置信息、依赖关系以及编译选项等数据存储在一个或多个.cache文件中。以题目中给出的例子“5de6044cad9398549e57bc46fc13908d-opencv_videoio_ffmpeg.dll”为例,这可能是一个针对特定模块...
好用的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=...
本项目"redis-cache-mybatis"正是为了实现这一目的,提供了一个可以直接使用的Redis缓存解决方案。 在MyBatis中,Redis缓存主要涉及以下几个核心概念: 1. **配置Redis**:首先,我们需要在应用的配置文件中添加...
当一个进程需要对数据块进行操作时,它必须首先获取相应的`cache buffers chains latch`。例如,在执行一个逻辑读取操作时,不仅会消耗CPU时间,还需要获取一个`latch`锁。这意味着每次逻辑读操作都会引发一次`latch...
一致性hash应用于负载均衡算法,本实现由C++语言开发。 一致性hash算法提出了在动态变化的Cache环境中,判定哈希算法好坏的四个定义: 1、平衡性(Balance)2、单调性(Monotonicity) 3、分散性(Spread)4、负载(Load)
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 ...