Table of the cache entries allocated by silc_idcache_add function.
This table is reallocated when new entry is added into the cache.
- unsigned int cache_count
+ uint32 cache_count
Number of cache entries in the cache.
is to provide faster access to the cache when searching by data.
This is updated by silc_idcache_add and sorting functions.
+ SilcIDCacheDestructor destructor
+
+ Destructor callback that is called when an cache entry expires or is
+ purged from the ID cache. The application must not free cache entry
+ because the library will do it automatically. The appliation, however,
+ is responsible of freeing any data in the entry.
+
*/
struct SilcIDCacheStruct {
SilcIDCacheEntry cache;
- unsigned int cache_count;
+ uint32 cache_count;
int sorted;
int fast_access[256];
+ SilcIDCacheDestructor destructor;
};
/*
struct SilcIDCacheListStruct {
SilcIDCacheEntry cache[64];
SilcIDCacheEntry *cache_dyn;
- unsigned int cache_dyn_count;
- unsigned int cache_count;
- unsigned int pos;
+ uint32 cache_dyn_count;
+ uint32 cache_count;
+ uint32 pos;
};
/* Allocates new ID cache object. The initial amount of allocated entries
can be sent as argument. If `count' is 0 the system uses default values. */
-SilcIDCache silc_idcache_alloc(unsigned int count)
+SilcIDCache silc_idcache_alloc(uint32 count,
+ SilcIDCacheDestructor destructor)
{
SilcIDCache cache;
cache->cache = silc_calloc(count ? count : 5, sizeof(*cache->cache));
cache->cache_count = count ? count : 5;
memset(cache->fast_access, -1, sizeof(cache->fast_access));
+ cache->destructor = destructor;
return cache;
}
break;
if (cache->cache[i].data &&
- !memcmp(cache->cache[i].data, data, strlen(cache->cache[i].data)))
+ !memcmp(cache->cache[i].data, data, cache->cache[i].data_len))
silc_idcache_list_add(list, &(cache->cache[i]));
}
- if (!silc_idcache_list_count(list))
+ if (!silc_idcache_list_count(list)) {
+ silc_idcache_list_free(list);
return FALSE;
+ }
if (ret)
*ret = list;
for (i = i; i < cache->cache_count; i++)
if (cache->cache[i].data &&
- !memcmp(cache->cache[i].data, data, strlen(cache->cache[i].data))) {
+ !memcmp(cache->cache[i].data, data, cache->cache[i].data_len)) {
if (ret)
*ret = &(cache->cache[i]);
return TRUE;
}
}
- if (!silc_idcache_list_count(list))
+ if (!silc_idcache_list_count(list)) {
+ silc_idcache_list_free(list);
return FALSE;
+ }
if (ret)
*ret = list;
silc_idcache_list_add(list, &(cache->cache[i]));
}
- if (!silc_idcache_list_count(list))
+ if (!silc_idcache_list_count(list)) {
+ silc_idcache_list_free(list);
return FALSE;
+ }
if (ret)
*ret = list;
however, it is not mandatory. */
int silc_idcache_add(SilcIDCache cache, unsigned char *data,
- SilcIdType id_type,
- void *id, void *context, int sort)
+ uint32 data_len, SilcIdType id_type, void *id,
+ void *context, int sort, int expire)
{
int i;
- unsigned int count;
- unsigned long curtime = time(NULL);
+ uint32 count;
+ uint32 curtime = time(NULL);
SilcIDCacheEntry c;
if (!cache || !cache->cache)
for (i = 0; i < count; i++) {
if (c[i].data == NULL && c[i].id == NULL) {
c[i].data = data;
+ c[i].data_len = data_len;
c[i].type = id_type;
c[i].id = id;
- c[i].expire = curtime + SILC_ID_CACHE_EXPIRE;
+ c[i].expire = (expire ? (curtime + SILC_ID_CACHE_EXPIRE) : 0);
c[i].context = context;
break;
}
c[i].id = NULL;
}
c[count].data = data;
+ c[count].data_len = data_len;
c[count].type = id_type;
c[count].id = id;
- c[count].expire = curtime + SILC_ID_CACHE_EXPIRE;
+ c[count].expire = (expire ? (curtime + SILC_ID_CACHE_EXPIRE) : 0);
c[count].context = context;
count += 5;
}
int silc_idcache_purge(SilcIDCache cache)
{
SilcIDCacheEntry c;
- unsigned long curtime = time(NULL);
+ uint32 curtime = time(NULL);
int i;
if (!cache || !cache->cache)
c = cache->cache;
for (i = 0; i < cache->cache_count; i++) {
- if (c[i].data &&
- (c[i].expire == 0 || c[i].expire < curtime)) {
+ if (c[i].data && c[i].expire && c[i].expire < curtime) {
+
+ /* Call the destructor */
+ if (cache->destructor)
+ cache->destructor(cache, &c[i]);
+
c[i].id = NULL;
c[i].data = NULL;
c[i].type = 0;
return TRUE;
}
+/* Purges the specific entry by context. */
+
+int silc_idcache_purge_by_context(SilcIDCache cache, void *context)
+{
+ SilcIDCacheEntry entry;
+
+ if (!silc_idcache_find_by_context(cache, context, &entry))
+ return FALSE;
+
+ /* Call the destructor */
+ if (cache->destructor)
+ cache->destructor(cache, entry);
+
+ entry->id = NULL;
+ entry->data = NULL;
+ entry->type = 0;
+ entry->expire = 0;
+ entry->context = NULL;
+ return TRUE;
+}
+
/* Allocates ID cache list. */
static SilcIDCacheList silc_idcache_list_alloc()