]> jfr.im git - irc/quakenet/newserv.git/blob - graphing/fsample.h
Export printchannels in newsearch.
[irc/quakenet/newserv.git] / graphing / fsample.h
1 #ifndef __FSAMPLE_H
2 #define __FSAMPLE_H
3
4 #include <sys/types.h>
5
6 typedef u_int32_t fsample_t;
7
8 typedef struct fsample fsample;
9
10 /* nice loss of type safety here... */
11 typedef void *(*CoreHandlerAddFn)(void *handler, void *arg);
12 typedef void (*CoreHandlerDelFn)(void *);
13
14 /* single sample functions */
15 fsample *fsopen(char *filename, size_t samples, CoreHandlerAddFn chafn, CoreHandlerDelFn chdfn);
16 void fsclose(fsample *f);
17
18 struct fsample_m;
19 typedef fsample_t (*DeriveValueFn)(struct fsample_m *v, int entry, fsample_t pos, void *tag);
20
21 typedef struct fsample_m_entry {
22 size_t freq;
23 fsample *f;
24 void *tag;
25 DeriveValueFn derive;
26 } fsample_m_entry;
27
28 typedef struct fsample_m {
29 size_t pos, samples;
30 CoreHandlerAddFn chafn;
31 CoreHandlerDelFn chdfn;
32 struct fsample_m_entry entry[];
33 } fsample_m;
34
35 /* multiple sample functions */
36 fsample_m *fsopen_m(size_t count, char *filename, size_t samples, CoreHandlerAddFn chafn, CoreHandlerDelFn chdfn);
37 void fsclose_m(fsample_m *f);
38 int fsadd_m(fsample_m *f, char *filename, size_t freq, DeriveValueFn derive, void *tag);
39 void fsset_m(fsample_m *f, fsample_t pos, fsample_t value);
40
41 /* aggregates */
42 fsample_t fsamean(fsample_m *f, int entry, fsample_t pos, void *tag);
43 fsample_t fsapmean(fsample_m *f, int entry, fsample_t pos, void *tag);
44
45 struct fsample_p {
46 fsample_t v;
47 unsigned char iteration;
48 };
49
50 struct fsample_header {
51 char magic[4];
52 fsample_t version;
53 unsigned char iteration;
54 fsample_t lastpos;
55 };
56
57 struct 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
66 static 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... */
74 static 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
90 static 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 */
102 static 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
118 static 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
125 static inline fsample_t fsget(fsample *f, fsample_t pos, fsample_t *t) {
126 return __fsget(f, pos, t);
127 }
128
129 static 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
133 static 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
137 static 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
141 #endif