Reputation: 120
I am trying to write an LRU cache which can hold any type of data item in c for a postgresql extension. Everything is fine except that I am relying on postgresql hashmap which itself allocates memory for entry and also maintains the same memory in a free list when removed.
The struct I defined:
typedef void *(*KeyConstructFunction)(void *data);
typedef void *(*EntryConstructFunction)(void *data);
typedef void (*DestoryEntryFunction)(void *data);
struct LRU_Cache
{
dlist_head *cacheList;
HTAB *cacheHashmap;
KeyConstructFunction keyConstructFunction;
EntryConstructFunction valueConstructFunction;
// will be called when I remove an entry from cache
DestoryEntryFunction elemDestroyFunction;
};
So the problem is since I need to maintain the data order I am using dlist_node in entry which will be given to dlist related functions to add into cacheList. since I won't the type of data passed I can't use the dlist functions as I don't know to which type I need to type cast. Consider the below function.
dlist_container(ENTRY_TYPE, node, dlist_head_node(&LRU_Cache->cacheList));
This can be solved by giving called may be another function pointer but I would have to then do it for some other dlist functions to so I thought that won't be a good approach and avoided that approach. since I don't know the entry type I am unable to do this operation which gives me the entire data item. I though using a standard struct like below
typedef struct Cache_Entry
{
void *key;
void *value;
dlist_node node;
} Cache_Entry;
But the problem is if I give key size and entry size then it will be like 8 bytes and 32 bytes respectively due to this I can only hold 32 bytes in free list and have to specify called to never free key, value he/she passes.
Seems like I got into some kind of dead lock. Is there a way to solve this design issue without compromising the generic thing.
Upvotes: 2
Views: 121