From 90154b676f80f5743b30078f860495d8ce009b03 Mon Sep 17 00:00:00 2001 From: Javier Fernandez Date: Thu, 24 Jun 2010 17:06:06 +0000 Subject: [PATCH] Implementing a provider selection algorithm. --- src/client.c | 55 ++++++++++++++++++++++++++++++++++++++---------- src/master-provider.c | 6 ++-- 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/src/client.c b/src/client.c index d4650e8..d820e28 100644 --- a/src/client.c +++ b/src/client.c @@ -327,11 +327,18 @@ gc_master_client_get_best_provider (GcMasterClient *client, GList **provider_list, GcInterfaceFlags iface) { + GcMasterClientPrivate *priv = GET_PRIVATE (client); + GcMasterProvider *best_provider = NULL; + GcInterfaceAccuracy *min_accuracy = NULL; GList *l = *provider_list; /* TODO: should maybe choose a acquiring provider if better ones are are not available */ g_debug ("client: choosing best provider"); + min_accuracy = g_new0(GcInterfaceAccuracy, 1); + min_accuracy->interface = iface; + min_accuracy->accuracy_level = priv->min_accuracy; + while (l) { GcMasterProvider *provider = l->data; @@ -348,20 +355,44 @@ gc_master_client_get_best_provider (GcMasterClient *client, continue; } /* provider did not need to be started */ - - /* TODO: currently returning even providers that are worse than priv->min_accuracy, - * if nothing else is available */ - if (gc_master_provider_get_status (provider) == GEOCLUE_STATUS_AVAILABLE) { - /* unsubscribe from all providers worse than this */ - gc_master_client_unsubscribe_providers (client, l->next, iface); - return provider; + + /* Avoid evaluating twice the same provider. */ + if (best_provider == provider) { + l = l->next; + continue; } - l = l->next; + + /* Check if provider is available. */ + if (!gc_master_provider_get_status (provider) == GEOCLUE_STATUS_AVAILABLE) { + goto continue_searching; + } + + /* First provider evaluated, so its the best. */ + if (best_provider == NULL) { + best_provider = provider; + l = l->next; + continue; + } + + /* Check if its the best provider. */ + if (0 < gc_master_provider_compare (provider, best_provider, min_accuracy)) { + gc_master_provider_unsubscribe (best_provider, client, iface); + best_provider = provider; + l = l->next; + continue; + } else { + goto continue_searching; + } + + continue_searching: + gc_master_provider_unsubscribe (provider, client, iface); + l = l->next; } - - /* no provider found */ - gc_master_client_unsubscribe_providers (client, *provider_list, iface); - return NULL; + + /* Free */ + g_free (min_accuracy); + + return best_provider; } static void diff --git a/src/master-provider.c b/src/master-provider.c index 790c043..7505c0b 100644 --- a/src/master-provider.c +++ b/src/master-provider.c @@ -1301,13 +1301,13 @@ gc_master_provider_compare (GcMasterProvider *a, * providers meet the minimum accuracy requirement */ if ((level_b >= min_level) && (level_a >= min_level)) { - diff = priv_a->required_resources - priv_b->required_resources; + diff = priv_b->required_resources - priv_a->required_resources; if (diff != 0 ) { return diff; } - return level_b - level_a; + return level_a - level_b; } /* one or both do not meet req's, sort by accuracy */ - return level_b - level_a; + return level_a - level_b; } -- 1.6.3.3