From 47d2721f8b7a7f2c40a0cea3c3b1040450546d69 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Sat, 2 Jul 2016 13:08:42 +0100 Subject: [PATCH] [Feature] Interpolate points sent to webui --- src/controller.c | 86 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 23 deletions(-) diff --git a/src/controller.c b/src/controller.c index 78c168460..486957375 100644 --- a/src/controller.c +++ b/src/controller.c @@ -1022,6 +1022,45 @@ rspamd_controller_handle_pie_chart ( return 0; } +void +rspamd_controller_graph_point (gulong t, gulong step, + struct rspamd_rrd_query_result* rrd_result, + gdouble *acc, + ucl_object_t **elt) +{ + guint nan_cnt; + gdouble sum = 0.0, yval; + ucl_object_t* data_elt; + guint i, j; + + for (i = 0; i < rrd_result->ds_count; i++) { + sum = 0.0; + nan_cnt = 0; + data_elt = ucl_object_typed_new (UCL_OBJECT); + ucl_object_insert_key (data_elt, ucl_object_fromint (t), "x", 1, false); + + for (j = 0; j < step; j++) { + yval = acc[i + j * rrd_result->ds_count]; + if (isnan(yval)) { + nan_cnt++; + } + else { + sum += yval; + } + } + if (nan_cnt == step) { + ucl_object_insert_key (data_elt, ucl_object_typed_new (UCL_NULL), + "y", 1, false); + } + else { + ucl_object_insert_key (data_elt, + ucl_object_fromdouble (sum / (gdouble) step), "y", 1, + false); + } + ucl_array_append (elt[i], data_elt); + } +} + /* * Graph command handler: * request: /graph?type= @@ -1042,9 +1081,9 @@ rspamd_controller_handle_graph ( struct rspamd_controller_worker_ctx *ctx; rspamd_ftok_t srch, *value; struct rspamd_rrd_query_result *rrd_result; - gulong i, j, start_row, cnt, t, ts; - gdouble yval, last = 0; - ucl_object_t *res, *elt[4], *data_elt; + gulong i, j, k, start_row, cnt, t, ts, step; + gdouble *acc; + ucl_object_t *res, *elt[4]; enum { rra_hourly = 0, rra_daily, @@ -1052,6 +1091,8 @@ rspamd_controller_handle_graph ( rra_monthly, rra_invalid } rra_num = rra_invalid; + /* How many points are we going to send to display */ + static const guint desired_points = 500; ctx = session->ctx; @@ -1125,43 +1166,42 @@ rspamd_controller_handle_graph ( start_row = rrd_result->cur_row == rrd_result->rra_rows - 1 ? 0 : rrd_result->cur_row; + /* Create window */ + step = (rrd_result->rra_rows / desired_points + 0.5); + acc = g_malloc0 (sizeof (double) * rrd_result->ds_count * step); + for (i = start_row, cnt = 0; cnt < rrd_result->rra_rows; cnt ++) { for (j = 0; j < rrd_result->ds_count; j++) { - - data_elt = ucl_object_typed_new (UCL_OBJECT); - t = ts * rrd_result->pdp_per_cdp; - ucl_object_insert_key (data_elt, - ucl_object_fromint (t), - "x", 1, - false); - yval = rrd_result->data[i * rrd_result->ds_count + j]; - - if (!isnan (yval)) { - ucl_object_insert_key (data_elt, - ucl_object_fromdouble (yval), - "y", 1, - false); - last = yval; + if (k < step) { + /* Just update window */ + acc[k * rrd_result->ds_count + j] = + rrd_result->data[i * rrd_result->ds_count + j]; + k ++; } else { - ucl_object_insert_key (data_elt, - ucl_object_fromdouble (last), - "y", 1, - false); + t = ts * rrd_result->pdp_per_cdp; + + /* Need a fresh point */ + rspamd_controller_graph_point (t, step, rrd_result, acc, elt); + k = 0; } - ucl_array_append (elt[j], data_elt); } i = start_row == 0 ? i + 1 : (i + 1) % start_row; ts ++; } + if (k > 0) { + rspamd_controller_graph_point (t, k, rrd_result, acc, elt); + } + for (i = 0; i < rrd_result->ds_count; i++) { ucl_array_append (res, elt[i]); } rspamd_controller_send_ucl (conn_ent, res); ucl_object_unref (res); + g_free (acc); return 0; } -- 2.39.5