mem-pool: replace per-identity online/offline lists by more efficient arrays

This saves two lists per connected peer identity, up to 0.4KB.
This commit is contained in:
Martin Willi
2013-07-29 08:55:21 +02:00
parent d882880e87
commit c5d2d867f1
+52 -48
View File
@@ -18,7 +18,7 @@
#include <utils/debug.h> #include <utils/debug.h>
#include <collections/hashtable.h> #include <collections/hashtable.h>
#include <collections/linked_list.h> #include <collections/array.h>
#include <threading/mutex.h> #include <threading/mutex.h>
#define POOL_LIMIT (sizeof(u_int)*8 - 1) #define POOL_LIMIT (sizeof(u_int)*8 - 1)
@@ -71,12 +71,27 @@ struct private_mem_pool_t {
typedef struct { typedef struct {
/* identitiy reference */ /* identitiy reference */
identification_t *id; identification_t *id;
/* list of online leases, as offset */ /* array of online leases, as u_int offset */
linked_list_t *online; array_t *online;
/* list of offline leases, as offset */ /* array of offline leases, as u_int offset */
linked_list_t *offline; array_t *offline;
} entry_t; } 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 * hashtable hash function for identities
*/ */
@@ -185,7 +200,7 @@ METHOD(mem_pool_t, get_online, u_int,
enumerator = this->leases->create_enumerator(this->leases); enumerator = this->leases->create_enumerator(this->leases);
while (enumerator->enumerate(enumerator, NULL, &entry)) while (enumerator->enumerate(enumerator, NULL, &entry))
{ {
count += entry->online->get_count(entry->online); count += array_count(entry->online);
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
this->mutex->unlock(this->mutex); this->mutex->unlock(this->mutex);
@@ -204,7 +219,7 @@ METHOD(mem_pool_t, get_offline, u_int,
enumerator = this->leases->create_enumerator(this->leases); enumerator = this->leases->create_enumerator(this->leases);
while (enumerator->enumerate(enumerator, NULL, &entry)) while (enumerator->enumerate(enumerator, NULL, &entry))
{ {
count += entry->offline->get_count(entry->offline); count += array_count(entry->offline);
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
this->mutex->unlock(this->mutex); this->mutex->unlock(this->mutex);
@@ -219,7 +234,7 @@ static int get_existing(private_mem_pool_t *this, identification_t *id,
host_t *requested) host_t *requested)
{ {
enumerator_t *enumerator; enumerator_t *enumerator;
uintptr_t current; u_int *current;
entry_t *entry; entry_t *entry;
int offset = 0; 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 */ /* check for a valid offline lease, refresh */
enumerator = entry->offline->create_enumerator(entry->offline); enumerator = array_create_enumerator(entry->offline);
if (enumerator->enumerate(enumerator, &current)) if (enumerator->enumerate(enumerator, &current))
{ {
entry->offline->remove_at(entry->offline, enumerator); offset = *current;
entry->online->insert_last(entry->online, (void*)current); array_insert(entry->online, ARRAY_TAIL, current);
offset = current; array_remove_at(entry->offline, enumerator);
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
if (offset) 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 */ /* 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, &current)) while (enumerator->enumerate(enumerator, &current))
{ {
if (current == host2offset(this, requested)) if (*current == host2offset(this, requested))
{ {
offset = current; offset = *current;
/* add an additional "online" entry */ /* add an additional "online" entry */
entry->online->insert_last(entry->online, (void*)current); array_insert(entry->online, ARRAY_TAIL, current);
break; 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) static int get_new(private_mem_pool_t *this, identification_t *id)
{ {
entry_t *entry; entry_t *entry;
uintptr_t offset = 0; u_int offset = 0;
if (this->unused < this->size) if (this->unused < this->size)
{ {
entry = this->leases->get(this->leases, id); entry = this->leases->get(this->leases, id);
if (!entry) if (!entry)
{ {
INIT(entry, entry = entry_create(id);
.id = id->clone(id),
.online = linked_list_create(),
.offline = linked_list_create(),
);
this->leases->put(this->leases, entry->id, entry); this->leases->put(this->leases, entry->id, entry);
} }
/* assigning offset, starting by 1 */ /* assigning offset, starting by 1 */
offset = ++this->unused; 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); DBG1(DBG_CFG, "assigning new lease to '%Y'", id);
} }
return offset; return offset;
@@ -299,13 +310,12 @@ static int get_reassigned(private_mem_pool_t *this, identification_t *id)
{ {
enumerator_t *enumerator; enumerator_t *enumerator;
entry_t *entry; entry_t *entry;
uintptr_t current, offset = 0; u_int current, offset = 0;
enumerator = this->leases->create_enumerator(this->leases); enumerator = this->leases->create_enumerator(this->leases);
while (enumerator->enumerate(enumerator, NULL, &entry)) while (enumerator->enumerate(enumerator, NULL, &entry))
{ {
if (entry->offline->remove_first(entry->offline, if (array_remove(entry->offline, ARRAY_HEAD, &current))
(void**)&current) == SUCCESS)
{ {
offset = current; offset = current;
DBG1(DBG_CFG, "reassigning existing offline lease by '%Y'" 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) if (offset)
{ {
INIT(entry, entry = entry_create(id);
.id = id->clone(id), array_insert(entry->online, ARRAY_TAIL, &offset);
.online = linked_list_create(),
.offline = linked_list_create(),
);
entry->online->insert_last(entry->online, (void*)offset);
this->leases->put(this->leases, entry->id, entry); this->leases->put(this->leases, entry->id, entry);
} }
return offset; return offset;
@@ -382,7 +388,7 @@ METHOD(mem_pool_t, release_address, bool,
enumerator_t *enumerator; enumerator_t *enumerator;
bool found = FALSE, more = FALSE; bool found = FALSE, more = FALSE;
entry_t *entry; entry_t *entry;
uintptr_t offset, current; u_int offset, *current;
if (this->size != 0) if (this->size != 0)
{ {
@@ -392,14 +398,14 @@ METHOD(mem_pool_t, release_address, bool,
{ {
offset = host2offset(this, address); offset = host2offset(this, address);
enumerator = entry->online->create_enumerator(entry->online); enumerator = array_create_enumerator(entry->online);
while (enumerator->enumerate(enumerator, &current)) while (enumerator->enumerate(enumerator, &current))
{ {
if (current == offset) if (*current == offset)
{ {
if (!found) if (!found)
{ /* remove the first entry only */ { /* remove the first entry only */
entry->online->remove_at(entry->online, enumerator); array_remove_at(entry->online, enumerator);
found = TRUE; found = TRUE;
} }
else else
@@ -414,7 +420,7 @@ METHOD(mem_pool_t, release_address, bool,
if (found && !more) if (found && !more)
{ {
/* no tunnels are online anymore for this lease, make offline */ /* 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); DBG1(DBG_CFG, "lease %H by '%Y' went offline", address, id);
} }
} }
@@ -446,7 +452,7 @@ typedef struct {
METHOD(enumerator_t, lease_enumerate, bool, METHOD(enumerator_t, lease_enumerate, bool,
lease_enumerator_t *this, identification_t **id, host_t **addr, bool *online) lease_enumerator_t *this, identification_t **id, host_t **addr, bool *online)
{ {
uintptr_t offset; u_int *offset;
DESTROY_IF(this->addr); DESTROY_IF(this->addr);
this->addr = NULL; this->addr = NULL;
@@ -455,17 +461,17 @@ METHOD(enumerator_t, lease_enumerate, bool,
{ {
if (this->entry) if (this->entry)
{ {
if (this->online->enumerate(this->online, (void**)&offset)) if (this->online->enumerate(this->online, &offset))
{ {
*id = this->entry->id; *id = this->entry->id;
*addr = this->addr = offset2host(this->pool, offset); *addr = this->addr = offset2host(this->pool, *offset);
*online = TRUE; *online = TRUE;
return TRUE; return TRUE;
} }
if (this->offline->enumerate(this->offline, (void**)&offset)) if (this->offline->enumerate(this->offline, &offset))
{ {
*id = this->entry->id; *id = this->entry->id;
*addr = this->addr = offset2host(this->pool, offset); *addr = this->addr = offset2host(this->pool, *offset);
*online = FALSE; *online = FALSE;
return TRUE; return TRUE;
} }
@@ -477,10 +483,8 @@ METHOD(enumerator_t, lease_enumerate, bool,
{ {
return FALSE; return FALSE;
} }
this->online = this->entry->online->create_enumerator( this->online = array_create_enumerator(this->entry->online);
this->entry->online); this->offline = array_create_enumerator(this->entry->offline);
this->offline = this->entry->offline->create_enumerator(
this->entry->offline);
} }
} }
@@ -522,8 +526,8 @@ METHOD(mem_pool_t, destroy, void,
while (enumerator->enumerate(enumerator, NULL, &entry)) while (enumerator->enumerate(enumerator, NULL, &entry))
{ {
entry->id->destroy(entry->id); entry->id->destroy(entry->id);
entry->online->destroy(entry->online); array_destroy(entry->online);
entry->offline->destroy(entry->offline); array_destroy(entry->offline);
free(entry); free(entry);
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);