]> jfr.im git - irc/quakenet/newserv.git/blame - graphing/fsample.c
Lua version now excludes "Lua engine", at least for MODULEVERSION.
[irc/quakenet/newserv.git] / graphing / fsample.c
CommitLineData
a6755701
CP
1#include "fsample.h"
2
3#include <sys/types.h>
4#include <sys/uio.h>
5#include <unistd.h>
6#include <sys/mman.h>
7#include <fcntl.h>
8#include <stdlib.h>
8186335d 9#include <string.h>
a6755701 10
8186335d
CP
11static fsample_t version = 1;
12
45eadff3
CP
13static void fscorefree(void *arg) {
14 fsample *f = (fsample *)arg;
15 munmap(f->header, f->len);
16}
17
18fsample *fsopen(char *filename, size_t samples, CoreHandlerAddFn chafn, CoreHandlerDelFn chdfn) {
d4e7ae7a 19 int flags = 0;
8186335d 20 int new = 0;
a6755701
CP
21 fsample *f = (fsample *)malloc(sizeof(fsample));
22 if(!f)
23 return NULL;
24
25 f->len = samples * sizeof(struct fsample_p) + sizeof(struct fsample_header);
26 f->fd = open(filename, O_RDWR|O_CREAT, 0600);
27
8186335d
CP
28 if(!lseek(f->fd, 0, SEEK_END))
29 new = 1;
30
a6755701
CP
31 if((f->fd == -1) || (lseek(f->fd, f->len - 1, SEEK_SET) == -1)) {
32 free(f);
33 return NULL;
34 }
35 write(f->fd, "", 1);
36
d4e7ae7a
CP
37 flags = MAP_SHARED;
38#ifdef MAP_NOCORE
39 flags|=MAP_NOCORE;
40#endif
41
42 f->header = mmap(NULL, f->len, PROT_READ|PROT_WRITE, flags, f->fd, 0);
8186335d
CP
43 if(f->header == MAP_FAILED) {
44 close(f->fd);
45 free(f);
46 return NULL;
47 }
48
49 if(!new && (memcmp(f->header->magic, "FSAMP", sizeof(f->header->magic)) || (version != f->header->version))) {
45eadff3 50 munmap(f->header, f->len);
a6755701
CP
51 close(f->fd);
52 free(f);
53 return NULL;
54 }
55
be606ed1 56 if(chafn && chdfn) {
45eadff3
CP
57 f->corehandler = chafn(fscorefree, f);
58 f->corehandlerdel = chdfn;
59 } else {
60 f->corehandler = NULL;
61 f->corehandlerdel = NULL;
62 }
63
8186335d
CP
64 memcpy(f->header->magic, "FSAMP", sizeof(f->header->magic));
65 f->header->version = version;
66
67 f->m = (struct fsample_p *)(f->header + 1);
a6755701
CP
68 f->samples = samples;
69
70 if(f->header->iteration == 0)
71 f->header->iteration = 1;
72
73 return f;
74}
75
76void fsclose(fsample *f) {
45eadff3 77 munmap(f->header, f->len);
a6755701 78 close(f->fd);
45eadff3
CP
79
80 if(f->corehandlerdel && f->corehandler)
81 (f->corehandlerdel)(f->corehandler);
82
a6755701
CP
83 free(f);
84}
85
a6755701 86int fsadd_m(fsample_m *f, char *filename, size_t freq, DeriveValueFn derive, void *tag) {
45eadff3 87 fsample_m_entry *p = &f->entry[f->pos];
a6755701 88
45eadff3
CP
89 p->f = fsopen(filename, f->samples / freq, f->chafn, f->chdfn);
90 if(!p->f)
a6755701
CP
91 return 0;
92
b88719fa 93 p->freq = freq;
45eadff3
CP
94 p->derive = derive;
95 p->tag = tag;
a6755701
CP
96 f->pos++;
97 return 1;
98}
99
45eadff3 100fsample_m *fsopen_m(size_t count, char *filename, size_t samples, CoreHandlerAddFn chafn, CoreHandlerDelFn chdfn) {
a6755701
CP
101 fsample_m *n = (fsample_m *)malloc(sizeof(fsample_m) + (count + 1) * sizeof(fsample_m_entry));
102 if(!n)
103 return NULL;
104
105 n->samples = samples;
106 n->pos = 0;
45eadff3
CP
107 n->chafn = chafn;
108 n->chdfn = chdfn;
a6755701
CP
109
110 if(!fsadd_m(n, filename, 1, NULL, 0)) {
111 free(n);
112 return NULL;
113 }
114
115 return n;
116}
117
118void fsset_m(fsample_m *f, fsample_t pos, fsample_t value) {
119 int i;
120
121 for(i=0;i<f->pos;i++) {
122 fsample_t v;
123
124 if((pos + 1) % f->entry[i].freq != 0)
125 continue;
126
127 if(f->entry[i].derive) {
128 v = (f->entry[i].derive)(f, i, pos, f->entry[i].tag);
129 } else {
130 v = value;
131 }
132
133 fsset(f->entry[i].f, pos / f->entry[i].freq, v);
134 }
135}
136
137void fsclose_m(fsample_m *f) {
138 int i;
139
140 for(i=0;i<f->pos;i++)
141 fsclose(f->entry[i].f);
142 free(f);
143}
144
a6755701
CP
145fsample_t fsamean(fsample_m *f, int entry, fsample_t pos, void *tag) {
146 fsample_t c = 0;
147 long samples = (long)tag;
148 int count = 0;
149 int rpos = pos / f->entry[0].freq;
150 int i;
151 fsample_t t;
152
153 for(i=0;i<samples;i++) {
154 if(__fsget_m(f, 0, rpos - i, &t)) {
155 c+=t;
156 count++;
157 } else {
158/* printf("bad :(\n");*/
159 }
160 }
161
162 if(count == 0)
163 return 0;
164
165 return c / count;
166}
167
168fsample_t fsapmean(fsample_m *f, int entry, fsample_t pos, void *tag) {
169 fsample_t c = 0;
170 long samples = (long)tag;
171 int count = 0;
172 int rpos = pos / f->entry[entry - 1].freq;
173 int i;
174 fsample_t t;
175
176 for(i=0;i<=samples;i++) {
177 if(__fsget(f->entry[entry - 1].f, rpos - i, &t)) {
178 c+=t;
179 count++;
180 } else {
181 /*printf("bad :(\n");*/
182 }
183 }
184
185 if(count == 0)
186 return 0;
187
188 return c / count;
189}