From 5e2621abc697d4cad962fa3ed13f91f0eb043681 Mon Sep 17 00:00:00 2001 From: Gurjeet Singh Date: Thu, 20 Apr 2023 22:06:39 -0700 Subject: [PATCH v0] Reduce code duplication in fe-connect.c Alternate commit title: Move address-shuffling code to a function The address-shuffling algorithm implemented by commit 7f5b198 was duplicated, so place it in a function and reuse. --- src/interfaces/libpq/fe-connect.c | 61 +++++++++++++++---------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index fcd3d0d9a3..8c277f5529 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -1058,6 +1058,31 @@ libpq_prng_init(PGconn *conn) pg_prng_seed(&conn->prng_state, rseed); } +/* + * Shuffles the addresses of the connection. + */ +static void +shuffleAddresses(PGConn *conn) +{ + /* + * This is the "inside-out" variant of the Fisher-Yates shuffle + * algorithm. Notionally, we append each new value to the array + * and then swap it with a randomly-chosen array element (possibly + * including itself, else we fail to generate permutations with + * the last integer last). The swap step can be optimized by + * combining it with the insertion. + */ + for (int i = 1; i < conn->naddr; i++) + { + AddrInfo temp; + int j = pg_prng_uint64_range(&conn->prng_state, 0, i); + + temp = conn->addr[j]; + conn->addr[j] = conn->addr[i]; + conn->addr[i] = temp; + } +} + /* * connectOptions2 * @@ -1711,26 +1736,14 @@ connectOptions2(PGconn *conn) else conn->load_balance_type = LOAD_BALANCE_DISABLE; + /* + * If random load balancing is enabled we shuffle the addresses. + */ if (conn->load_balance_type == LOAD_BALANCE_RANDOM) { libpq_prng_init(conn); - /* - * This is the "inside-out" variant of the Fisher-Yates shuffle - * algorithm. Notionally, we append each new value to the array and - * then swap it with a randomly-chosen array element (possibly - * including itself, else we fail to generate permutations with the - * last integer last). The swap step can be optimized by combining it - * with the insertion. - */ - for (i = 1; i < conn->nconnhost; i++) - { - int j = pg_prng_uint64_range(&conn->prng_state, 0, i); - pg_conn_host temp = conn->connhost[j]; - - conn->connhost[j] = conn->connhost[i]; - conn->connhost[i] = temp; - } + shuffleAddresses(conn); } /* @@ -2745,25 +2758,11 @@ keep_going: /* We will come back to here until there is */ if (conn->load_balance_type == LOAD_BALANCE_RANDOM) { - /* - * This is the "inside-out" variant of the Fisher-Yates shuffle - * algorithm. Notionally, we append each new value to the array - * and then swap it with a randomly-chosen array element (possibly - * including itself, else we fail to generate permutations with - * the last integer last). The swap step can be optimized by - * combining it with the insertion. - * * We don't need to initialize conn->prng_state here, because that * already happened in connectOptions2. */ - for (int i = 1; i < conn->naddr; i++) - { - int j = pg_prng_uint64_range(&conn->prng_state, 0, i); - AddrInfo temp = conn->addr[j]; - conn->addr[j] = conn->addr[i]; - conn->addr[i] = temp; - } + shuffleAddresses(conn); } reset_connection_state_machine = true; -- 2.35.1