From c5d2d867f120926c3946faa583c86c6cce15f895 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Wed, 24 Jul 2013 16:13:07 +0200 Subject: [PATCH] mem-pool: replace per-identity online/offline lists by more efficient arrays This saves two lists per connected peer identity, up to 0.4KB. --- src/libhydra/attributes/mem_pool.c | 100 +++++++++++++++-------------- 1 file changed, 52 insertions(+), 48 deletions(-) diff --git a/src/libhydra/attributes/mem_pool.c b/src/libhydra/attributes/mem_pool.c index 16a5b519cb..9b9bc93b5e 100644 --- a/src/libhydra/attributes/mem_pool.c +++ b/src/libhydra/attributes/mem_pool.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #define POOL_LIMIT (sizeof(u_int)*8 - 1) @@ -71,12 +71,27 @@ struct private_mem_pool_t { typedef struct { /* identitiy reference */ identification_t *id; - /* list of online leases, as offset */ - linked_list_t *online; - /* list of offline leases, as offset */ - linked_list_t *offline; + /* array of online leases, as u_int offset */ + array_t *online; + /* array of offline leases, as u_int offset */ + array_t *offline; } entry_t; +/** + * Create a new entry + */ +static entry_t* entry_create(identification_t *id) +{ + entry_t *entry; + + INIT(entry, + .id = id->clone(id), + .online = array_create(sizeof(u_int), 0), + .offline = array_create(sizeof(u_int), 0), + ); + return entry; +} + /** * hashtable hash function for identities */ @@ -185,7 +200,7 @@ METHOD(mem_pool_t, get_online, u_int, enumerator = this->leases->create_enumerator(this->leases); while (enumerator->enumerate(enumerator, NULL, &entry)) { - count += entry->online->get_count(entry->online); + count += array_count(entry->online); } enumerator->destroy(enumerator); this->mutex->unlock(this->mutex); @@ -204,7 +219,7 @@ METHOD(mem_pool_t, get_offline, u_int, enumerator = this->leases->create_enumerator(this->leases); while (enumerator->enumerate(enumerator, NULL, &entry)) { - count += entry->offline->get_count(entry->offline); + count += array_count(entry->offline); } enumerator->destroy(enumerator); this->mutex->unlock(this->mutex); @@ -219,7 +234,7 @@ static int get_existing(private_mem_pool_t *this, identification_t *id, host_t *requested) { enumerator_t *enumerator; - uintptr_t current; + u_int *current; entry_t *entry; int offset = 0; @@ -230,12 +245,12 @@ static int get_existing(private_mem_pool_t *this, identification_t *id, } /* check for a valid offline lease, refresh */ - enumerator = entry->offline->create_enumerator(entry->offline); + enumerator = array_create_enumerator(entry->offline); if (enumerator->enumerate(enumerator, ¤t)) { - entry->offline->remove_at(entry->offline, enumerator); - entry->online->insert_last(entry->online, (void*)current); - offset = current; + offset = *current; + array_insert(entry->online, ARRAY_TAIL, current); + array_remove_at(entry->offline, enumerator); } enumerator->destroy(enumerator); if (offset) @@ -245,14 +260,14 @@ static int get_existing(private_mem_pool_t *this, identification_t *id, } /* check for a valid online lease to reassign */ - enumerator = entry->online->create_enumerator(entry->online); + enumerator = array_create_enumerator(entry->online); while (enumerator->enumerate(enumerator, ¤t)) { - if (current == host2offset(this, requested)) + if (*current == host2offset(this, requested)) { - offset = current; + offset = *current; /* add an additional "online" entry */ - entry->online->insert_last(entry->online, (void*)current); + array_insert(entry->online, ARRAY_TAIL, current); break; } } @@ -270,23 +285,19 @@ static int get_existing(private_mem_pool_t *this, identification_t *id, static int get_new(private_mem_pool_t *this, identification_t *id) { entry_t *entry; - uintptr_t offset = 0; + u_int offset = 0; if (this->unused < this->size) { entry = this->leases->get(this->leases, id); if (!entry) { - INIT(entry, - .id = id->clone(id), - .online = linked_list_create(), - .offline = linked_list_create(), - ); + entry = entry_create(id); this->leases->put(this->leases, entry->id, entry); } /* assigning offset, starting by 1 */ offset = ++this->unused; - entry->online->insert_last(entry->online, (void*)offset); + array_insert(entry->online, ARRAY_TAIL, &offset); DBG1(DBG_CFG, "assigning new lease to '%Y'", id); } return offset; @@ -299,13 +310,12 @@ static int get_reassigned(private_mem_pool_t *this, identification_t *id) { enumerator_t *enumerator; entry_t *entry; - uintptr_t current, offset = 0; + u_int current, offset = 0; enumerator = this->leases->create_enumerator(this->leases); while (enumerator->enumerate(enumerator, NULL, &entry)) { - if (entry->offline->remove_first(entry->offline, - (void**)¤t) == SUCCESS) + if (array_remove(entry->offline, ARRAY_HEAD, ¤t)) { offset = current; DBG1(DBG_CFG, "reassigning existing offline lease by '%Y'" @@ -317,12 +327,8 @@ static int get_reassigned(private_mem_pool_t *this, identification_t *id) if (offset) { - INIT(entry, - .id = id->clone(id), - .online = linked_list_create(), - .offline = linked_list_create(), - ); - entry->online->insert_last(entry->online, (void*)offset); + entry = entry_create(id); + array_insert(entry->online, ARRAY_TAIL, &offset); this->leases->put(this->leases, entry->id, entry); } return offset; @@ -382,7 +388,7 @@ METHOD(mem_pool_t, release_address, bool, enumerator_t *enumerator; bool found = FALSE, more = FALSE; entry_t *entry; - uintptr_t offset, current; + u_int offset, *current; if (this->size != 0) { @@ -392,14 +398,14 @@ METHOD(mem_pool_t, release_address, bool, { offset = host2offset(this, address); - enumerator = entry->online->create_enumerator(entry->online); + enumerator = array_create_enumerator(entry->online); while (enumerator->enumerate(enumerator, ¤t)) { - if (current == offset) + if (*current == offset) { if (!found) { /* remove the first entry only */ - entry->online->remove_at(entry->online, enumerator); + array_remove_at(entry->online, enumerator); found = TRUE; } else @@ -414,7 +420,7 @@ METHOD(mem_pool_t, release_address, bool, if (found && !more) { /* no tunnels are online anymore for this lease, make offline */ - entry->offline->insert_last(entry->offline, (void*)offset); + array_insert(entry->offline, ARRAY_TAIL, &offset); DBG1(DBG_CFG, "lease %H by '%Y' went offline", address, id); } } @@ -446,7 +452,7 @@ typedef struct { METHOD(enumerator_t, lease_enumerate, bool, lease_enumerator_t *this, identification_t **id, host_t **addr, bool *online) { - uintptr_t offset; + u_int *offset; DESTROY_IF(this->addr); this->addr = NULL; @@ -455,17 +461,17 @@ METHOD(enumerator_t, lease_enumerate, bool, { if (this->entry) { - if (this->online->enumerate(this->online, (void**)&offset)) + if (this->online->enumerate(this->online, &offset)) { *id = this->entry->id; - *addr = this->addr = offset2host(this->pool, offset); + *addr = this->addr = offset2host(this->pool, *offset); *online = TRUE; return TRUE; } - if (this->offline->enumerate(this->offline, (void**)&offset)) + if (this->offline->enumerate(this->offline, &offset)) { *id = this->entry->id; - *addr = this->addr = offset2host(this->pool, offset); + *addr = this->addr = offset2host(this->pool, *offset); *online = FALSE; return TRUE; } @@ -477,10 +483,8 @@ METHOD(enumerator_t, lease_enumerate, bool, { return FALSE; } - this->online = this->entry->online->create_enumerator( - this->entry->online); - this->offline = this->entry->offline->create_enumerator( - this->entry->offline); + this->online = array_create_enumerator(this->entry->online); + this->offline = array_create_enumerator(this->entry->offline); } } @@ -522,8 +526,8 @@ METHOD(mem_pool_t, destroy, void, while (enumerator->enumerate(enumerator, NULL, &entry)) { entry->id->destroy(entry->id); - entry->online->destroy(entry->online); - entry->offline->destroy(entry->offline); + array_destroy(entry->online); + array_destroy(entry->offline); free(entry); } enumerator->destroy(enumerator); -- 2.47.2