]> granicus.if.org Git - vnstat/commitdiff
refactor rate calculations, fix use of correct prefix symbol, closes #41
authorTeemu Toivola <git@humdi.net>
Tue, 12 Apr 2016 21:09:59 +0000 (00:09 +0300)
committerTeemu Toivola <git@humdi.net>
Tue, 12 Apr 2016 21:09:59 +0000 (00:09 +0300)
src/common.c
src/misc.c
src/misc.h
tests/misc_tests.c

index 9a2c6597b24c74b01225d07fac14082fa6c60e8a..b577f54a4cd31c65d12802fc1213a5e7f5ffc121 100644 (file)
@@ -214,6 +214,9 @@ void addtraffic(uint64_t *destmb, int *destkb, const uint64_t srcmb, const int s
 
 uint64_t mbkbtokb(uint64_t mb, uint64_t kb)
 {
+       if (mb==0) {
+               return kb;
+       }
        if (kb>=1024) {
                mb+=kb/1024;
                kb-=(kb/1024)*1024;
index 2780c62b99c7c688bedc731ade77b5ebe4c5da4a..36c433b67a0cd7625d8330f4e21aec5fd9939d32 100644 (file)
@@ -237,42 +237,14 @@ char *getvalue(uint64_t mb, uint64_t kb, int len, int type)
 
 char *getrate(uint64_t mb, uint64_t kb, uint32_t interval, int len)
 {
-       static char buffer[64];
-       int unit, declen = 2;
-       uint64_t kB;
-       float rate;
-
-       if (interval==0) {
-               snprintf(buffer, 64, "%*s", len, "n/a");
-               return buffer;
-       }
-
-       if (mb!=0) {
-               kB=mbkbtokb(mb, kb);
-       } else {
-               kB=kb;
-       }
-
-       /* convert to proper unit */
-       if (cfg.rateunit) {
-               rate = (kB*8)/(float)interval;
-               unit = 2;
-               if (interval<5) {
-                       declen = 0;
-               }
-       } else {
-               rate = kB/(float)interval;
-               unit = cfg.unit;
-       }
-
-       return getratestring(rate, len, declen, unit);
+       return gettrafficrate(mbkbtokb(mb, kb) * 1024, interval, len);
 }
 
 char *gettrafficrate(uint64_t bytes, uint32_t interval, int len)
 {
        static char buffer[64];
        int unit, declen = 2;
-       float rate;
+       uint64_t b;
 
        if (interval==0) {
                snprintf(buffer, 64, "%*s", len, "n/a");
@@ -281,17 +253,17 @@ char *gettrafficrate(uint64_t bytes, uint32_t interval, int len)
 
        /* convert to proper unit */
        if (cfg.rateunit) {
-               rate = (bytes*8)/(float)(interval*1024);
+               b = bytes * 8;
                unit = 2;
                if (interval<5) {
                        declen = 0;
                }
        } else {
-               rate = bytes/(float)(interval*1024);
+               b = bytes;
                unit = cfg.unit;
        }
 
-       return getratestring(rate, len, declen, unit);
+       return getratestring(b / interval, len, declen, unit);
 }
 
 uint64_t getscale(uint64_t kb)
@@ -353,11 +325,11 @@ char *getrateunit(int unit, int index)
        }
 }
 
-uint32_t getunitdivider(int unit, int index)
+uint64_t getunitdivider(int unit, int index)
 {
-       uint32_t unitdiv[] = { 0, 0, 1024, 1048576, 1073741824,
-                              0, 1024, 1048576, 1073741824,
-                              0, 1000, 1000000, 1000000000 };
+       uint64_t unitdiv[] = { 0, 1024, 1048576, 1073741824, 1099511627776,
+                              1024, 1048576, 1073741824, 1099511627776,
+                              1000, 1000000, 1000000000, 1000000000000};
 
        if (index>UNITCOUNT) {
                return unitdiv[0];
@@ -366,15 +338,15 @@ uint32_t getunitdivider(int unit, int index)
        }
 }
 
-char *getratestring(float rate, int len, int declen, int unit)
+char *getratestring(uint64_t rate, int len, int declen, int unit)
 {
        static char buffer[64];
-       uint32_t limit[3] = { 1000, 1024000, 1048576000 };
+       uint64_t limit[3] = { 1024000, 1048576000, 1073741824000 };
 
        if (cfg.rateunit) {
-               limit[0] = 1000;
-               limit[1] = 1000000;
-               limit[2] = 1000000000;
+               limit[0] = 1000000;
+               limit[1] = 1000000000;
+               limit[2] = 1000000000000;
        }
 
        /* tune spacing according to unit */
@@ -391,7 +363,7 @@ char *getratestring(float rate, int len, int declen, int unit)
        } else if (rate>=limit[0]) {
                snprintf(buffer, 64, "%"DECCONV"*.2f %s", len, rate/(float)getunitdivider(unit, 2), getrateunit(unit, 2));
        } else {
-               snprintf(buffer, 64, "%"DECCONV"*.*f %s", len, declen, rate, getrateunit(unit, 1));
+               snprintf(buffer, 64, "%"DECCONV"*.*f %s", len, declen, rate/(float)getunitdivider(unit, 1), getrateunit(unit, 1));
        }
 
        return buffer;
index 4d3ef3c850086d7f86f929489de6c7364987c962..2c2e0eab846e8fc2d51dfe88861b9bd790eccca5 100644 (file)
@@ -13,8 +13,8 @@ char *gettrafficrate(uint64_t bytes, uint32_t interval, int len);
 uint64_t getscale(uint64_t kb);
 char *getunit(int index);
 char *getrateunit(int unit, int index);
-uint32_t getunitdivider(int unit, int index);
-char *getratestring(float rate, int len, int declen, int unit);
+uint64_t getunitdivider(int unit, int index);
+char *getratestring(uint64_t rate, int len, int declen, int unit);
 int getpadding(int len, char *str);
 void cursortocolumn(int column);
 void cursorhide(void);
index 790e253bd01d2aac541d490136257a039b5c7ea4..fde5e8e70e90ea91a791c412792b7c4428f5ea55 100644 (file)
@@ -39,7 +39,7 @@ START_TEST(getunitdivider_returns_something_with_all_cfg_combinations)
        int j;
 
        for (j=1; j<=(UNITCOUNT+1); j++) {
-               if (j==1 || j>UNITCOUNT) {
+               if (j>UNITCOUNT) {
                        ck_assert_int_eq(getunitdivider(_i, j), 0);
                } else {
                        ck_assert_int_ne(getunitdivider(_i, j), 0);
@@ -181,15 +181,15 @@ START_TEST(getrate_bits)
 {
        cfg.rateunit = 1;
        cfg.unit = 0;
-       ck_assert_str_eq(getrate(0, 100, 1, 0), "800 kbit/s");
-       ck_assert_str_eq(getrate(1, 3210, 1, 0), "33.87 Mbit/s");
-       ck_assert_str_eq(getrate(1024, 0, 1, 0), "8.39 Gbit/s");
-       ck_assert_str_eq(getrate(1048576, 0, 1, 0), "8.59 Tbit/s");
+       ck_assert_str_eq(getrate(0, 100, 1, 0), "819 kbit/s");
+       ck_assert_str_eq(getrate(1, 3210, 1, 0), "34.68 Mbit/s");
+       ck_assert_str_eq(getrate(1024, 0, 1, 0), "8.59 Gbit/s");
+       ck_assert_str_eq(getrate(1048576, 0, 1, 0), "8.80 Tbit/s");
        cfg.unit = 1;
-       ck_assert_str_eq(getrate(0, 100, 1, 0), "800 kbit/s");
-       ck_assert_str_eq(getrate(1, 3210, 1, 0), "33.87 Mbit/s");
-       ck_assert_str_eq(getrate(1024, 0, 1, 0), "8.39 Gbit/s");
-       ck_assert_str_eq(getrate(1048576, 0, 1, 0), "8.59 Tbit/s");
+       ck_assert_str_eq(getrate(0, 100, 1, 0), "819 kbit/s");
+       ck_assert_str_eq(getrate(1, 3210, 1, 0), "34.68 Mbit/s");
+       ck_assert_str_eq(getrate(1024, 0, 1, 0), "8.59 Gbit/s");
+       ck_assert_str_eq(getrate(1048576, 0, 1, 0), "8.80 Tbit/s");
 }
 END_TEST
 
@@ -201,9 +201,9 @@ START_TEST(getrate_interval_divides)
        ck_assert_str_eq(getrate(0, 100, 2, 0), "50.00 KiB/s");
        ck_assert_str_eq(getrate(0, 100, 10, 0), "10.00 KiB/s");
        cfg.rateunit = 1;
-       ck_assert_str_eq(getrate(0, 100, 1, 0), "800 kbit/s");
-       ck_assert_str_eq(getrate(0, 100, 2, 0), "400 kbit/s");
-       ck_assert_str_eq(getrate(0, 100, 10, 0), "80.00 kbit/s");
+       ck_assert_str_eq(getrate(0, 100, 1, 0), "819 kbit/s");
+       ck_assert_str_eq(getrate(0, 100, 2, 0), "410 kbit/s");
+       ck_assert_str_eq(getrate(0, 100, 10, 0), "81.92 kbit/s");
 }
 END_TEST
 
@@ -251,15 +251,15 @@ START_TEST(gettrafficrate_bits)
 {
        cfg.rateunit = 1;
        cfg.unit = 0;
-       ck_assert_str_eq(gettrafficrate(102400, 1, 0), "800 kbit/s");
-       ck_assert_str_eq(gettrafficrate(1048576, 1, 0), "8.19 Mbit/s");
-       ck_assert_str_eq(gettrafficrate(1073741824, 1, 0), "8.39 Gbit/s");
-       ck_assert_str_eq(gettrafficrate(1099511627776ULL, 1, 0), "8.59 Tbit/s");
+       ck_assert_str_eq(gettrafficrate(102400, 1, 0), "819 kbit/s");
+       ck_assert_str_eq(gettrafficrate(1048576, 1, 0), "8.39 Mbit/s");
+       ck_assert_str_eq(gettrafficrate(1073741824, 1, 0), "8.59 Gbit/s");
+       ck_assert_str_eq(gettrafficrate(1099511627776ULL, 1, 0), "8.80 Tbit/s");
        cfg.unit = 1;
-       ck_assert_str_eq(gettrafficrate(102400, 1, 0), "800 kbit/s");
-       ck_assert_str_eq(gettrafficrate(1048576, 1, 0), "8.19 Mbit/s");
-       ck_assert_str_eq(gettrafficrate(1073741824, 1, 0), "8.39 Gbit/s");
-       ck_assert_str_eq(gettrafficrate(1099511627776ULL, 1, 0), "8.59 Tbit/s");
+       ck_assert_str_eq(gettrafficrate(102400, 1, 0), "819 kbit/s");
+       ck_assert_str_eq(gettrafficrate(1048576, 1, 0), "8.39 Mbit/s");
+       ck_assert_str_eq(gettrafficrate(1073741824, 1, 0), "8.59 Gbit/s");
+       ck_assert_str_eq(gettrafficrate(1099511627776ULL, 1, 0), "8.80 Tbit/s");
 }
 END_TEST
 
@@ -271,9 +271,9 @@ START_TEST(gettrafficrate_interval_divides)
        ck_assert_str_eq(gettrafficrate(102400, 2, 0), "50.00 KiB/s");
        ck_assert_str_eq(gettrafficrate(102400, 10, 0), "10.00 KiB/s");
        cfg.rateunit = 1;
-       ck_assert_str_eq(gettrafficrate(102400, 1, 0), "800 kbit/s");
-       ck_assert_str_eq(gettrafficrate(102400, 2, 0), "400 kbit/s");
-       ck_assert_str_eq(gettrafficrate(102400, 10, 0), "80.00 kbit/s");
+       ck_assert_str_eq(gettrafficrate(102400, 1, 0), "819 kbit/s");
+       ck_assert_str_eq(gettrafficrate(102400, 2, 0), "410 kbit/s");
+       ck_assert_str_eq(gettrafficrate(102400, 10, 0), "81.92 kbit/s");
 }
 END_TEST