]> jfr.im git - irc/quakenet/newserv.git/blame - graphing/fsample.h
Lua version now excludes "Lua engine", at least for MODULEVERSION.
[irc/quakenet/newserv.git] / graphing / fsample.h
CommitLineData
a6755701
CP
1#ifndef __FSAMPLE_H
2#define __FSAMPLE_H
3
4#include <sys/types.h>
5
6typedef u_int32_t fsample_t;
7
8typedef struct fsample fsample;
9
45eadff3
CP
10/* nice loss of type safety here... */
11typedef void *(*CoreHandlerAddFn)(void *handler, void *arg);
12typedef void (*CoreHandlerDelFn)(void *);
13
a6755701 14/* single sample functions */
45eadff3 15fsample *fsopen(char *filename, size_t samples, CoreHandlerAddFn chafn, CoreHandlerDelFn chdfn);
a6755701 16void fsclose(fsample *f);
a6755701
CP
17
18struct fsample_m;
19typedef fsample_t (*DeriveValueFn)(struct fsample_m *v, int entry, fsample_t pos, void *tag);
8186335d
CP
20
21typedef struct fsample_m_entry {
a6755701
CP
22 size_t freq;
23 fsample *f;
24 void *tag;
25 DeriveValueFn derive;
26} fsample_m_entry;
27
28typedef struct fsample_m {
8186335d 29 size_t pos, samples;
45eadff3
CP
30 CoreHandlerAddFn chafn;
31 CoreHandlerDelFn chdfn;
a6755701
CP
32 struct fsample_m_entry entry[];
33} fsample_m;
34
35/* multiple sample functions */
45eadff3 36fsample_m *fsopen_m(size_t count, char *filename, size_t samples, CoreHandlerAddFn chafn, CoreHandlerDelFn chdfn);
a6755701
CP
37void fsclose_m(fsample_m *f);
38int fsadd_m(fsample_m *f, char *filename, size_t freq, DeriveValueFn derive, void *tag);
39void fsset_m(fsample_m *f, fsample_t pos, fsample_t value);
a6755701
CP
40
41/* aggregates */
42fsample_t fsamean(fsample_m *f, int entry, fsample_t pos, void *tag);
43fsample_t fsapmean(fsample_m *f, int entry, fsample_t pos, void *tag);
44
d8b17362
CP
45struct fsample_p {
46 fsample_t v;
47 unsigned char iteration;
48};
49
50struct fsample_header {
51 char magic[4];
52 fsample_t version;
53 unsigned char iteration;
54 fsample_t lastpos;
55};
56
57struct fsample {
58 struct fsample_p *m;
59 int fd;
60 size_t samples, len;
61 struct fsample_header *header;
62 void *corehandler;
63 CoreHandlerDelFn corehandlerdel;
64};
65
66static inline unsigned char previteration(fsample *f) {
67 unsigned char p = f->header->iteration - 1;
68 if(p == 0)
69 p = 255;
70 return p;
71}
72
73/* doesn't support writing to negative numbers... */
74static inline void fsset(fsample *f, fsample_t pos, fsample_t value) {
75 fsample_t actualpos = pos % f->samples;
76 struct fsample_p *p = &f->m[actualpos];
77
78 if(f->header->lastpos > actualpos) {
79 f->header->iteration++;
80 if(f->header->iteration == 0)
81 f->header->iteration = 1;
82 }
83
84 f->header->lastpos = actualpos;
85
86 p->iteration = f->header->iteration;
87 p->v = value;
88}
89
90static inline fsample_t mmod(int x, int y) {
91#if -5 % 3 == -2
92 int v = x % y;
93 if(v < 0)
94 v = v + y;
95 return v;
96#else
97#error Unknown modulo operator function.
98#endif
99}
100
101/* API functions only have access to positive indicies */
102static inline fsample_t __fsget(fsample *f, int pos, fsample_t *t) {
103 struct fsample_p *p = &f->m[mmod(pos, f->samples)];
104
105 if(p->iteration != f->header->iteration) {
106 unsigned char prev = previteration(f);
107
108 if(prev != p->iteration || (pos <= f->header->lastpos)) {
109 /*printf("bad: prev: %d p->iteration: %d, pos: %d lastpos: %d\n", prev, p->iteration, pos, f->header->lastpos);*/
110 return 0;
111 }
112 }
113
114 *t = p->v;
115 return p->iteration;
116}
117
118static inline fsample_t fsget_r(fsample *f, fsample_t pos, fsample_t *t) {
119 struct fsample_p *p = &f->m[mmod(pos, f->samples)];
120
121 *t = p->v;
122 return p->iteration;
123}
124
125static inline fsample_t fsget(fsample *f, fsample_t pos, fsample_t *t) {
126 return __fsget(f, pos, t);
127}
128
129static inline fsample_t __fsget_m(fsample_m *f, int entry, int pos, fsample_t *t) {
130 return __fsget(f->entry[entry].f, pos / f->entry[entry].freq, t);
131}
132
133static inline fsample_t fsget_m(fsample_m *f, int entry, fsample_t pos, fsample_t *t) {
134 return fsget(f->entry[entry].f, pos / f->entry[entry].freq, t);
135}
136
137static inline fsample_t fsget_mr(fsample_m *f, int entry, fsample_t pos, fsample_t *t) {
138 return fsget_r(f->entry[entry].f, pos / f->entry[entry].freq, t);
139}
140
a6755701 141#endif