[DCCP] tfrc: Identify TFRC table limits and simplify code
Gerrit Renker [Sun, 3 Dec 2006 16:52:41 +0000 (14:52 -0200)]
This
 * adds documentation about the lowest resolution that is possible within
   the bounds of the current lookup table
 * defines a constant TFRC_SMALLEST_P which defines this resolution
 * issues a warning if a given value of p is below resolution
 * combines two previously adjacent if-blocks of nearly identical
   structure into one

This patch does not change the algorithm as such.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>

net/dccp/ccids/lib/tfrc_equation.c

index ef3233d..0a4a3d2 100644 (file)
@@ -19,6 +19,7 @@
 
 #define TFRC_CALC_X_ARRSIZE 500
 #define TFRC_CALC_X_SPLIT   50000      /* 0.05 * 1000000, details below */
+#define TFRC_SMALLEST_P            (TFRC_CALC_X_SPLIT/TFRC_CALC_X_ARRSIZE)
 
 /*
   TFRC TCP Reno Throughput Equation Lookup Table for f(p)
@@ -68,7 +69,9 @@
   granularity for the practically more relevant case of small values of p (up to
   5%), the second column is used; the first one ranges up to 100%.  This split
   corresponds to the value of q = TFRC_CALC_X_SPLIT. At the same time this also
-  determines the smallest resolution.
+  determines the smallest resolution possible with this lookup table:
+
+    TFRC_SMALLEST_P   =  TFRC_CALC_X_SPLIT / TFRC_CALC_X_ARRSIZE
 
   The entire table is generated by:
     for(i=0; i < TFRC_CALC_X_ARRSIZE; i++) {
@@ -79,7 +82,7 @@
   With the given configuration, we have, with M = TFRC_CALC_X_ARRSIZE-1,
     lookup[0][0]  =  g(1000000/(M+1))           =  1000000 * f(0.2%)
     lookup[M][0]  =  g(1000000)                         =  1000000 * f(100%)
-    lookup[0][1]  =  g(TFRC_CALC_X_SPLIT/(M+1))         =  1000000 * f(0.01%)
+    lookup[0][1]  =  g(TFRC_SMALLEST_P)                  = 1000000 * f(0.01%)
     lookup[M][1]  =  g(TFRC_CALC_X_SPLIT)       =  1000000 * f(5%)
 
   In summary, the two columns represent f(p) for the following ranges:
@@ -616,15 +619,21 @@ u32 tfrc_calc_x(u16 s, u32 R, u32 p)
                return ~0U;
        }
 
-       if (p < TFRC_CALC_X_SPLIT)                    /* 0      <= p <  0.05  */
-               index = (p / (TFRC_CALC_X_SPLIT / TFRC_CALC_X_ARRSIZE)) - 1;
-       else                                          /* 0.05   <= p <= 1.00  */
-               index = (p / (1000000 / TFRC_CALC_X_ARRSIZE)) - 1;
+       if (p <= TFRC_CALC_X_SPLIT)             {     /* 0.0000 < p <= 0.05   */
+               if (p < TFRC_SMALLEST_P) {            /* 0.0000 < p <  0.0001 */
+                       DCCP_WARN("Value of p (%d) below resolution. "
+                                 "Substituting %d\n", p, TFRC_SMALLEST_P);
+                       index = 0;
+               } else                                /* 0.0001 <= p <= 0.05  */
+                       index =  p/TFRC_SMALLEST_P - 1;
+
+               f = tfrc_calc_x_lookup[index][1];
+
+       } else {                                      /* 0.05   <  p <= 1.00  */
+               index = p/(1000000/TFRC_CALC_X_ARRSIZE) - 1;
 
-       if (p >= TFRC_CALC_X_SPLIT)
                f = tfrc_calc_x_lookup[index][0];
-       else
-               f = tfrc_calc_x_lookup[index][1];
+       }
 
        /* The following computes X = s/(R*f(p)) in bytes per second. Since f(p)
         * and R are both scaled by 1000000, we need to multiply by 1000000^2.