Revision 5f3adef4 monl/result_buffer.cpp

View differences:

monl/result_buffer.cpp
24 24

  
25 25
#include "mon_event.h"
26 26

  
27
#ifndef WIN32
28 27
#include <arpa/inet.h>
29
#endif
30 28

  
31 29
#include <sys/time.h>
32 30
#include <stdlib.h>
......
48 46
	"_win_max",
49 47
	"_sum",
50 48
	"_win_sum",
51
	"_rate",
52
	"_period_sum"
49
	"_rate"
53 50
};
54 51

  
55 52
int ResultBuffer::publishResults(void){
......
75 72
		return EOK;
76 73
	new_data = false;
77 74

  
78
	updateStats();
79

  
80 75
	info("MONL: publishResults called: %s value: %f (%s)", publish_name.c_str(), stats[LAST], default_name);
81 76
	if(publish_length == 0)
82 77
		return EOK;
......
119 114
		repPublish(repo_client, NULL, NULL, &mr);
120 115
		publish_name.erase(name_size);
121 116
	}
122

  
123
	stats[PERIOD_SUM] = NAN;
124

  
125 117
	return EOK;
126 118
};
127 119

  
128 120
int ResultBuffer::init() {
129 121
	int i;
130
	n_samples = 0; samples = 0;
122
	n_samples = 0; samples = 0; sum_samples = 0;
131 123
	sum_win_samples = 0; rate_sum_samples = 0;
132 124
	pos = 0;
133 125
	sum_win_var_samples = 0;
......
154 146
	old_pos = pos;
155 147
	old_size = size;
156 148

  
157
	sum_win_var_samples = 0;
149
	sum_win_samples = sum_win_var_samples = 0;
158 150
	n_samples = 0; pos = 0; size = s;
159
	stats[WIN_SUM] = 0;
160 151

  
161 152
	for(i = 0; i < n_sam; i++) {
162 153
		j = old_pos - n_sam + i;
......
171 162
	return EOK;
172 163
};
173 164

  
174
/* This function is used to update internal variables with data from a new sample */
175 165
int ResultBuffer::newSample(result r) {
176 166
	samples++;
177 167

  
......
179 169

  
180 170
	//TODO add statistical data like avg
181 171

  
182
	if(isnan(stats[SUM]))
183
		stats[SUM] = r;
184
	else
185
		stats[SUM] += r;
186

  
187
	if(isnan(stats[PERIOD_SUM]))
188
		stats[PERIOD_SUM] = r;
189
	else
190
		stats[PERIOD_SUM] += r;
191

  
172
	sum_samples += r;
192 173
	rate_sum_samples += r;
193 174

  
175
	stats[SUM] = sum_samples;
176

  
194 177
	/* Average  */
195 178
	if(isnan(stats[AVG]))
196 179
		stats[AVG] = 0;
......
202 185
	else
203 186
		stats[VAR] = stats[VAR] * (samples - 2)/(samples - 1) + samples / pow(samples - 1, 2) * pow(r - stats[AVG],2);
204 187

  
188

  
205 189
	/* Minimum maximum */
206 190
	if(r < stats[MIN] || isnan(stats[MIN]))
207 191
		stats[MIN] = r;
......
209 193
	if(r > stats[MAX] || isnan(stats[MAX]))
210 194
		stats[MAX] = r;
211 195

  
196
	// Update window based stats
212 197
	newSampleWin(r);
213 198

  
214 199
	new_data = true;
......
222 207
};
223 208

  
224 209
int ResultBuffer::newSampleWin(result r) {
210
	int i,j;
211
	result var_s;
212

  
213
	//TODO add statistical data like avg
225 214

  
226 215
	/* sum */
227 216
	if(n_samples < size)	{
228 217
		n_samples++;
229 218
	} else {
230
		stats[WIN_SUM] -= circular_buffer[pos];
219
		sum_win_samples -= circular_buffer[pos];
220
		sum_win_var_samples -= circular_buffer_var[pos];
231 221
	}
222
	sum_win_samples += r;
232 223

  
233
	if(isnan(stats[WIN_SUM]))
234
		stats[WIN_SUM] = r;
235
	else
236
		stats[WIN_SUM] += r;
224
	stats[WIN_SUM] = sum_win_samples;	
237 225

  
238
	circular_buffer[pos] = r;
226
	stats[WIN_AVG] = sum_win_samples/n_samples;
227

  
228
	var_s = pow(r - stats[WIN_AVG],2);
229
	sum_win_var_samples += var_s;
230

  
231
	if(n_samples > 1)
232
		stats[WIN_VAR] = sum_win_var_samples/(n_samples - 1);
239 233

  
234
	/* Minimum maximum */
235
	if(isnan(stats[WIN_MIN]))
236
		stats[WIN_MIN] = r;
237
	if(isnan(stats[WIN_MAX]))
238
		stats[WIN_MAX] = r;
239

  
240
	if(stats[WIN_MIN] == circular_buffer[pos] || stats[WIN_MAX] == circular_buffer[pos]) {
241
		circular_buffer[pos] = stats[WIN_MAX] = stats[WIN_MIN] = r;
242
		for(i = 0; i <= n_samples - 1; i++) {
243
			j = pos - i; // pos already incremented and last sample is starting one
244
			if(j < 0)
245
				j += size;
246
			if(circular_buffer[j] < stats[WIN_MIN])
247
				stats[WIN_MIN] = circular_buffer[j];
248
			if(circular_buffer[j] > stats[WIN_MAX])
249
				stats[WIN_MAX] = circular_buffer[j];
250
		}
251
	} else {
252
		if(r < stats[WIN_MIN]) 
253
			stats[WIN_MIN] = r;
254
		if (r > stats[WIN_MAX])
255
			stats[WIN_MAX] = r;
256
	}
257

  
258
	circular_buffer[pos] = r;
259
	circular_buffer_var[pos] = var_s;
240 260
	pos++;
241 261
	if(pos >= size)
242 262
		pos -= size;
243 263

  
244 264
	return EOK;
245 265
};
246

  
247

  
248
/*This function updates the stats vector */
249
void ResultBuffer::updateStats(void) {
250
	int i,j;
251

  
252
	/* Note: some stats are already updated on the fly in newSample() */
253
	/* This function is to update the more time consuming not recursive statitistics */
254

  
255
	stats[WIN_AVG] = stats[WIN_SUM]/n_samples;
256

  
257
	/* Minimum, maximum and variance*/
258
	stats[WIN_MIN] = stats[WIN_MAX] = stats[LAST];
259
	stats[WIN_VAR] = 0.0;
260
	for(i = 1; i <= n_samples; i++) {
261
		j = pos - i; // pos already incremented and last sample is starting one
262
		if(j < 0)
263
			j += size;
264
		if(circular_buffer[j] < stats[WIN_MIN])
265
			stats[WIN_MIN] = circular_buffer[j];
266
		if(circular_buffer[j] > stats[WIN_MAX])
267
			stats[WIN_MAX] = circular_buffer[j];
268
		stats[WIN_VAR] += pow(stats[WIN_AVG] - circular_buffer[j], 2);
269
	}
270
	if(n_samples > 1)
271
		stats[WIN_VAR] = stats[WIN_VAR] / (n_samples - 1);
272
	else
273
		stats[WIN_VAR] = NAN;
274
}
275

  

Also available in: Unified diff