当前位置: 首页 > 工具软件 > AMPS > 使用案例 >

AMPS:Cache模块源码解读

祖迪
2023-12-01

  这里讲的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

AMPS_Cache.c

#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;
}



 类似资料: