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:
Michal Schmidt
2014-09-15 16:08:50 +02:00
parent f44541bc93
commit d5099efc47
82 changed files with 278 additions and 226 deletions
+1 -1
View File
@@ -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;
+5
View File
@@ -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;
+1
View File
@@ -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);
+1 -3
View File
@@ -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;
+2 -2
View File
@@ -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;
+7 -2
View File
@@ -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;
+2 -2
View File
@@ -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;
+1 -1
View File
@@ -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;
+7 -2
View File
@@ -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
};
+1 -2
View File
@@ -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;
+1 -1
View File
@@ -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;
+3 -3
View File
@@ -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;
+1 -1
View File
@@ -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;
+2 -2
View File
@@ -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;