dns_cache: optimize insertion performance

This commit is contained in:
Nick Peng
2023-09-12 21:49:03 +08:00
parent 1a492f7dc0
commit 875100f5c1

View File

@@ -40,6 +40,7 @@ struct dns_cache_head {
int enable_inactive; int enable_inactive;
int inactive_list_expired; int inactive_list_expired;
pthread_mutex_t lock; pthread_mutex_t lock;
struct dns_cache *last_active_inserted;
}; };
typedef int (*dns_cache_read_callback)(struct dns_cache_record *cache_record, struct dns_cache_data *cache_data); typedef int (*dns_cache_read_callback)(struct dns_cache_record *cache_record, struct dns_cache_data *cache_data);
@@ -64,6 +65,7 @@ int dns_cache_init(int size, int enable_inactive, int inactive_list_expired)
dns_cache_head.size = size; dns_cache_head.size = size;
dns_cache_head.enable_inactive = enable_inactive; dns_cache_head.enable_inactive = enable_inactive;
dns_cache_head.inactive_list_expired = inactive_list_expired; dns_cache_head.inactive_list_expired = inactive_list_expired;
dns_cache_head.last_active_inserted = NULL;
pthread_mutex_init(&dns_cache_head.lock, NULL); pthread_mutex_init(&dns_cache_head.lock, NULL);
return 0; return 0;
@@ -127,12 +129,21 @@ static void _dns_cache_remove(struct dns_cache *dns_cache)
hash_del(&dns_cache->node); hash_del(&dns_cache->node);
list_del_init(&dns_cache->list); list_del_init(&dns_cache->list);
dns_cache_release(dns_cache); dns_cache_release(dns_cache);
if (dns_cache == dns_cache_head.last_active_inserted) {
dns_cache_release(dns_cache_head.last_active_inserted);
dns_cache_head.last_active_inserted = NULL;
}
} }
static void _dns_cache_move_inactive(struct dns_cache *dns_cache) static void _dns_cache_move_inactive(struct dns_cache *dns_cache)
{ {
list_del(&dns_cache->list); list_del(&dns_cache->list);
list_add_tail(&dns_cache->list, &dns_cache_head.inactive_list); list_add_tail(&dns_cache->list, &dns_cache_head.inactive_list);
if (dns_cache == dns_cache_head.last_active_inserted) {
dns_cache_release(dns_cache_head.last_active_inserted);
dns_cache_head.last_active_inserted = NULL;
}
time(&dns_cache->info.replace_time); time(&dns_cache->info.replace_time);
} }
@@ -264,18 +275,35 @@ static void _dns_cache_insert_sorted(struct dns_cache *dns_cache, struct list_he
{ {
time_t ttl; time_t ttl;
struct dns_cache *tmp = NULL; struct dns_cache *tmp = NULL;
struct list_head *insert_head = head;
if (dns_cache_head.last_active_inserted && dns_cache != dns_cache_head.last_active_inserted) {
if (dns_cache_head.last_active_inserted->info.ttl == dns_cache->info.ttl) {
insert_head = &(dns_cache_head.last_active_inserted->list);
goto out;
} else if (dns_cache_head.last_active_inserted->info.ttl > dns_cache->info.ttl) {
head = &(dns_cache_head.last_active_inserted->list);
insert_head = head;
}
}
/* ascending order */ /* ascending order */
ttl = dns_cache->info.insert_time + dns_cache->info.ttl; ttl = dns_cache->info.insert_time + dns_cache->info.ttl;
list_for_each_entry_reverse(tmp, head, list) list_for_each_entry_reverse(tmp, head, list)
{ {
if ((tmp->info.insert_time + tmp->info.ttl) <= ttl) { if ((tmp->info.insert_time + tmp->info.ttl) <= ttl) {
list_add(&dns_cache->list, &tmp->list); insert_head = &tmp->list;
return; break;
} }
} }
list_add(&dns_cache->list, head); out:
if (dns_cache_head.last_active_inserted) {
dns_cache_release(dns_cache_head.last_active_inserted);
}
list_add(&dns_cache->list, insert_head);
dns_cache_head.last_active_inserted = dns_cache;
dns_cache_get(dns_cache);
} }
static int _dns_cache_replace(struct dns_cache_key *cache_key, int ttl, int speed, int no_inactive, int inactive, static int _dns_cache_replace(struct dns_cache_key *cache_key, int ttl, int speed, int no_inactive, int inactive,
@@ -1034,6 +1062,11 @@ void dns_cache_destroy(void)
struct dns_cache *dns_cache = NULL; struct dns_cache *dns_cache = NULL;
struct dns_cache *tmp = NULL; struct dns_cache *tmp = NULL;
if (dns_cache_head.last_active_inserted) {
dns_cache_release(dns_cache_head.last_active_inserted);
dns_cache_head.last_active_inserted = NULL;
}
pthread_mutex_lock(&dns_cache_head.lock); pthread_mutex_lock(&dns_cache_head.lock);
list_for_each_entry_safe(dns_cache, tmp, &dns_cache_head.inactive_list, list) list_for_each_entry_safe(dns_cache, tmp, &dns_cache_head.inactive_list, list)
{ {