From a45854b5d8dc699e68c5b538e299d5ef8fda59f3 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 21 Oct 2012 01:28:33 +0200 Subject: Aggregate similar updates --- ffd/update.c | 51 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 17 deletions(-) (limited to 'ffd/update.c') diff --git a/ffd/update.c b/ffd/update.c index 5ae3006..d273fec 100644 --- a/ffd/update.c +++ b/ffd/update.c @@ -35,18 +35,18 @@ static ffd_queue_t *pending_updates = NULL; -typedef struct _update_arg { +typedef struct _update_arg_t { ffd_node_id_t node; uint16_t type; uint16_t key; ffd_neigh_t *neigh; unsigned ref; -} update_arg; +} update_arg_t; -static inline update_arg* update_new(const ffd_node_id_t *node, uint16_t type, uint16_t key, ffd_neigh_t *neigh) { - update_arg *arg = malloc(sizeof(update_arg)); +static inline update_arg_t* update_new(const ffd_node_id_t *node, uint16_t type, uint16_t key, ffd_neigh_t *neigh) { + update_arg_t *arg = malloc(sizeof(update_arg_t)); arg->node = *node; arg->type = type; @@ -61,12 +61,12 @@ static inline update_arg* update_new(const ffd_node_id_t *node, uint16_t type, u return arg; } -static inline update_arg* update_ref(update_arg *arg) { +static inline update_arg_t* update_ref(update_arg_t *arg) { arg->ref++; return arg; } -static inline void update_unref(update_arg *arg) { +static inline void update_unref(update_arg_t *arg) { if (!--arg->ref) { if (arg->neigh) ffd_neigh_unref(arg->neigh); @@ -79,7 +79,7 @@ void ffd_update_enqueue(const ffd_node_id_t *node, uint16_t type, uint16_t key, if (neigh) ffd_neigh_ref(neigh); - update_arg *arg = update_new(node, type, key, neigh); + update_arg_t *arg = update_new(node, type, key, neigh); if (urgent) { ffd_queue_put_delayed(&pending_updates, NULL, &now, FFD_URGENT_DELAY, update_ref(arg)); @@ -99,19 +99,36 @@ int ffd_update_timeout(void) { void ffd_update_run(void) { while (!ffd_update_timeout()) { - update_arg *arg = pending_updates->arg; + ffd_neigh_t *neigh = ((update_arg_t*)pending_updates->arg)->neigh; - ffd_neigh_t *neigh = arg->neigh; - ffd_announce_t *announce = ffd_announce_find(&arg->node, arg->type, arg->key); + ffd_update_t *update = ffd_send_update_new(NULL, neigh); - fprintf(stderr, "debug: sending scheduled update.\n"); + fprintf(stderr, "debug: sending scheduled updates.\n"); - if (announce) - ffd_send_update(NULL, neigh, announce, false); - else - ffd_send_retract(neigh, arg->node, arg->type, arg->key); + ffd_queue_t **entry; + for (entry = &pending_updates; *entry;) { + update_arg_t *arg = (*entry)->arg; - update_unref(arg); - ffd_queue_drop(&pending_updates); + if (arg->neigh != neigh) { + entry = &(*entry)->next; + continue; + } + + ffd_announce_t *announce = ffd_announce_find(&arg->node, arg->type, arg->key); + bool ret; + + if (announce) + ret = ffd_send_update_add(update, announce); + else + ret = ffd_send_update_retract(update, arg->node, arg->type, arg->key); + + if (!ret) + break; + + update_unref(arg); + ffd_queue_drop(entry); + } + + ffd_send_update_finish(update); } } -- cgit v1.2.3