From 5d19de3b63f0ab0b060df28a583180a6dafae1a0 Mon Sep 17 00:00:00 2001
From: Moe Jette <jette1@llnl.gov>
Date: Sat, 1 Jan 2011 18:42:02 +0000
Subject: [PATCH] patch from Gerrit: 01_hostlist_parse_int_into_array.diff

hostlist: shorter conversion

This replaces the hostlist_parse_int_to_array() routine with a simpler and
equivalent routine. I was wondering what the algorithm does, when suddenly
the flow became simpler.

Problem: we want to create an array 'out' of 'dims' dimensions where
         out[i], 0 <= i < dims, has the coefficients a_j of the polynomial

	 a_(dims-1) * B^(dims-1) + ... + a_1 * B + a_0

	 where B is the base of the polynomial 'in' and
	    a_0        = out[dims - 1]
	    a_1        = out[dims - 2]
	    ...
	    a_(dims-1) = a[0]

Using the Horner Scheme, 'in' is represented as
 * dims = 1:                                   a_0 = out[0]
 * dims = 2:                        a_1  * B + a_0 = out[0] * B + out[1]
 * dims = 3:            (a_2  * B + a_1) * B + a_0
 * dims = 4: ((a_3 * B + a_2) * B + a_1) * B + a_0
   ...
 * dims = n: ((a_(n-1) * B + a_(n-2)) * B ... + a_1) * B + a_0

We can get a_0 = out[dims-1] as "in % B" and then derive a_1, a_2, ... by
first dividing by B, and then repeating the process.

If in is 0, all 'dims' coefficients are 0, if it is negative, all coefficients
are negative.
---
 src/common/hostlist.c | 53 ++++++-------------------------------------
 1 file changed, 7 insertions(+), 46 deletions(-)

diff --git a/src/common/hostlist.c b/src/common/hostlist.c
index cf2e74f7996..f3698819e5f 100644
--- a/src/common/hostlist.c
+++ b/src/common/hostlist.c
@@ -2516,52 +2516,13 @@ int hostlist_get_base()
 }
 
 
-void hostlist_parse_int_to_array(int in, int *out, int dims, int hostlist_base)
-{
-	int a;
-
-	static int my_start_pow_minus = 0;
-	static int my_start_pow = 0;
-	static int last_dims = 0;
-        int my_pow_minus = my_start_pow_minus;
-	int my_pow = my_start_pow;
-
-	if(!hostlist_base)
-		hostlist_base = hostlist_get_base();
-
-	if(!my_start_pow || (last_dims != dims)) {
-		/* this will never change so just calculate it once */
-		my_start_pow = 1;
-
-		/* To avoid having to use the pow function and include
-		   the math lib everywhere just do this. */
-		for(a = 0; a<dims; a++)
-			my_start_pow *= hostlist_base;
-
-		my_pow = my_start_pow;
-		my_pow_minus = my_start_pow_minus =
-			my_start_pow / hostlist_base;
-		last_dims = dims;
-	}
-
-	for(a = 0; a<dims; a++) {
-		out[a] = (int)in % my_pow;
-		/* This only needs to be done until we get a 0 here
-		   meaning we are on the last dimension. This avoids
-		   dividing by 0. */
-		if(dims - a) {
-			out[a] /= my_pow_minus;
-			/* set this up for the next dimension */
-			my_pow = my_pow_minus;
-			my_pow_minus /= hostlist_base;
-		}
-		if(out[a] < 0) {
-			error("Dim %d returned negative %d from %d %d %d",
-			      a, out[a], in, my_pow, my_pow_minus);
-			xassert(0);
-			out[a] = 0;
-		}
-	}
+/* convert 'in' polynomial of base 'base' to 'out' array of 'dim' dimensions */
+void hostlist_parse_int_to_array(int in, int *out, int dims, int base)
+{
+	int hostlist_base = base ? base : hostlist_get_base();
+
+	for ( ; --dims >= 0; in /= hostlist_base)
+		out[dims] = in % hostlist_base;
 }
 
 /* return true if a bracket is needed for the range at i in hostlist hl */
-- 
GitLab