Annotation of embedaddon/bmon/src/graph.c, revision 1.1.1.2
1.1 misho 1: /*
2: * graph.c Graph creation utility
3: *
1.1.1.2 ! misho 4: * Copyright (c) 2001-2013 Thomas Graf <tgraf@suug.ch>
! 5: * Copyright (c) 2013 Red Hat, Inc.
1.1 misho 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>
1.1.1.2 ! misho 30: #include <bmon/history.h>
1.1 misho 31: #include <bmon/conf.h>
1.1.1.2 ! misho 32: #include <bmon/unit.h>
1.1 misho 33: #include <bmon/utils.h>
34:
1.1.1.2 ! misho 35: size_t graph_row_size(struct graph_cfg *cfg)
! 36: {
! 37: /* +1 for trailing \0 */
! 38: return cfg->gc_width + 1;
! 39: }
1.1 misho 40:
1.1.1.2 ! misho 41: static inline size_t table_size(struct graph_cfg *cfg)
1.1 misho 42: {
1.1.1.2 ! misho 43: return cfg->gc_height * graph_row_size(cfg);
! 44: }
1.1 misho 45:
1.1.1.2 ! misho 46: static inline char *at_row(struct graph_cfg *cfg, char *col, int nrow)
! 47: {
! 48: return col + (nrow * graph_row_size(cfg));
! 49: }
1.1 misho 50:
1.1.1.2 ! misho 51: static inline char *at_col(char *row, int ncol)
! 52: {
! 53: return row + ncol;
1.1 misho 54: }
55:
1.1.1.2 ! misho 56: static inline char *tbl_pos(struct graph_cfg *cfg, char *tbl, int nrow, int ncol)
1.1 misho 57: {
1.1.1.2 ! misho 58: return at_col(at_row(cfg, tbl, nrow), ncol);
! 59: }
1.1 misho 60:
1.1.1.2 ! misho 61: static void write_column(struct graph_cfg *cfg, struct graph_table *tbl, int ncol,
! 62: uint64_t value, double *scale, double half_step)
! 63: {
! 64: char *col = at_col(tbl->gt_table, ncol);
! 65: int i;
1.1 misho 66:
1.1.1.2 ! misho 67: #if 0
! 68: if (value == UNK_DATA) {
! 69: for (i = 0; i < height; i++)
! 70: *(at_row(g, col, i)) = unk_char;
! 71: #endif
! 72: if (value) {
! 73: *(at_row(cfg, col, 0)) = ':';
! 74:
! 75: for (i = 0; i < cfg->gc_height; i++)
! 76: if (value >= (scale[i] - half_step))
! 77: *(at_row(cfg, col, i)) = cfg->gc_foreground;
! 78: }
! 79: }
1.1 misho 80:
1.1.1.2 ! misho 81: static void fill_table(struct graph *g, struct graph_table *tbl,
! 82: struct history *h, struct history_store *data)
! 83: {
! 84: struct graph_cfg *cfg = &g->g_cfg;
! 85: uint64_t max = 0;
! 86: double v;
! 87: int i, n, t;
! 88: float half_step, step;
! 89:
! 90: if (!tbl->gt_table) {
! 91: tbl->gt_table = xcalloc(table_size(cfg), sizeof(char));
! 92: tbl->gt_scale = xcalloc(cfg->gc_height, sizeof(double));
! 93: }
1.1 misho 94:
1.1.1.2 ! misho 95: memset(tbl->gt_table, cfg->gc_background, table_size(cfg));
1.1 misho 96:
1.1.1.2 ! misho 97: /* end each line with a \0 */
! 98: for (i = 0; i < cfg->gc_height; i++)
! 99: *tbl_pos(cfg, tbl->gt_table, i, cfg->gc_width) = '\0';
1.1 misho 100:
1.1.1.2 ! misho 101: /* leave table blank if there is no data */
! 102: if (!h || !data->hs_data)
! 103: return;
1.1 misho 104:
1.1.1.2 ! misho 105: if (cfg->gc_width > h->h_definition->hd_size)
! 106: BUG();
1.1 misho 107:
1.1.1.2 ! misho 108: /* find the largest peak */
! 109: for (n = h->h_index, i = 0; i < cfg->gc_width; i++) {
! 110: if (--n < 0)
! 111: n = h->h_definition->hd_size - 1;
! 112: v = history_data(h, data, n);
! 113: if (v != HISTORY_UNKNOWN && max < v)
! 114: max = v;
! 115: }
1.1 misho 116:
1.1.1.2 ! misho 117: step = (double) max / (double) cfg->gc_height;
! 118: half_step = step / 2.0f;
1.1 misho 119:
1.1.1.2 ! misho 120: for (i = 0; i < cfg->gc_height; i++)
! 121: tbl->gt_scale[i] = (double) (i + 1) * step;
1.1 misho 122:
1.1.1.2 ! misho 123: for (n = h->h_index, i = 0; i < cfg->gc_width; i++) {
! 124: char * col = at_col(tbl->gt_table, i);
1.1 misho 125:
1.1.1.2 ! misho 126: if (--n < 0)
! 127: n = h->h_definition->hd_size - 1;
! 128: v = history_data(h, data, n);
! 129:
! 130: if (v == HISTORY_UNKNOWN) {
! 131: for (t = 0; t < cfg->gc_height; t++)
! 132: *(at_row(cfg, col, t)) = cfg->gc_unknown;
! 133: } else if (v > 0) {
! 134: *(at_row(cfg, col, 0)) = cfg->gc_noise;
! 135:
! 136: for (t = 0; t < cfg->gc_height; t++)
! 137: if (v >= (tbl->gt_scale[t] - half_step))
! 138: *(at_row(cfg, col, t)) = cfg->gc_foreground;
! 139: }
! 140: }
1.1 misho 141:
1.1.1.2 ! misho 142: n = (cfg->gc_height / 3) * 2;
! 143: if (n >= cfg->gc_height)
! 144: n = (cfg->gc_height - 1);
1.1 misho 145:
1.1.1.2 ! misho 146: v = unit_divisor(tbl->gt_scale[n], cfg->gc_unit,
! 147: &tbl->gt_y_unit, NULL);
! 148:
! 149: for (i = 0; i < cfg->gc_height; i++)
! 150: tbl->gt_scale[i] /= v;
1.1 misho 151: }
152:
1.1.1.2 ! misho 153: struct graph *graph_alloc(struct history *h, struct graph_cfg *cfg)
1.1 misho 154: {
1.1.1.2 ! misho 155: struct graph *g;
1.1 misho 156:
1.1.1.2 ! misho 157: if (!cfg->gc_height)
1.1 misho 158: BUG();
159:
1.1.1.2 ! misho 160: g = xcalloc(1, sizeof(*g));
1.1 misho 161:
1.1.1.2 ! misho 162: memcpy(&g->g_cfg, cfg, sizeof(*cfg));
1.1 misho 163:
1.1.1.2 ! misho 164: if (h != NULL &&
! 165: (cfg->gc_width > h->h_definition->hd_size || !cfg->gc_width))
! 166: g->g_cfg.gc_width = h->h_definition->hd_size;
! 167:
! 168: if (!g->g_cfg.gc_width)
! 169: BUG();
1.1 misho 170:
171: return g;
172: }
173:
1.1.1.2 ! misho 174: void graph_refill(struct graph *g, struct history *h)
1.1 misho 175: {
1.1.1.2 ! misho 176: fill_table(g, &g->g_rx, h, h ? &h->h_rx : NULL);
! 177: fill_table(g, &g->g_tx, h, h ? &h->h_tx : NULL);
1.1 misho 178: }
179:
1.1.1.2 ! misho 180: void graph_free(struct graph *g)
1.1 misho 181: {
1.1.1.2 ! misho 182: if (!g)
! 183: return;
! 184:
! 185: xfree(g->g_rx.gt_table);
! 186: xfree(g->g_rx.gt_scale);
! 187: xfree(g->g_tx.gt_table);
! 188: xfree(g->g_tx.gt_scale);
1.1 misho 189: xfree(g);
190: }
191:
1.1.1.2 ! misho 192: #if 0
! 193:
1.1 misho 194: void new_graph(void)
195: {
1.1.1.2 ! misho 196: if (ngraphs >= (MAX_GRAPHS - 1))
1.1 misho 197: return;
1.1.1.2 ! misho 198: set_ngraphs_hard(ngraphs + 1);
1.1 misho 199: }
200:
201: void del_graph(void)
202: {
1.1.1.2 ! misho 203: if (ngraphs <= 1)
1.1 misho 204: return;
1.1.1.2 ! misho 205: set_ngraphs_hard(ngraphs - 1);
1.1 misho 206: }
207:
208: int next_graph(void)
209: {
1.1.1.2 ! misho 210: struct item *it = item_current();
1.1 misho 211: if (it == NULL)
212: return EMPTY_LIST;
213:
1.1.1.2 ! misho 214: if (it->i_graph_sel >= (ngraphs - 1))
1.1 misho 215: it->i_graph_sel = 0;
216: else
217: it->i_graph_sel++;
218:
219: return 0;
220: }
221:
222: int prev_graph(void)
223: {
1.1.1.2 ! misho 224: struct item *it = item_current();
1.1 misho 225: if (it == NULL)
226: return EMPTY_LIST;
227:
228: if (it->i_graph_sel <= 0)
1.1.1.2 ! misho 229: it->i_graph_sel = ngraphs - 1;
1.1 misho 230: else
231: it->i_graph_sel--;
232:
233: return 0;
234: }
1.1.1.2 ! misho 235:
! 236: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>