Annotation of embedaddon/bmon/src/graph.c, revision 1.1.1.3
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 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: }
1.1 misho 74:
1.1.1.2 misho 75: memset(tbl->gt_table, cfg->gc_background, table_size(cfg));
1.1 misho 76:
1.1.1.2 misho 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';
1.1 misho 80:
1.1.1.2 misho 81: /* leave table blank if there is no data */
82: if (!h || !data->hs_data)
83: return;
1.1 misho 84:
1.1.1.2 misho 85: if (cfg->gc_width > h->h_definition->hd_size)
86: BUG();
1.1 misho 87:
1.1.1.2 misho 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: }
1.1 misho 96:
1.1.1.2 misho 97: step = (double) max / (double) cfg->gc_height;
98: half_step = step / 2.0f;
1.1 misho 99:
1.1.1.2 misho 100: for (i = 0; i < cfg->gc_height; i++)
101: tbl->gt_scale[i] = (double) (i + 1) * step;
1.1 misho 102:
1.1.1.2 misho 103: for (n = h->h_index, i = 0; i < cfg->gc_width; i++) {
104: char * col = at_col(tbl->gt_table, i);
1.1 misho 105:
1.1.1.2 misho 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: }
1.1 misho 121:
1.1.1.2 misho 122: n = (cfg->gc_height / 3) * 2;
123: if (n >= cfg->gc_height)
124: n = (cfg->gc_height - 1);
1.1 misho 125:
1.1.1.2 misho 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;
1.1 misho 131: }
132:
1.1.1.2 misho 133: struct graph *graph_alloc(struct history *h, struct graph_cfg *cfg)
1.1 misho 134: {
1.1.1.2 misho 135: struct graph *g;
1.1 misho 136:
1.1.1.2 misho 137: if (!cfg->gc_height)
1.1 misho 138: BUG();
139:
1.1.1.2 misho 140: g = xcalloc(1, sizeof(*g));
1.1 misho 141:
1.1.1.2 misho 142: memcpy(&g->g_cfg, cfg, sizeof(*cfg));
1.1 misho 143:
1.1.1.2 misho 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();
1.1 misho 150:
151: return g;
152: }
153:
1.1.1.2 misho 154: void graph_refill(struct graph *g, struct history *h)
1.1 misho 155: {
1.1.1.2 misho 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);
1.1 misho 158: }
159:
1.1.1.2 misho 160: void graph_free(struct graph *g)
1.1 misho 161: {
1.1.1.2 misho 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);
1.1 misho 169: xfree(g);
170: }
171:
1.1.1.2 misho 172: #if 0
173:
1.1 misho 174: void new_graph(void)
175: {
1.1.1.2 misho 176: if (ngraphs >= (MAX_GRAPHS - 1))
1.1 misho 177: return;
1.1.1.2 misho 178: set_ngraphs_hard(ngraphs + 1);
1.1 misho 179: }
180:
181: void del_graph(void)
182: {
1.1.1.2 misho 183: if (ngraphs <= 1)
1.1 misho 184: return;
1.1.1.2 misho 185: set_ngraphs_hard(ngraphs - 1);
1.1 misho 186: }
187:
188: int next_graph(void)
189: {
1.1.1.2 misho 190: struct item *it = item_current();
1.1 misho 191: if (it == NULL)
192: return EMPTY_LIST;
193:
1.1.1.2 misho 194: if (it->i_graph_sel >= (ngraphs - 1))
1.1 misho 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: {
1.1.1.2 misho 204: struct item *it = item_current();
1.1 misho 205: if (it == NULL)
206: return EMPTY_LIST;
207:
208: if (it->i_graph_sel <= 0)
1.1.1.2 misho 209: it->i_graph_sel = ngraphs - 1;
1.1 misho 210: else
211: it->i_graph_sel--;
212:
213: return 0;
214: }
1.1.1.2 misho 215:
216: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>