network: Move network offset calculation

network_find_rank_index was used to find the offset of the selected
network_info among known networks so as to compute a modifier based on
the rankmod table.  Instead of using known_networks_foreach for this,
moove it to knownnetworks.c where it can be coded and optimized
separately.

For now provide a simple for loop implementation.
This commit is contained in:
Denis Kenzior 2019-08-09 01:06:10 -05:00
parent d2639e5d4e
commit 72a8f2888a
3 changed files with 31 additions and 32 deletions

View File

@ -72,6 +72,33 @@ const char *known_network_get_path(const struct network_info *network)
return path;
}
/*
* Finds the position n of this network_info in the list of known networks
* sorted by connected_time. E.g. an offset of 0 means the most recently
* used network. Only networks with seen_count > 0 are considered. E.g.
* only networks that appear in scan results on at least one wifi card.
*
* Returns -ENOENT if the entry couldn't be found.
*/
int known_network_offset(const struct network_info *target)
{
const struct l_queue_entry *entry;
const struct network_info *info;
int n = 0;
for (entry = l_queue_get_entries(known_networks); entry;
entry = entry->next) {
info = entry->data;
if (target == info)
return n;
if (info->seen_count)
n += 1;
}
return -ENOENT;
}
static void known_network_register_dbus(struct network_info *network)
{
const char *path = known_network_get_path(network);

View File

@ -31,6 +31,7 @@ struct known_frequency {
uint32_t frequency;
};
int known_network_offset(const struct network_info *target);
bool known_networks_foreach(known_networks_foreach_func_t function,
void *user_data);
bool known_networks_has_hidden(void);

View File

@ -201,35 +201,6 @@ void network_disconnected(struct network *network)
network_settings_close(network);
}
struct network_find_rank_data {
const struct network_info *info;
int n;
};
static bool network_find_rank_update(const struct network_info *network,
void *user_data)
{
struct network_find_rank_data *data = user_data;
if (network == data->info)
return false;
if (network->seen_count)
data->n++;
return true;
}
static int network_find_rank_index(const struct network_info *info)
{
struct network_find_rank_data data = { info, 0 };
if (!known_networks_foreach(network_find_rank_update, &data))
return data.n;
return -1;
}
/* First 64 entries calculated by 1 / pow(n, 0.3) for n >= 1 */
static const double rankmod_table[] = {
1.0000000000, 0.8122523964, 0.7192230933, 0.6597539554,
@ -263,8 +234,8 @@ bool network_rankmod(const struct network *network, double *rankmod)
if (!network->info->connected_time.tv_sec)
return false;
n = network_find_rank_index(network->info);
if (n == -1)
n = known_network_offset(network->info);
if (n < 0)
return false;
nmax = L_ARRAY_SIZE(rankmod_table);
@ -1418,7 +1389,7 @@ void network_rank_update(struct network *network, bool connected)
if (connected)
rank = INT_MAX;
else if (network->info->connected_time.tv_sec != 0) {
int n = network_find_rank_index(network->info);
int n = known_network_offset(network->info);
if (n >= (int) L_ARRAY_SIZE(rankmod_table))
n = L_ARRAY_SIZE(rankmod_table) - 1;