The cache mentioned here is not a high-speed cache in computer storage systems, but a software cache. It is mainly used to improve data processing efficiency. In amps, the cache structure is as follows:
/* Cache structure */struct _ ampscache {void * pvhashtable;/* hash table for searching */void * pvheap;/* heap for adding, deleting, and modifying */intncachesize; /* cache size * // * Data Processing callback function */callback;};/* hash and heap node Structure in cache */struct _ ampscacheentry {int nhandle; t_ampshashtablekey ohashtablekey; void * pvampscache; long lentrycreationtime;/* node creation time, used as the hash key */void * pvuserdata ;};
It maintains a hash table for search (with the node insertion time as the key value) and a heap for addition, deletion, and modification, the advantages of these two data structures are used to achieve high-speed access to the cache.
The source code is as follows:
Amps_cache.h
# Ifndef _ syntax # DEFINE _ coding # ifdef _ cplusplusextern "C" {# endif # include "Syntax" # include "amps_hash.h" # include "amps_heap.h" typedef struct _ ampscache t_ampscache; typedef struct _ ampscacheentry t_ampscacheentry;/* cache structure */struct _ ampscache {void * pvhashtable;/* hash table for searching */void * pvheap;/* heap, used to add, delete, modify, and delete */intncachesize;/* cache size * // * Data Processing callback function */amps_cacheprocessuserdatacallbackpfamps_cacheprocessuserdatacallback ;}; /* hash and heap node Structure in cache */struct _ ampscacheentry {int nhandle; t_ampshashtablekey ohashtablekey; void * pvampscache; long lentrycreationtime;/* node Creation Time, key */void * pvuserdata;} as hash; void * cache_init (void * r_pvampscontext, int r_ncachesize, callback); void cache_cleanup (void * r_pvampscontext, void * handle ); int cache_freeentry (void * r_pvampscontext, void * callback); int Digest (void * r_pvampscontext, void * handle, callback * handle, void * r_pvdata); int cache_removeentry (void * r_pvampscontext, void * handle, comment * r_pohashtablekey); int cache_updateentry (void * r_pvampscontext, void * handle, role * handle); void * cache_lookupentry (void * r_pvampscontext, void * handle, t_ampshashtablekey * r_pohashtablekey); # ifdef _ cplusplus} # 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 "/************** **************************************** * ********** Function Name: cache_init Function Description: cache module initialization input parameter: void * r_pvampscontext APMs application context int r_ncachesize cache size amps_cacheprocessuserdatacallback r_pfamps_cacheprocessuserdatacallback output parameter: return value: void * cache handle *************************** * ***********************************/Void * cache_init (void * r_pvampscontext, int r_ncachesize, amps_cacheprocessuserdatacallback callback) {t_ampscache * poampscache = NULL; trace (cache_trace_id (r_pvampscontext), amps_trace_level_info, "entering. \ n ");/* allocate a cache object */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;}/* specify the cache size */poampscache-> ncachesize = r_ncachesize;/* cache node data processing callback function */Trace (cache_trace_id (r_pvampscontext ), amps_trace_level_debug, "set poampscache-> pfamps_cacheprocessuserdatacallback to user given function. \ n "); poampscache-> pfamps_cacheprocessuserdatacallback = r_pfamps_cacheproces Suserdatacallback;/* Create the hash table used by the cache for searching */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;}/* The heap used to create the cache for adding, deleting, and modifying */poampscache-> pvheap = heap_init (r_pvampscontext, poampscache-> ncachesize, cache_freeentr Y); 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 ;} /*************************************** * ************************** Function Name: cache_cleanup Function Description: cache module destruction input parameter: void * r_pvampscontext APMs application context void * r_pvampscache cache handle Output parameter: return value: 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 ");/* release hash table */Trace (cache_trace_id (r_pvampscontext), amps_trace_level_debug," hashtable_delete called. \ n "); hashtable_delete (r_pvampscont EXT, poampscache-> pvhashtable);/* release heap */Trace (cache_trace_id (r_pvampscontext), amps_trace_level_debug, "heap_cleanup called. \ n "); heap_cleanup (r_pvampscontext, poampscache-> pvheap);/* release cache handle */Trace (cache_trace_id (r_pvampscontext), callback," amps_internalfree called for poampscache. \ n "); amps_internalfree (poampscache); trace (cache_trace_id (r_pvampscontext), amps_trace_level_in Fo, "leaving. \ n ");} /*************************************** * ************************** Function Name: cache_addentry Function Description: input parameter for writing data to the cache: void * r_pvampscontext APMs application context void * r_pvampscache cache handle points Output parameter: return value: void *************************************** * ************************/INT cache_addentry (void * r_pvampscontext, void * r_pvampscache, t_ampshash Tablekey * r_pohashtablekey, void * r_pvdata) {t_ampscache * poampscache = enabled; t_heap * poheap = poampscache-> pvheap; optional * Signature = NULL; trace (r_pvampscontext), callback, callback, "entering. \ n ");/* allocate a cache node */allocated = amps_internalmalloc (sizeof (t_ampscacheentry); If (null = poampscacheentrytoadd) {trace (cache_trace_id (r_pvam) Pscontext), amps_trace_level_error, "amps_internalmalloc failed for poampscacheentrytoadd. \ n "); Return amps_error_failure;}/* node assignment */partition-> ohashtablekey = * r_pohashtablekey;/* store the hash node */partition-> pvampscache = poampscache; /* store the cache handle */poampscacheentrytoadd-> pvuserdata = r_pvdata;/* store data * // * creation time of the node, this time is the key value of the hash in the cache */poampscacheentrytoadd-> lentrycreationtime = SAP I _getcurrenttimeinmillisec (r_pvampscontext)/1000; // set creation time/* cache full */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 ");/* obtain the minimum heap root node, that is, enter the earliest node of the cache */If (amps_success! = Heap_getminnode (r_pvampscontext, poheap, (void **) & poheapnodeleastrefered) {trace (cache_trace_id (r_pvampscontext), digest, "heapgetminnode failed. \ n "); amps_internalfree (poampscacheentrytoadd); Return amps_error_failure;}/* release from heap */If (amps_success! = Cache_removeentry (r_pvampscontext, r_pvampscache, poheapnodeleastrefered-> pvdatavalue) {trace (cache_trace_id (r_pvampscontext), callback, "cache_removeentry failed. \ n "); amps_internalfree (random); Return amps_error_failure;}/* write the hash node into */random-> nhandle = hashtable_insert (r_pvampscontext, poampscache-> pvhashtable, ignore, & poampscacheen Trytoadd-> ohashtablekey); If (amps_invalid_handle = callback-> nhandle) {trace (cache_trace_id (r_pvampscontext), amps_trace_level_error, "hashtable_insert failed. \ n "); amps_internalfree (random); Return random;}/* write new nodes to the heap */Trace (cache_trace_id (r_pvampscontext), amps_trace_level_debug," inserting new entry into heap. \ n "); If (amps_error_failure = heap_insert Min (r_pvampscontext, poheap, latency, latency-> 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 ;} /*************************************** ** * ********************** Function name: cache_removeentry Function Description: delete data input parameters from the cache :: void * r_pvampscontext APMs application context void * r_pvampscache cache handle t_ampshashtablekey * r_pohashtablekey cache junction output parameter: return value: int *************************************** * ***********************/INT cache_removeentry (void * r_pvampscontext, void * r_pvampscache, t_ampshashtablekey * r_pohashtablekey) {t_ampscache * poampscache = r_pvampscache; t_h EAP * poheap = poampscache-> pvheap; t_ampscacheentry * poampscacheentrytoremove = NULL; trace (cache_trace_id (r_pvampscontext), amps_trace_level_info, "entering. \ n ");/* Find the cache node */poampscacheentrytoremove = hashtable_search (r_pvampscontext, poampscache-> pvhashtable, r_pohashtablekey); If (null! = Success) {/* delete from the hash table */Trace (cache_trace_id (r_pvampscontext), amps_trace_level_debug, "Removing entry from hashtable. \ n"); If (amps_success! = Hashtable_removebyhandle (r_pvampscontext, poampscache-> pvhashtable, callback-> nhandle) {trace (cache_trace_id (r_pvampscontext), callback, "hashtable_removebyhandle failed. \ n "); Return amps_error_failure;}/* Delete from heap */Trace (cache_trace_id (r_pvampscontext), amps_trace_level_debug," Removing entry from heap. \ n "); If (amps_success! = Heap_removenodemin (r_pvampscontext, poheap, callback-> 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 ;} /*************************************** * ************************** Function Name: cache_updateen Try Function Description: update the data input parameter in the cache: void * r_pvampscontext APMs application context void * r_pvampscache cache handle t_ampshashtablekey * r_pohashtablekey cache output parameter: return value: int *************************************** * ************************/INT cache_updateentry (void * r_pvampscontext, void * r_pvampscache, t_ampshashtablekey * r_pohashtablekey) {t_ampscache * poampscache = r_pvampscache; t_heap * poheap = poampscache-> pvheap Eentry * poampscacheentrytoupdate = NULL; long loldentrycreationtime = 0; trace (cache_trace_id (r_pvampscontext), amps_trace_level_info, "entering. \ n ");/* Find */poampscacheentrytoupdate = hashtable_search (r_pvampscontext, poampscache-> pvhashtable, r_pohashtablekey); If (null! = Keys) {/* the key value is time */loldentrycreationtime = hour-> lentrycreationtime; poampscacheentrytoupdate-> lentrycreationtime = sapi_getcurrenttimeinmillisec (r_pvampscontext)/1000; /* update */If (amps_success! = Heap_updatenodeminkey (r_pvampscontext, poheap, loldentrycreationtime, queue-> lentrycreationtime) {trace (cache_trace_id (r_pvampscontext), queue, "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_pvamp Scontext), amps_trace_level_info, "leaving. \ n "); Return amps_success ;} /*************************************** * ************************** Function Name: cache_lookupentry Function Description: query the data input parameter in the cache: void * r_pvampscontext APMs application context void * r_pvampscache cache handle t_ampshashtablekey * r_pohashtablekey cache junction output parameter: return value: void * found node ********************************** * *****************************/void * cache_lookupentry (void * R_pvampscontext, void * callback, role * r_pohashtablekey) {t_ampscache * poampscache = r_pvampscache; t_heap * poheap = poampscache-> pvheap; duration * timeout = NULL; long timeout = 0; trace (cache_trace_id (r_pvampscontext), amps_trace_level_info, "entering. \ n "); poampscacheentrytofind = hashtable_search (r_pvampscontext, poampscache-> pvhashtable, R_pohashtablekey); If (null! = Timeout) {loldentrycreationtime = timeout-> lentrycreationtime; timeout-> lentrycreationtime = sapi_getcurrenttimeinmillisec (r_pvampscontext)/1000;/* update the time */If (amps_success! = Heap_updatenodeminkey (r_pvampscontext, poheap, loldentrycreationtime, queue-> lentrycreationtime) {trace (cache_trace_id (r_pvampscontext), queue, "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_in Fo, "leaving. \ n "); Return (poampscacheentrytofind-> pvuserdata );} /*************************************** * ************************** Function Name: cache_freeentry Function Description: Release cache node input parameter: void * r_pvampscontext APMs application context void * r_pvampscacheentrytofree cache node output parameter: return value: int *************************************** * ***********************/INT cache_freeentry (void * r_pvampscontext, void * r_pvampscacheentrytofree) {t_ampsca Cheentry * Signature = signature; t_ampscache * poampscache = poampscacheentrytofree-> pvampscache; trace (cache_trace_id (r_pvampscontext), amps_trace_level_info, "entering. \ n ");/* The registered callback function may be used before release */If (null! = Poampscache-> pfamps_cacheprocessuserdatacallback) {trace (cache_trace_id (r_pvampscontext), amps_trace_level_debug, "poampscache-> Reset called. \ n "); poampscache-> callback (r_pvampscontext, callback-> pvuserdata);} trace (cache_trace_id (r_pvampscontext), amps_trace_level_debug," amps_internalfree called for callback. \ n "); amps_internalfree (poampscacheentrytofree); trace (cache_trace_id (r_pvampscontext), amps_trace_level_info," leaving. \ n "); Return amps_success ;}