]> git.sesse.net Git - nms/blob - sql/get_rate.c
Optimize the get_datarate() function, using some SQL and some C instead.
[nms] / sql / get_rate.c
1 /*
2    gcc -fPIC -c get_rate.c -I$( pg_config --includedir-server )
3    gcc -shared -o get_rate.so get_rate.o
4  */
5
6 #include "postgres.h"
7 #include <string.h>
8 #include "fmgr.h"
9 #include "funcapi.h"
10 #include "catalog/pg_type.h"
11 #include "utils/lsyscache.h"
12 #include "utils/array.h"
13 #include "access/heapam.h"
14
15 #ifdef PG_MODULE_MAGIC
16 PG_MODULE_MAGIC;
17 #endif
18
19 PG_FUNCTION_INFO_V1(get_rate);
20
21 Datum
22 get_rate(PG_FUNCTION_ARGS)
23 {
24         float8 bytes_in_1 = PG_GETARG_FLOAT8(0);
25         float8 bytes_out_1 = PG_GETARG_FLOAT8(1);
26         float8 time_1 = PG_GETARG_FLOAT8(2);
27
28         float8 bytes_in_2 = PG_GETARG_FLOAT8(3);
29         float8 bytes_out_2 = PG_GETARG_FLOAT8(4);
30         float8 time_2 = PG_GETARG_FLOAT8(5);
31
32         bool no_wrap = PG_GETARG_BOOL(6);
33
34         Datum values[2];
35
36         int16 elmlen;
37         bool elmbyval;
38         char elmalign;
39
40         double in_rate, out_rate;
41
42         if (bytes_in_2 >= bytes_in_1 && bytes_out_2 >= bytes_out_1) {
43                 // regular case, no wraparound or reset
44                 in_rate = (bytes_in_2 - bytes_in_1) / (time_2 - time_1);
45                 out_rate = (bytes_out_2 - bytes_out_1) / (time_2 - time_1);
46         } else {
47                 // is wraparound unlikely?
48                 if (no_wrap 
49                     || (bytes_in_2 + 4294967296.0 - bytes_in_1) >= 2147483648.0 
50                     || (bytes_out_2 + 4294967296.0 - bytes_out_1) >= 2147483648.0) {
51                         // assume the switch zeroed in the middle of the poll interval
52                         in_rate = bytes_in_2 / (2.0 * (time_2 - time_1));
53                         out_rate = bytes_out_2 / (2.0 * (time_2 - time_1));
54                 } else {
55                         // probably wraparound
56                         if (bytes_in_2 < bytes_in_1)
57                                 bytes_in_2 += 4294967296.0;
58                         if (bytes_out_2 < bytes_out_1)
59                                 bytes_out_2 += 4294967296.0;
60
61                         in_rate = (bytes_in_2 - bytes_in_1) / (time_2 - time_1);
62                         out_rate = (bytes_out_2 - bytes_out_1) / (time_2 - time_1);
63                 }
64         }
65
66         values[0] = Float8GetDatum(in_rate);
67         values[1] = Float8GetDatum(out_rate);
68         get_typlenbyvalalign(FLOAT8OID, &elmlen, &elmbyval, &elmalign);
69         PG_RETURN_ARRAYTYPE_P(construct_array(values, 2, FLOAT8OID, elmlen, elmbyval, elmalign));
70 }