hashmap: introduce hash_ops to make struct Hashmap smaller
It is redundant to store 'hash' and 'compare' function pointers in struct Hashmap separately. The functions always comprise a pair. Store a single pointer to struct hash_ops instead. systemd keeps hundreds of hashmaps, so this saves a little bit of memory.
This commit is contained in:
@@ -186,7 +186,7 @@ static int dns_cache_init(DnsCache *c) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_ensure_allocated(&c->by_key, dns_resource_key_hash_func, dns_resource_key_compare_func);
|
||||
r = hashmap_ensure_allocated(&c->by_key, &dns_resource_key_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -371,6 +371,11 @@ int dns_name_compare_func(const void *a, const void *b) {
|
||||
}
|
||||
}
|
||||
|
||||
const struct hash_ops dns_name_hash_ops = {
|
||||
.hash = dns_name_hash_func,
|
||||
.compare = dns_name_compare_func
|
||||
};
|
||||
|
||||
int dns_name_equal(const char *x, const char *y) {
|
||||
int r, q, k, w;
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ int dns_name_normalize(const char *s, char **_ret);
|
||||
|
||||
unsigned long dns_name_hash_func(const void *s, const uint8_t hash_key[HASH_KEY_SIZE]);
|
||||
int dns_name_compare_func(const void *a, const void *b);
|
||||
extern const struct hash_ops dns_name_hash_ops;
|
||||
|
||||
int dns_name_equal(const char *x, const char *y);
|
||||
int dns_name_endswith(const char *name, const char *suffix);
|
||||
|
||||
@@ -433,9 +433,7 @@ int dns_packet_append_name(DnsPacket *p, const char *name,
|
||||
goto fail;
|
||||
|
||||
if (allow_compression) {
|
||||
r = hashmap_ensure_allocated(&p->names,
|
||||
dns_name_hash_func,
|
||||
dns_name_compare_func);
|
||||
r = hashmap_ensure_allocated(&p->names, &dns_name_hash_ops);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ static int dns_query_add_transaction(DnsQuery *q, DnsScope *s, DnsResourceKey *k
|
||||
assert(q);
|
||||
assert(s);
|
||||
|
||||
r = set_ensure_allocated(&q->transactions, NULL, NULL);
|
||||
r = set_ensure_allocated(&q->transactions, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -166,7 +166,7 @@ static int dns_query_add_transaction(DnsQuery *q, DnsScope *s, DnsResourceKey *k
|
||||
return r;
|
||||
}
|
||||
|
||||
r = set_ensure_allocated(&t->queries, NULL, NULL);
|
||||
r = set_ensure_allocated(&t->queries, NULL);
|
||||
if (r < 0)
|
||||
goto gc;
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ int dns_resource_key_match_cname(const DnsResourceKey *key, const DnsResourceRec
|
||||
return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
|
||||
}
|
||||
|
||||
unsigned long dns_resource_key_hash_func(const void *i, const uint8_t hash_key[HASH_KEY_SIZE]) {
|
||||
static unsigned long dns_resource_key_hash_func(const void *i, const uint8_t hash_key[HASH_KEY_SIZE]) {
|
||||
const DnsResourceKey *k = i;
|
||||
unsigned long ul;
|
||||
|
||||
@@ -144,7 +144,7 @@ unsigned long dns_resource_key_hash_func(const void *i, const uint8_t hash_key[H
|
||||
return ul;
|
||||
}
|
||||
|
||||
int dns_resource_key_compare_func(const void *a, const void *b) {
|
||||
static int dns_resource_key_compare_func(const void *a, const void *b) {
|
||||
const DnsResourceKey *x = a, *y = b;
|
||||
int ret;
|
||||
|
||||
@@ -165,6 +165,11 @@ int dns_resource_key_compare_func(const void *a, const void *b) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct hash_ops dns_resource_key_hash_ops = {
|
||||
.hash = dns_resource_key_hash_func,
|
||||
.compare = dns_resource_key_compare_func
|
||||
};
|
||||
|
||||
int dns_resource_key_to_string(const DnsResourceKey *key, char **ret) {
|
||||
char cbuf[DECIMAL_STR_MAX(uint16_t)], tbuf[DECIMAL_STR_MAX(uint16_t)];
|
||||
const char *c, *t;
|
||||
|
||||
@@ -159,8 +159,6 @@ DnsResourceKey* dns_resource_key_unref(DnsResourceKey *key);
|
||||
int dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b);
|
||||
int dns_resource_key_match_rr(const DnsResourceKey *key, const DnsResourceRecord *rr);
|
||||
int dns_resource_key_match_cname(const DnsResourceKey *key, const DnsResourceRecord *rr);
|
||||
unsigned long dns_resource_key_hash_func(const void *i, const uint8_t hash_key[HASH_KEY_SIZE]);
|
||||
int dns_resource_key_compare_func(const void *a, const void *b);
|
||||
int dns_resource_key_to_string(const DnsResourceKey *key, char **ret);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceKey*, dns_resource_key_unref);
|
||||
|
||||
@@ -175,3 +173,5 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceRecord*, dns_resource_record_unref);
|
||||
|
||||
const char *dns_class_to_string(uint16_t type);
|
||||
int dns_class_from_string(const char *name, uint16_t *class);
|
||||
|
||||
extern const struct hash_ops dns_resource_key_hash_ops;
|
||||
|
||||
@@ -709,7 +709,7 @@ int dns_scope_notify_conflict(DnsScope *scope, DnsResourceRecord *rr) {
|
||||
|
||||
/* We don't send these queries immediately. Instead, we queue
|
||||
* them, and send them after some jitter delay. */
|
||||
r = hashmap_ensure_allocated(&scope->conflict_queue, dns_resource_key_hash_func, dns_resource_key_compare_func);
|
||||
r = hashmap_ensure_allocated(&scope->conflict_queue, &dns_resource_key_hash_ops);
|
||||
if (r < 0) {
|
||||
log_oom();
|
||||
return r;
|
||||
|
||||
@@ -100,7 +100,7 @@ DnsServer* dns_server_free(DnsServer *s) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned long dns_server_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) {
|
||||
static unsigned long dns_server_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) {
|
||||
const DnsServer *s = p;
|
||||
uint64_t u;
|
||||
|
||||
@@ -110,7 +110,7 @@ unsigned long dns_server_hash_func(const void *p, const uint8_t hash_key[HASH_KE
|
||||
return u;
|
||||
}
|
||||
|
||||
int dns_server_compare_func(const void *a, const void *b) {
|
||||
static int dns_server_compare_func(const void *a, const void *b) {
|
||||
const DnsServer *x = a, *y = b;
|
||||
|
||||
if (x->family < y->family)
|
||||
@@ -120,3 +120,8 @@ int dns_server_compare_func(const void *a, const void *b) {
|
||||
|
||||
return memcmp(&x->address, &y->address, FAMILY_ADDRESS_SIZE(x->family));
|
||||
}
|
||||
|
||||
const struct hash_ops dns_server_hash_ops = {
|
||||
.hash = dns_server_hash_func,
|
||||
.compare = dns_server_compare_func
|
||||
};
|
||||
|
||||
@@ -60,5 +60,4 @@ int dns_server_new(
|
||||
|
||||
DnsServer* dns_server_free(DnsServer *s);
|
||||
|
||||
unsigned long dns_server_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]);
|
||||
int dns_server_compare_func(const void *a, const void *b);
|
||||
extern const struct hash_ops dns_server_hash_ops;
|
||||
|
||||
@@ -78,7 +78,7 @@ int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsQuestion *q) {
|
||||
assert(s);
|
||||
assert(q);
|
||||
|
||||
r = hashmap_ensure_allocated(&s->manager->dns_transactions, NULL, NULL);
|
||||
r = hashmap_ensure_allocated(&s->manager->dns_transactions, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -126,11 +126,11 @@ static int dns_zone_init(DnsZone *z) {
|
||||
|
||||
assert(z);
|
||||
|
||||
r = hashmap_ensure_allocated(&z->by_key, dns_resource_key_hash_func, dns_resource_key_compare_func);
|
||||
r = hashmap_ensure_allocated(&z->by_key, &dns_resource_key_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_ensure_allocated(&z->by_name, dns_name_hash_func, dns_name_compare_func);
|
||||
r = hashmap_ensure_allocated(&z->by_name, &dns_name_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -194,7 +194,7 @@ static int dns_zone_item_probe_start(DnsZoneItem *i) {
|
||||
return r;
|
||||
}
|
||||
|
||||
r = set_ensure_allocated(&t->zone_items, NULL, NULL);
|
||||
r = set_ensure_allocated(&t->zone_items, NULL);
|
||||
if (r < 0)
|
||||
goto gc;
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ int link_new(Manager *m, Link **ret, int ifindex) {
|
||||
assert(m);
|
||||
assert(ifindex > 0);
|
||||
|
||||
r = hashmap_ensure_allocated(&m->links, NULL, NULL);
|
||||
r = hashmap_ensure_allocated(&m->links, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -737,11 +737,11 @@ int manager_write_resolv_conf(Manager *m) {
|
||||
manager_read_resolv_conf(m);
|
||||
|
||||
/* Add the full list to a set, to filter out duplicates */
|
||||
dns = set_new(dns_server_hash_func, dns_server_compare_func);
|
||||
dns = set_new(&dns_server_hash_ops);
|
||||
if (!dns)
|
||||
return -ENOMEM;
|
||||
|
||||
domains = set_new(dns_name_hash_func, dns_name_compare_func);
|
||||
domains = set_new(&dns_name_hash_ops);
|
||||
if (!domains)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user