Refine LRU cache by clearing old objects

This commit is contained in:
Max Lv
2016-10-26 08:53:21 +08:00
parent e0cfa6945a
commit 85a5c86637
9 changed files with 84 additions and 12 deletions
+6
View File
@@ -56,6 +56,12 @@ remove_from_block_list(char *addr)
return cache_remove(block_list, addr, addr_len);
}
void
clear_block_list()
{
cache_clear(block_list, 3600); // Clear items older than 1 hour
}
int
check_block_list(char *addr, int err_level)
{
+1
View File
@@ -34,6 +34,7 @@
int init_acl(const char *path);
void free_acl(void);
void clear_block_list(void);
int acl_match_host(const char *ip);
int acl_add_ip(const char *ip);
+43 -1
View File
@@ -94,7 +94,7 @@ cache_delete(struct cache *cache, int keep_data)
if (cache->free_cb) {
cache->free_cb(entry->data);
} else {
ss_free(tmp->data);
ss_free(entry->data);
}
}
ss_free(entry->key);
@@ -106,6 +106,45 @@ cache_delete(struct cache *cache, int keep_data)
return 0;
}
/** Clear old cache object
*
* @param cache
* The cache object to clear
*
* @param age
* Clear only objects older than the age (sec)
*
* @return EINVAL if cache is NULL, 0 otherwise
*/
int
cache_clear(struct cache *cache, ev_tstamp age)
{
struct cache_entry *entry, *tmp;
if (!cache) {
return EINVAL;
}
ev_tstamp now = ev_time();
HASH_ITER(hh, cache->entries, entry, tmp){
if (now - entry->ts > age) {
HASH_DEL(cache->entries, entry);
if (entry->data != NULL) {
if (cache->free_cb) {
cache->free_cb(entry->data);
} else {
ss_free(entry->data);
}
}
ss_free(entry->key);
ss_free(entry);
}
}
return 0;
}
/** Removes a cache entry
*
* @param cache
@@ -179,6 +218,7 @@ cache_lookup(struct cache *cache, char *key, size_t key_len, void *result)
HASH_FIND(hh, cache->entries, key, key_len, tmp);
if (tmp) {
HASH_DELETE(hh, cache->entries, tmp);
tmp->ts = ev_time();
HASH_ADD_KEYPTR(hh, cache->entries, tmp->key, key_len, tmp);
*dirty_hack = tmp->data;
} else {
@@ -200,6 +240,7 @@ cache_key_exist(struct cache *cache, char *key, size_t key_len)
HASH_FIND(hh, cache->entries, key, key_len, tmp);
if (tmp) {
HASH_DELETE(hh, cache->entries, tmp);
tmp->ts = ev_time();
HASH_ADD_KEYPTR(hh, cache->entries, tmp->key, key_len, tmp);
return 1;
} else {
@@ -242,6 +283,7 @@ cache_insert(struct cache *cache, char *key, size_t key_len, void *data)
entry->key = ss_malloc(key_len);
memcpy(entry->key, key, key_len);
entry->data = data;
entry->ts = ev_time();
HASH_ADD_KEYPTR(hh, cache->entries, entry->key, key_len, entry);
if (HASH_COUNT(cache->entries) >= cache->max_entries) {
+9 -6
View File
@@ -29,6 +29,7 @@
#define _CACHE_
#include "uthash.h"
#include "ev.h"
/**
* A cache entry
@@ -36,6 +37,7 @@
struct cache_entry {
char *key; /**<The key */
void *data; /**<Payload */
ev_tstamp ts; /**<Timestamp */
UT_hash_handle hh; /**<Hash Handle for uthash */
};
@@ -48,12 +50,13 @@ struct cache {
void (*free_cb) (void *element); /**<Callback function to free cache entries */
};
extern int cache_create(struct cache **dst, const size_t capacity,
int cache_create(struct cache **dst, const size_t capacity,
void (*free_cb)(void *element));
extern int cache_delete(struct cache *cache, int keep_data);
extern int cache_lookup(struct cache *cache, char *key, size_t key_len, void *result);
extern int cache_insert(struct cache *cache, char *key, size_t key_len, void *data);
extern int cache_remove(struct cache *cache, char *key, size_t key_len);
extern int cache_key_exist(struct cache *cache, char *key, size_t key_len);
int cache_delete(struct cache *cache, int keep_data);
int cache_clear(struct cache *cache, ev_tstamp age);
int cache_lookup(struct cache *cache, char *key, size_t key_len, void *result);
int cache_insert(struct cache *cache, char *key, size_t key_len, void *data);
int cache_remove(struct cache *cache, char *key, size_t key_len);
int cache_key_exist(struct cache *cache, char *key, size_t key_len);
#endif
+3 -3
View File
@@ -1392,7 +1392,7 @@ enc_key_init(int method, const char *pass)
if (sodium_init() == -1) {
FATAL("Failed to initialize sodium");
}
if (method == SALSA20 || method == CHACHA20 || method == CHACHA20IETF) {
// Fake cipher
cipher = (cipher_kt_t *)&cipher_info;
@@ -1469,8 +1469,8 @@ enc_init(const char *pass, const char *method)
break;
}
if (m >= CIPHER_NUM) {
LOGE("Invalid cipher name: %s, use table instead", method);
m = TABLE;
LOGE("Invalid cipher name: %s, use rc4-md5 instead", method);
m = RC4_MD5;
}
}
if (m == TABLE) {
+1 -1
View File
@@ -1316,7 +1316,7 @@ main(int argc, char **argv)
}
if (method == NULL) {
method = "table";
method = "rc4-md5";
}
if (timeout == NULL) {
+4
View File
@@ -910,6 +910,10 @@ main(int argc, char **argv)
exit(EXIT_FAILURE);
}
if (method == NULL) {
method = "rc4-md5";
}
if (timeout == NULL) {
timeout = "60";
}
+13 -1
View File
@@ -91,6 +91,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents);
static void remote_recv_cb(EV_P_ ev_io *w, int revents);
static void remote_send_cb(EV_P_ ev_io *w, int revents);
static void server_timeout_cb(EV_P_ ev_timer *watcher, int revents);
static void block_list_clear_cb(EV_P_ ev_timer *watcher, int revents);
static remote_t *new_remote(int fd);
static server_t *new_server(int fd, listen_ctx_t *listener);
@@ -127,6 +128,7 @@ static char *manager_address = NULL;
uint64_t tx = 0;
uint64_t rx = 0;
ev_timer stat_update_watcher;
ev_timer block_list_watcher;
static struct cork_dllist connections;
@@ -974,6 +976,12 @@ server_send_cb(EV_P_ ev_io *w, int revents)
}
}
static void
block_list_clear_cb(EV_P_ ev_timer *watcher, int revents)
{
clear_block_list();
}
static void
server_timeout_cb(EV_P_ ev_timer *watcher, int revents)
{
@@ -1653,7 +1661,7 @@ main(int argc, char **argv)
}
if (method == NULL) {
method = "table";
method = "rc4-md5";
}
if (timeout == NULL) {
@@ -1793,6 +1801,9 @@ main(int argc, char **argv)
ev_timer_start(EV_DEFAULT, &stat_update_watcher);
}
ev_timer_init(&block_list_watcher, block_list_clear_cb, UPDATE_INTERVAL, UPDATE_INTERVAL);
ev_timer_start(EV_DEFAULT, &block_list_watcher);
// setuid
if (user != NULL) {
run_as(user);
@@ -1811,6 +1822,7 @@ main(int argc, char **argv)
if (manager_address != NULL) {
ev_timer_stop(EV_DEFAULT, &stat_update_watcher);
}
ev_timer_stop(EV_DEFAULT, &block_list_watcher);
// Clean up
for (int i = 0; i <= server_num; i++) {
+4
View File
@@ -909,6 +909,10 @@ main(int argc, char **argv)
exit(EXIT_FAILURE);
}
if (method == NULL) {
method = "rc4-md5";
}
if (timeout == NULL) {
timeout = "60";
}