]> git.sesse.net Git - nms/blob - web/ext/flowpusher.cpp
Add lots of TG06 graph stuff.
[nms] / web / ext / flowpusher.cpp
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <sys/wait.h>
4 #include <malloc.h>
5 #include <vector>
6 #include "flowpusher.h"
7
8 FlowPusher::FlowPusher(std::vector<flow_element> &flow) : flow(flow)
9 {
10 }
11
12 void FlowPusher::find_diff(double x, double &prev_x, unsigned long long y1, unsigned long long prev_y1, unsigned long long y2, unsigned long long prev_y2,
13         unsigned long long &yf1, unsigned long long &yf2)
14 {
15         // Heuristics: if last reading was more than ten minutes away, and both
16         //             readings went down from last reading, we assume the counters
17         //             were zeroed. If not, we assume wraparound.
18         bool over_10mins = (x - prev_x >= 600);
19         bool y1_wrapped = ((prev_y1 == 0 && y1 == 0) || y1 < prev_y1);
20         bool y2_wrapped = ((prev_y2 == 0 && y2 == 0) || y2 < prev_y2);
21         bool both_zero = (y1 == 0 && y2 == 0);  
22         bool any_wide = (prev_y1 > 4294967296ULL || prev_y2 > 4294967296ULL);
23         
24         if ((over_10mins && (y1_wrapped || y2_wrapped)) || both_zero || (any_wide && (y1_wrapped || y2_wrapped))) {
25                 prev_y1 = 0;
26                 prev_y2 = 0;
27
28                 // our best estimate for when it was zeroed :-)
29                 prev_x = (prev_x + x) / 2;
30         }
31
32         if (y1 < prev_y1) {
33                 yf1 = (unsigned long long)(((unsigned long long)y1 + 4294967296ULL) - prev_y1);
34         } else {
35                 yf1 = (unsigned long long)(y1 - prev_y1);
36         }
37         
38         if (y2 < prev_y2) {
39                 yf2 = (unsigned long long)(((unsigned long long)y2 + 4294967296ULL) - prev_y2) / (x - prev_x);
40         } else {
41                 yf2 = (unsigned long long)(y2 - prev_y2);
42         }
43 }
44
45 void FlowPusher::push(double x, unsigned long long y1, unsigned long long y2)
46 {
47         unsigned long long yf1, yf2;
48
49         find_diff(x, prev_x, y1, prev_y1, y2, prev_y2, yf1, yf2);
50         yf1 /= (x - prev_x);
51         yf2 /= (x - prev_x);
52                 
53         flow_element fe;
54         fe.x = unsigned((prev_x + x)*0.5);
55         fe.y1 = yf1;
56         fe.y2 = yf2;
57
58         min_x = std::min(min_x, fe.x);
59         max_x = std::max(max_x, fe.x);
60         
61         min_y = std::min(min_y, fe.y1);
62         max_y = std::max(max_y, fe.y1);
63         
64         min_y = std::min(min_y, fe.y2);
65         max_y = std::max(max_y, fe.y2);
66
67         flow.push_back(fe);
68
69         prev_x = x;
70         prev_y1 = y1;
71         prev_y2 = y2;
72 }
73
74 void FlowPusher::reset(double x, unsigned long long y1, unsigned long long y2)
75 {
76         flow.resize(0);
77         
78         min_y = 0;
79         max_y = 10000000;
80         
81         max_x = time(NULL);
82         min_x = max_x - 86400;
83         
84         prev_x = x;
85         prev_y1 = y1;
86         prev_y2 = y2;
87 }