这里讲的Cache并不是通常说的计算机存储系统中的高速缓存,而是软件层面的缓存,它的做用主要是为了提高数据处理的效率。在AMPS中,Cache的结构如下:
/*Cache结构*/
struct _AMPSCache
{
void* pvHASHTable; /*Hash表,用于查找*/
void* pvHeap; /*堆,用于增删改*/
int nCacheSize; /*Cache大小*/
/*数据处理回调函数*/
AMPS_CacheProcessUserDataCallback pfAMPS_CacheProcessUserDataCallback;
};
/*Cache中hash和堆的结点结构*/
struct _AMPSCacheEntry
{
int nHandle;
t_AMPSHashTableKey oHASHTableKey;
void* pvAMPSCache;
long lEntryCreationTime; /*结点创建时间,做为hash的key*/
void* pvUserData;
};
它内部维护了一个用于查找的hash表(以结点插入时间做为key值)和一个用于增删改的堆,利用这两个数据结构各自的优势来实现了Cache的高速访问。
其源码如下:
AMPS_Cache.h
#ifndef __HEADER_AMPS_CACHE_H
#define __HEADER_AMPS_CACHE_H
#ifdef __cplusplus
extern "C" {
#endif
#include "AMPS_API.h"
#include "AMPS_Hash.h"
#include "AMPS_Heap.h"
typedef struct _AMPSCache t_AMPSCache;
typedef struct _AMPSCacheEntry t_AMPSCacheEntry;
/*Cache结构*/
struct _AMPSCache
{
void* pvHASHTable; /*Hash表,用于查找*/
void* pvHeap; /*堆,用于增删改*/
int nCacheSize; /*Cache大小*/
/*数据处理回调函数*/
AMPS_CacheProcessUserDataCallback pfAMPS_CacheProcessUserDataCallback;
};
/*Cache中hash和堆的结点结构*/
struct _AMPSCacheEntry
{
int nHandle;
t_AMPSHashTableKey oHASHTableKey;
void* pvAMPSCache;
long lEntryCreationTime; /*结点创建时间,做为hash的key*/
void* pvUserData;
};
void* Cache_Init(void* r_pvAMPSContext, int r_nCacheSize, AMPS_CacheProcessUserDataCallback r_pfAMPS_CacheProcessUserDataCallback);
void Cache_Cleanup(void* r_pvAMPSContext, void* r_pvAMPSCache);
int Cache_FreeEntry(void* r_pvAMPSContext, void* r_pvAMPSCacheEntryToFree);
int Cache_AddEntry(void* r_pvAMPSContext, void* r_pvAMPSCache, t_AMPSHashTableKey* r_poHASHTableKey, void* r_pvData);
int Cache_RemoveEntry(void* r_pvAMPSContext, void* r_pvAMPSCache, t_AMPSHashTableKey* r_poHASHTableKey);
int Cache_UpdateEntry(void* r_pvAMPSContext, void* r_pvAMPSCache, t_AMPSHashTableKey* r_poHASHTableKey);
void* Cache_LookupEntry(void* r_pvAMPSContext, void* r_pvAMPSCache, t_AMPSHashTableKey* r_poHASHTableKey);
#ifdef __cplusplus
}
#endif
#endif //__HEADER_AMPS_CACHE_H
#include "AMPS_Core.h"
#include "AMPS_Defines.h"
#include "AMPS_MemMgt.h"
#include "AMPS_LinkList.h"
#include "AMPS_Cache.h"
/*****************************************************************
函数名称: Cache_Init
功能描述: Cache模块初始化
入参::
void* r_pvAMPSContext APMS应用上下文
int r_nCacheSize Cache大小
AMPS_CacheProcessUserDataCallback r_pfAMPS_CacheProcessUserDataCallback
出参:
返回值:
void* Cache句柄
*****************************************************************/
void* Cache_Init(void* r_pvAMPSContext, int r_nCacheSize, AMPS_CacheProcessUserDataCallback r_pfAMPS_CacheProcessUserDataCallback)
{
t_AMPSCache* poAMPSCache = NULL;
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
/*分配一个Cache对象*/
poAMPSCache = AMPS_InternalMalloc(sizeof(t_AMPSCache));
if (NULL == poAMPSCache)
{
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "AMPS_InternalMalloc failed for poAMPSCache.\n");
return NULL;
}
/*指定Cache大小*/
poAMPSCache->nCacheSize = r_nCacheSize;
/*Cache中结点数据处理回调函数*/
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "Set poAMPSCache->pfAMPS_CacheProcessUserDataCallback to user given function.\n");
poAMPSCache->pfAMPS_CacheProcessUserDataCallback = r_pfAMPS_CacheProcessUserDataCallback;
/*创建Cache所使用的Hash表,用于查找*/
poAMPSCache->pvHASHTable = HashTable_Create(r_pvAMPSContext, poAMPSCache->nCacheSize, NULL);
if (NULL == poAMPSCache->pvHASHTable)
{
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "HashTable_Create failed.\n");
return NULL;
}
/*创建Cache所使用堆,用于增、删、改*/
poAMPSCache->pvHeap = Heap_Init(r_pvAMPSContext, poAMPSCache->nCacheSize, Cache_FreeEntry);
if(NULL == poAMPSCache->pvHeap)
{
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "HeapInit failed.\n");
return NULL;
}
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return poAMPSCache;
}
/*****************************************************************
函数名称: Cache_Cleanup
功能描述: Cache模块销毁
入参::
void* r_pvAMPSContext APMS应用上下文
void* r_pvAMPSCache Cache句柄
出参:
返回值:
void
*****************************************************************/
void Cache_Cleanup(void* r_pvAMPSContext, void* r_pvAMPSCache)
{
t_AMPSCache* poAMPSCache = r_pvAMPSCache;
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
/*释放Hash表*/
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "HashTable_Delete called.\n");
HashTable_Delete(r_pvAMPSContext, poAMPSCache->pvHASHTable);
/*释放堆*/
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "Heap_Cleanup called.\n");
Heap_Cleanup(r_pvAMPSContext, poAMPSCache->pvHeap);
/*释放Cache句柄*/
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "AMPS_InternalFree called for poAMPSCache.\n");
AMPS_InternalFree(poAMPSCache);
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
}
/*****************************************************************
函数名称: Cache_AddEntry
功能描述: 向Cache内写数
入参::
void* r_pvAMPSContext APMS应用上下文
void* r_pvAMPSCache Cache句柄
t_AMPSHashTableKey* r_poHASHTableKey Cache结点
void* r_pvData 结点数
出参:
返回值:
void
*****************************************************************/
int Cache_AddEntry(void* r_pvAMPSContext, void* r_pvAMPSCache, t_AMPSHashTableKey* r_poHASHTableKey, void* r_pvData)
{
t_AMPSCache* poAMPSCache = r_pvAMPSCache;
t_Heap* poHeap = poAMPSCache->pvHeap;
t_AMPSCacheEntry* poAMPSCacheEntryToAdd = NULL;
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
/*分配一个Cache结点*/
poAMPSCacheEntryToAdd = AMPS_InternalMalloc(sizeof(t_AMPSCacheEntry));
if (NULL == poAMPSCacheEntryToAdd)
{
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "AMPS_InternalMalloc failed for poAMPSCacheEntryToAdd.\n");
return AMPS_ERROR_FAILURE;
}
/*结点赋值*/
poAMPSCacheEntryToAdd->oHASHTableKey = *r_poHASHTableKey; /*存放hash结点*/
poAMPSCacheEntryToAdd->pvAMPSCache = poAMPSCache; /*存放Cache句柄*/
poAMPSCacheEntryToAdd->pvUserData = r_pvData; /*存放数据*/
/*结点创建时间,这个时间是cache中hash的key值*/
poAMPSCacheEntryToAdd->lEntryCreationTime = SAPI_GetCurrentTimeInMilliSec(r_pvAMPSContext)/1000; //Set creation time
/*Cache已满*/
if(poHeap->nIndex >= poAMPSCache->nCacheSize) //Cache is full, remove Entry from Cache
{
t_HeapNode* poHeapNodeLeastRefered = NULL;
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "Cache is full, Remove Entry from Cache.\n");
/*获取最小堆根结点,即进入Cache最早的结点*/
if(AMPS_SUCCESS != Heap_GetMinNode(r_pvAMPSContext, poHeap, (void**)&poHeapNodeLeastRefered))
{
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "HeapGetMinNode failed.\n");
AMPS_InternalFree(poAMPSCacheEntryToAdd);
return AMPS_ERROR_FAILURE;
}
/*从堆中释放*/
if(AMPS_SUCCESS != Cache_RemoveEntry(r_pvAMPSContext, r_pvAMPSCache, poHeapNodeLeastRefered->pvDataValue))
{
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "Cache_RemoveEntry failed.\n");
AMPS_InternalFree(poAMPSCacheEntryToAdd);
return AMPS_ERROR_FAILURE;
}
}
/*将hash结点写入*/
poAMPSCacheEntryToAdd->nHandle = HashTable_Insert(r_pvAMPSContext, poAMPSCache->pvHASHTable, poAMPSCacheEntryToAdd, &poAMPSCacheEntryToAdd->oHASHTableKey);
if(AMPS_INVALID_HANDLE == poAMPSCacheEntryToAdd->nHandle)
{
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "HashTable_Insert failed.\n");
AMPS_InternalFree(poAMPSCacheEntryToAdd);
return AMPS_ERROR_FAILURE;
}
/*将新结点写入堆*/
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "Inserting new Entry into Heap.\n");
if(AMPS_ERROR_FAILURE == Heap_InsertMin(r_pvAMPSContext, poHeap, poAMPSCacheEntryToAdd, poAMPSCacheEntryToAdd->lEntryCreationTime))
{
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "HeapInsertMin failed.\n");
AMPS_InternalFree(poAMPSCacheEntryToAdd);
return AMPS_ERROR_FAILURE;
}
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Cache_RemoveEntry
功能描述: 从Cache中删除数据
入参::
void* r_pvAMPSContext APMS应用上下文
void* r_pvAMPSCache Cache句柄
t_AMPSHashTableKey* r_poHASHTableKey Cache结点
出参:
返回值:
int
*****************************************************************/
int Cache_RemoveEntry(void* r_pvAMPSContext, void* r_pvAMPSCache, t_AMPSHashTableKey* r_poHASHTableKey)
{
t_AMPSCache* poAMPSCache = r_pvAMPSCache;
t_Heap* poHeap = poAMPSCache->pvHeap;
t_AMPSCacheEntry* poAMPSCacheEntryToRemove = NULL;
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
/*查找cache结点*/
poAMPSCacheEntryToRemove = HashTable_Search(r_pvAMPSContext, poAMPSCache->pvHASHTable, r_poHASHTableKey);
if(NULL != poAMPSCacheEntryToRemove)
{
/*从hash表中删除*/
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "Removing Entry from HashTable.\n");
if(AMPS_SUCCESS != HashTable_RemoveByHandle(r_pvAMPSContext, poAMPSCache->pvHASHTable, poAMPSCacheEntryToRemove->nHandle))
{
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "HashTable_RemoveByHandle failed.\n");
return AMPS_ERROR_FAILURE;
}
/*从堆中删除*/
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "Removing Entry from Heap.\n");
if (AMPS_SUCCESS != Heap_RemoveNodeMin(r_pvAMPSContext, poHeap, poAMPSCacheEntryToRemove->lEntryCreationTime))
{
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "Heap_RemoveNodeMin failed.\n");
return AMPS_ERROR_FAILURE;
}
}
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Cache_UpdateEntry
功能描述: 更新Cache中的数据
入参::
void* r_pvAMPSContext APMS应用上下文
void* r_pvAMPSCache Cache句柄
t_AMPSHashTableKey* r_poHASHTableKey Cache结点
出参:
返回值:
int
*****************************************************************/
int Cache_UpdateEntry(void* r_pvAMPSContext, void* r_pvAMPSCache, t_AMPSHashTableKey* r_poHASHTableKey)
{
t_AMPSCache* poAMPSCache = r_pvAMPSCache;
t_Heap* poHeap = poAMPSCache->pvHeap;
t_AMPSCacheEntry* poAMPSCacheEntryToUpdate = NULL;
long lOldEntryCreationTime = 0;
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
/*查找*/
poAMPSCacheEntryToUpdate = HashTable_Search(r_pvAMPSContext, poAMPSCache->pvHASHTable, r_poHASHTableKey);
if(NULL != poAMPSCacheEntryToUpdate)
{
/*以时间为key值*/
lOldEntryCreationTime = poAMPSCacheEntryToUpdate->lEntryCreationTime;
poAMPSCacheEntryToUpdate->lEntryCreationTime = SAPI_GetCurrentTimeInMilliSec(r_pvAMPSContext)/1000;
/*更新*/
if(AMPS_SUCCESS != Heap_UpdateNodeMinKey(r_pvAMPSContext, poHeap, lOldEntryCreationTime, poAMPSCacheEntryToUpdate->lEntryCreationTime))
{
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "Heap_UpdateNodeMinKey failed.\n");
return AMPS_ERROR_FAILURE;
}
}
else
{
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "HashTable_Search failed.\n");
return AMPS_ERROR_FAILURE;
}
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Cache_LookupEntry
功能描述: 查找Cache中的数据
入参::
void* r_pvAMPSContext APMS应用上下文
void* r_pvAMPSCache Cache句柄
t_AMPSHashTableKey* r_poHASHTableKey Cache结点
出参:
返回值:
void* 查找到的结点
*****************************************************************/
void* Cache_LookupEntry(void* r_pvAMPSContext, void* r_pvAMPSCache, t_AMPSHashTableKey* r_poHASHTableKey)
{
t_AMPSCache* poAMPSCache = r_pvAMPSCache;
t_Heap* poHeap = poAMPSCache->pvHeap;
t_AMPSCacheEntry* poAMPSCacheEntryToFind = NULL;
long lOldEntryCreationTime = 0;
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
poAMPSCacheEntryToFind = HashTable_Search(r_pvAMPSContext, poAMPSCache->pvHASHTable, r_poHASHTableKey);
if(NULL != poAMPSCacheEntryToFind)
{
lOldEntryCreationTime = poAMPSCacheEntryToFind->lEntryCreationTime;
poAMPSCacheEntryToFind->lEntryCreationTime = SAPI_GetCurrentTimeInMilliSec(r_pvAMPSContext)/1000;
/*找到后,更新一下时间*/
if(AMPS_SUCCESS != Heap_UpdateNodeMinKey(r_pvAMPSContext, poHeap, lOldEntryCreationTime, poAMPSCacheEntryToFind->lEntryCreationTime))
{
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "Heap_UpdateNodeMinKey failed.\n");
return NULL;
}
}
else
{
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "HashTable_Search failed.\n");
return NULL;
}
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return(poAMPSCacheEntryToFind->pvUserData);
}
/*****************************************************************
函数名称: Cache_FreeEntry
功能描述: 释放Cache结点
入参::
void* r_pvAMPSContext APMS应用上下文
void* r_pvAMPSCacheEntryToFree Cache结点
出参:
返回值:
int
*****************************************************************/
int Cache_FreeEntry(void* r_pvAMPSContext, void* r_pvAMPSCacheEntryToFree)
{
t_AMPSCacheEntry* poAMPSCacheEntryToFree = r_pvAMPSCacheEntryToFree;
t_AMPSCache* poAMPSCache = poAMPSCacheEntryToFree->pvAMPSCache;
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
/*释放前可能过注册的回调函数做处理*/
if(NULL != poAMPSCache->pfAMPS_CacheProcessUserDataCallback)
{
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "poAMPSCache->pfAMPS_CacheProcessUserDataCallback called.\n");
poAMPSCache->pfAMPS_CacheProcessUserDataCallback(r_pvAMPSContext, poAMPSCacheEntryToFree->pvUserData);
}
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "AMPS_InternalFree called for poAMPSCacheEntryToRemove.\n");
AMPS_InternalFree(poAMPSCacheEntryToFree);
TRACE( CACHE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}