From 76393615c3bd7443bb41a1f1054b798b8c4a1117 Mon Sep 17 00:00:00 2001 From: Matthias Wachs Date: Wed, 18 Jan 2012 14:42:15 +0000 Subject: [PATCH] - functionality for "for all peers" constraints --- src/ats/gnunet-service-ats_addresses.c | 4 +- src/ats/gnunet-service-ats_addresses.h | 4 ++ src/ats/gnunet-service-ats_addresses_mlp.c | 79 +++++++++++++++++++--- src/ats/gnunet-service-ats_addresses_mlp.h | 14 ++++ src/ats/test_ats_mlp.c | 14 +++- 5 files changed, 104 insertions(+), 11 deletions(-) diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c index 06eee9fb3..ae78858e6 100644 --- a/src/ats/gnunet-service-ats_addresses.c +++ b/src/ats/gnunet-service-ats_addresses.c @@ -154,7 +154,9 @@ create_address (const struct GNUNET_PeerIdentity *peer, memcpy (&aa[1], plugin_addr, plugin_addr_len); aa->plugin = GNUNET_strdup (plugin_name); aa->session_id = session_id; - + aa->mlp_information = NULL; + aa->next = NULL; + aa->prev = NULL; return aa; } diff --git a/src/ats/gnunet-service-ats_addresses.h b/src/ats/gnunet-service-ats_addresses.h index a5230b4f3..33ff5869d 100644 --- a/src/ats/gnunet-service-ats_addresses.h +++ b/src/ats/gnunet-service-ats_addresses.h @@ -34,6 +34,10 @@ struct ATS_Address { + struct ATS_Address *next; + + struct ATS_Address *prev; + struct GNUNET_PeerIdentity peer; size_t addr_len; diff --git a/src/ats/gnunet-service-ats_addresses_mlp.c b/src/ats/gnunet-service-ats_addresses_mlp.c index c3a7cfb5c..3899e126a 100644 --- a/src/ats/gnunet-service-ats_addresses_mlp.c +++ b/src/ats/gnunet-service-ats_addresses_mlp.c @@ -34,7 +34,7 @@ #endif #include "float.h" -#define DEBUG_ATS GNUNET_YES +#define DEBUG_ATS GNUNET_NO /* A very big value */ #define M DBL_MAX @@ -325,12 +325,14 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON double *ar= GNUNET_malloc (pi * sizeof (double)); mlp->ar = ar; - /* Adding constraint rows */ - /* Feasibility constraints */ - - /* c 1) bandwidth capping */ - /* c 3) minimum bandwidth */ - /* c 4) minimum number of connections */ + /* Adding constraint rows + * This constraints are kind of "for all addresses" + * Feasibility constraints: + * + * c 1) bandwidth capping + * c 3) minimum bandwidth + * c 4) minimum number of connections + */ mlp->r_c4 = glp_add_rows (mlp->prob, 1); glp_set_row_bnds (mlp->prob, mlp->r_c4, GLP_LO, mlp->n_min, 0.0); @@ -811,6 +813,37 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult address->mlp_information = mlpi; mlp->addr_in_problem ++; + /* Check for and add peer */ + struct ATS_Peer *peer = mlp->peer_head; + while (peer != NULL) + { + if (0 == memcmp (&address->peer, &peer->id, sizeof (struct GNUNET_PeerIdentity))) + break; + peer = peer->next; + } + if (peer == NULL) + { +#if DEBUG_ATS + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Adding new peer `%s'\n", GNUNET_i2s (&address->peer)); +#endif + peer = GNUNET_malloc (sizeof (struct ATS_Peer)); + peer->head = NULL; + peer->tail = NULL; + memcpy (&peer->id, &address->peer, sizeof (struct GNUNET_PeerIdentity)); + GNUNET_assert(address->prev == NULL); + GNUNET_assert(address->next == NULL); + GNUNET_CONTAINER_DLL_insert (peer->head, peer->tail, address); + GNUNET_CONTAINER_DLL_insert (mlp->peer_head, mlp->peer_tail, peer); + } + else + { +#if DEBUG_ATS + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Adding address to peer `%s'\n", GNUNET_i2s (&address->peer)); +#endif + GNUNET_CONTAINER_DLL_insert (peer->head, peer->tail, address); + } + + /* Add bandwidth column */ col = glp_add_cols (mlp->prob, 2); mlpi->c_b = col; @@ -836,8 +869,12 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult glp_set_col_kind (mlp->prob, mlpi->c_n, GLP_IV); /* Objective function coefficient == 0 */ glp_set_obj_coef (mlp->prob, mlpi->c_n, 0); - - /* Add */ + } + else + { +#if DEBUG_ATS + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating existing address to peer `%s'\n", GNUNET_i2s (&address->peer)); +#endif } /* Recalculate */ @@ -869,6 +906,30 @@ GAS_mlp_address_delete (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult mlp->addr_in_problem --; } + /* Remove from peer list */ + struct ATS_Peer *head = mlp->peer_head; + while (head != NULL) + { + if (0 == memcmp (&address->peer, &head->id, sizeof (struct GNUNET_PeerIdentity))) + break; + head = head->next; + } + GNUNET_assert (head != NULL); +#if DEBUG_ATS + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Deleting address for `%s'\n", GNUNET_i2s (&address->peer)); +#endif + GNUNET_CONTAINER_DLL_remove (head->head, head->tail, address); + + if ((head->head == NULL) && (head->tail == NULL)) + { + /* No address for peer left, remove peer */ +#if DEBUG_ATS + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Deleting peer `%s'\n", GNUNET_i2s (&address->peer)); +#endif + GNUNET_CONTAINER_DLL_remove (mlp->peer_head, mlp->peer_tail, head); + GNUNET_free (head); + } + /* Update problem */ /* Recalculate */ diff --git a/src/ats/gnunet-service-ats_addresses_mlp.h b/src/ats/gnunet-service-ats_addresses_mlp.h index 3878b0f5f..2383f24ef 100644 --- a/src/ats/gnunet-service-ats_addresses_mlp.h +++ b/src/ats/gnunet-service-ats_addresses_mlp.h @@ -40,6 +40,17 @@ #define MLP_MAX_EXEC_DURATION GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3) #define MLP_MAX_ITERATIONS INT_MAX +struct ATS_Peer +{ + struct ATS_Peer *next; + struct ATS_Peer *prev; + + struct GNUNET_PeerIdentity id; + + struct ATS_Address *head; + struct ATS_Address *tail; +}; + /** * MLP Handle */ @@ -135,6 +146,9 @@ struct GAS_MLP_Handle /* Information about the problem */ + struct ATS_Peer *peer_head; + struct ATS_Peer *peer_tail; + /* current problem matrix */ /* row index array */ int *ia; diff --git a/src/ats/test_ats_mlp.c b/src/ats/test_ats_mlp.c index 48916d2d9..94009ee4e 100644 --- a/src/ats/test_ats_mlp.c +++ b/src/ats/test_ats_mlp.c @@ -60,14 +60,26 @@ check (void *cls, char *const *args, const char *cfgfile, addresses = GNUNET_CONTAINER_multihashmap_create (10); GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_WEAK, &addr.peer.hashPubKey); + addr.mlp_information = NULL; + addr.next = NULL; + addr.prev = NULL; addr.plugin = strdup ("dummy"); GNUNET_CONTAINER_multihashmap_put(addresses, &addr.peer.hashPubKey, &addr, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); mlp = GAS_mlp_init (cfg, NULL, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS); - GAS_mlp_address_update(mlp, addresses, &addr); + /* Add a new address */ + GAS_mlp_address_update (mlp, addresses, &addr); GNUNET_assert (mlp != NULL); + GNUNET_assert (mlp->addr_in_problem == 1); + + /* Update an new address */ + GAS_mlp_address_update (mlp, addresses, &addr); + GNUNET_assert (mlp->addr_in_problem == 1); + + /* Delete an address */ + GAS_mlp_address_delete (mlp, addresses, &addr); GAS_mlp_done (mlp); -- 2.25.1