File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bmon / src / graph.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 21 14:58:35 2019 UTC (4 years, 11 months ago) by misho
Branches: bmon, MAIN
CVS tags: v4_0p0, HEAD
bmon ver 4.0

    1: /*
    2:  * graph.c             Graph creation utility
    3:  *
    4:  * Copyright (c) 2001-2013 Thomas Graf <tgraf@suug.ch>
    5:  * Copyright (c) 2013 Red Hat, Inc.
    6:  *
    7:  * Permission is hereby granted, free of charge, to any person obtaining a
    8:  * copy of this software and associated documentation files (the "Software"),
    9:  * to deal in the Software without restriction, including without limitation
   10:  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   11:  * and/or sell copies of the Software, and to permit persons to whom the
   12:  * Software is furnished to do so, subject to the following conditions:
   13:  *
   14:  * The above copyright notice and this permission notice shall be included
   15:  * in all copies or substantial portions of the Software.
   16:  *
   17:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   18:  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   19:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   20:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   21:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   22:  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   23:  * DEALINGS IN THE SOFTWARE.
   24:  */
   25: 
   26: #include <bmon/bmon.h>
   27: #include <bmon/graph.h>
   28: #include <bmon/input.h>
   29: #include <bmon/conf.h>
   30: #include <bmon/history.h>
   31: #include <bmon/conf.h>
   32: #include <bmon/unit.h>
   33: #include <bmon/utils.h>
   34: 
   35: size_t graph_row_size(struct graph_cfg *cfg)
   36: {
   37: 	/* +1 for trailing \0 */
   38: 	return cfg->gc_width + 1;
   39: }
   40: 
   41: static inline size_t table_size(struct graph_cfg *cfg)
   42: {
   43: 	return cfg->gc_height * graph_row_size(cfg);
   44: }
   45: 
   46: static inline char *at_row(struct graph_cfg *cfg, char *col, int nrow)
   47: {
   48: 	return col + (nrow * graph_row_size(cfg));
   49: }
   50: 
   51: static inline char *at_col(char *row, int ncol)
   52: {
   53: 	return row + ncol;
   54: }
   55: 
   56: static inline char *tbl_pos(struct graph_cfg *cfg, char *tbl, int nrow, int ncol)
   57: {
   58: 	return at_col(at_row(cfg, tbl, nrow), ncol);
   59: }
   60: 
   61: static void fill_table(struct graph *g, struct graph_table *tbl,
   62: 		       struct history *h, struct history_store *data)
   63: {
   64: 	struct graph_cfg *cfg = &g->g_cfg;
   65: 	uint64_t max = 0;
   66: 	double v;
   67: 	int i, n, t;
   68: 	float half_step, step;
   69: 
   70: 	if (!tbl->gt_table) {
   71: 		tbl->gt_table = xcalloc(table_size(cfg), sizeof(char));
   72: 		tbl->gt_scale = xcalloc(cfg->gc_height, sizeof(double));
   73: 	}
   74: 
   75: 	memset(tbl->gt_table, cfg->gc_background, table_size(cfg));
   76: 
   77: 	/* end each line with a \0 */
   78: 	for (i = 0; i < cfg->gc_height; i++)
   79: 		*tbl_pos(cfg, tbl->gt_table, i, cfg->gc_width) = '\0';
   80: 
   81: 	/* leave table blank if there is no data */
   82: 	if (!h || !data->hs_data)
   83: 		return;
   84: 
   85: 	if (cfg->gc_width > h->h_definition->hd_size)
   86: 		BUG();
   87: 
   88: 	/* find the largest peak */
   89: 	for (n = h->h_index, i = 0; i < cfg->gc_width; i++) {
   90: 		if (--n < 0)
   91: 			n = h->h_definition->hd_size - 1;
   92: 		v = history_data(h, data, n);
   93: 		if (v != HISTORY_UNKNOWN && max < v)
   94: 			max = v;
   95: 	}
   96: 
   97: 	step = (double) max / (double) cfg->gc_height;
   98: 	half_step = step / 2.0f;
   99: 
  100: 	for (i = 0; i < cfg->gc_height; i++)
  101: 		tbl->gt_scale[i] = (double) (i + 1) * step;
  102: 
  103: 	for (n = h->h_index, i = 0; i < cfg->gc_width; i++) {
  104: 		char * col = at_col(tbl->gt_table, i);
  105: 
  106: 		if (--n < 0)
  107: 			n = h->h_definition->hd_size - 1;
  108: 		v = history_data(h, data, n);
  109: 
  110: 		if (v == HISTORY_UNKNOWN) {
  111: 			for (t = 0; t < cfg->gc_height; t++)
  112: 				*(at_row(cfg, col, t)) = cfg->gc_unknown;
  113: 		} else if (v > 0) {
  114: 			*(at_row(cfg, col, 0)) = cfg->gc_noise;
  115: 
  116: 			for (t = 0; t < cfg->gc_height; t++)
  117: 				if (v >= (tbl->gt_scale[t] - half_step))
  118: 					*(at_row(cfg, col, t)) = cfg->gc_foreground;
  119: 		}
  120: 	}
  121: 
  122: 	n = (cfg->gc_height / 3) * 2;
  123: 	if (n >= cfg->gc_height)
  124: 		n = (cfg->gc_height - 1);
  125: 
  126: 	v = unit_divisor(tbl->gt_scale[n], cfg->gc_unit,
  127: 			 &tbl->gt_y_unit, NULL);
  128: 	
  129: 	for (i = 0; i < cfg->gc_height; i++)
  130: 		tbl->gt_scale[i] /= v;
  131: }
  132: 
  133: struct graph *graph_alloc(struct history *h, struct graph_cfg *cfg)
  134: {
  135: 	struct graph *g;
  136: 
  137: 	if (!cfg->gc_height)
  138: 		BUG();
  139: 
  140: 	g = xcalloc(1, sizeof(*g));
  141: 
  142: 	memcpy(&g->g_cfg, cfg, sizeof(*cfg));
  143: 
  144: 	if (h != NULL &&
  145: 	    (cfg->gc_width > h->h_definition->hd_size || !cfg->gc_width))
  146: 		g->g_cfg.gc_width = h->h_definition->hd_size;
  147: 
  148: 	if (!g->g_cfg.gc_width)
  149: 		BUG();
  150: 
  151: 	return g;
  152: }
  153: 
  154: void graph_refill(struct graph *g, struct history *h)
  155: {
  156: 	fill_table(g, &g->g_rx, h, h ? &h->h_rx : NULL);
  157: 	fill_table(g, &g->g_tx, h, h ? &h->h_tx : NULL);
  158: }
  159: 
  160: void graph_free(struct graph *g)
  161: {
  162: 	if (!g)
  163: 		return;
  164: 
  165: 	xfree(g->g_rx.gt_table);
  166: 	xfree(g->g_rx.gt_scale);
  167: 	xfree(g->g_tx.gt_table);
  168: 	xfree(g->g_tx.gt_scale);
  169: 	xfree(g);
  170: }
  171: 
  172: #if 0
  173: 
  174: void new_graph(void)
  175: {
  176: 	if (ngraphs >= (MAX_GRAPHS - 1))
  177: 		return;
  178: 	set_ngraphs_hard(ngraphs + 1);
  179: }
  180: 
  181: void del_graph(void)
  182: {
  183: 	if (ngraphs <= 1)
  184: 		return;
  185: 	set_ngraphs_hard(ngraphs - 1);
  186: }
  187: 
  188: int next_graph(void)
  189: {
  190: 	struct item *it = item_current();
  191: 	if (it == NULL)
  192: 		return EMPTY_LIST;
  193: 
  194: 	if (it->i_graph_sel >= (ngraphs - 1))
  195: 		it->i_graph_sel = 0;
  196: 	else
  197: 		it->i_graph_sel++;
  198: 
  199: 	return 0;
  200: }
  201: 	
  202: int prev_graph(void)
  203: {
  204: 	struct item *it = item_current();
  205: 	if (it == NULL)
  206: 		return EMPTY_LIST;
  207: 
  208: 	if (it->i_graph_sel <= 0)
  209: 		it->i_graph_sel = ngraphs - 1;
  210: 	else
  211: 		it->i_graph_sel--;
  212: 
  213: 	return 0;
  214: }
  215: 
  216: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>