@cryptotaxi247 / netdata-1 / commits / 518fb5967

convert nfacct to linked-list instead of array

Costa Tsaousis (ktsaou) committed Mar 17, 2017 at 01:36 UTC 518fb596709b39a374820471cb146f481f0b8340
1 file changed +57 -70
src/plugin_nfacct.c
+57 -70
@@ -4,8 +4,8 @@
4 #include <libmnl/libmnl.h>
5 #include <libnetfilter_acct/libnetfilter_acct.h>
6
7 -struct mynfacct {
8 - const char *name;
7 +struct nfacct_data {
8 + char *name;
9 uint32_t hash;
10
11 uint64_t pkts;
@@ -15,75 +15,58 @@ struct mynfacct {
15 RRDDIM *rd_packets;
16
17 int updated;
18 -};
18
20 -struct nfacct_list {
21 - int size;
22 - int len;
23 - struct mynfacct data[];
24 -} *nfacct_list = NULL;
19 + struct nfacct_data *next;
20 +};
21
26 -static inline void nfacct_list_grow() {
27 - if(!nfacct_list || nfacct_list->len == nfacct_list->size) {
28 - int size = (nfacct_list) ? nfacct_list->size : 0;
29 - int len = (nfacct_list) ? nfacct_list->len : 0;
30 - size++;
22 +static struct nfacct_list {
23 + struct nfacct *nfacct_buffer;
24 + struct nfacct_data *nfacct_metrics;
25 +} nfacct_root = {
26 + .nfacct_buffer = NULL,
27 + .nfacct_metrics = NULL
28 +};
29
32 - info("nfacct.plugin: increasing nfacct_list to size %d", size);
30 +static inline struct nfacct_data *nfacct_data_get(const char *name, uint32_t hash) {
31 + struct nfacct_data *d = NULL, *last = NULL;
32 + for(d = nfacct_root.nfacct_metrics; d ; last = d, d = d->next) {
33 + if(unlikely(d->hash == hash && !strcmp(d->name, name)))
34 + return d;
35 + }
36
34 - nfacct_list = reallocz(nfacct_list, sizeof(struct nfacct_list) + (sizeof(struct mynfacct) * size));
35 - memset(&nfacct_list->data[len], 0, sizeof(struct mynfacct));
37 + d = callocz(1, sizeof(struct nfacct_data));
38 + d->name = strdupz(name);
39 + d->hash = hash;
40
37 - nfacct_list->size = size;
38 - nfacct_list->len = len;
41 + if(!last) {
42 + d->next = nfacct_root.nfacct_metrics;
43 + nfacct_root.nfacct_metrics = d;
44 }
45 + else {
46 + d->next = last->next;
47 + last->next = d;
48 + }
49 +
50 + return d;
51 }
52
53 static int nfacct_callback(const struct nlmsghdr *nlh, void *data) {
54 (void)data;
55
45 - static struct nfacct *nfacct = NULL;
46 -
47 - if(unlikely(!nfacct)) {
48 - nfacct = nfacct_alloc();
49 - if(!nfacct) {
50 - error("nfacct.plugin: nfacct_alloc() failed.");
51 - return MNL_CB_OK;
52 - }
53 -
54 - if(unlikely(!nfacct_list))
55 - nfacct_list_grow();
56 - }
57 -
58 - if(nfacct_nlmsg_parse_payload(nlh, nfacct) < 0) {
56 + if(nfacct_nlmsg_parse_payload(nlh, nfacct_root.nfacct_buffer) < 0) {
57 error("nfacct.plugin: nfacct_nlmsg_parse_payload() failed.");
58 return MNL_CB_OK;
59 }
60
63 - const char *name = nfacct_attr_get_str(nfacct, NFACCT_ATTR_NAME);
61 + const char *name = nfacct_attr_get_str(nfacct_root.nfacct_buffer, NFACCT_ATTR_NAME);
62 uint32_t hash = simple_hash(name);
63
66 - int i;
67 - struct mynfacct *mynfacct = NULL;
68 - for(i = 0; i < nfacct_list->len; i++) {
69 - if(nfacct_list->data[i].hash == hash && !strcmp(nfacct_list->data[i].name, name)) {
70 - mynfacct = &nfacct_list->data[i];
71 - break;
72 - }
73 - }
74 -
75 - if(!mynfacct) {
76 - nfacct_list_grow();
77 - mynfacct = &nfacct_list->data[nfacct_list->len++];
78 - mynfacct->name = name;
79 - mynfacct->hash = hash;
80 - }
64 + struct nfacct_data *d = nfacct_data_get(name, hash);
65
82 - mynfacct->pkts = nfacct_attr_get_u64(nfacct, NFACCT_ATTR_PKTS);
83 - mynfacct->bytes = nfacct_attr_get_u64(nfacct, NFACCT_ATTR_BYTES);
84 - mynfacct->updated = 1;
66 + d->pkts = nfacct_attr_get_u64(nfacct_root.nfacct_buffer, NFACCT_ATTR_PKTS);
67 + d->bytes = nfacct_attr_get_u64(nfacct_root.nfacct_buffer, NFACCT_ATTR_BYTES);
68 + d->updated = 1;
69
86 - nfacct_list->len++;
70 return MNL_CB_OK;
71 }
72
@@ -98,6 +81,10 @@ void *nfacct_main(void *ptr) {
81 if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
82 error("nfacct.plugin: Cannot set pthread cancel state to ENABLE.");
83
84 + nfacct_root.nfacct_buffer = nfacct_alloc();
85 + if(!nfacct_root.nfacct_buffer)
86 + fatal("nfacct.plugin: nfacct_alloc() failed.");
87 +
88 char buf[MNL_SOCKET_BUFFER_SIZE];
89 struct mnl_socket *nl = NULL;
90 struct nlmsghdr *nlh = NULL;
@@ -161,8 +148,8 @@ void *nfacct_main(void *ptr) {
148
149 // --------------------------------------------------------------------
150
164 - if(nfacct_list && nfacct_list->len) {
165 - int i;
151 + if(nfacct_root.nfacct_metrics) {
152 + struct nfacct_data *d;
153
154 if(!st_packets) {
155 st_packets = rrdset_create_localhost(
@@ -180,12 +167,12 @@ void *nfacct_main(void *ptr) {
167 }
168 else rrdset_next(st_packets);
169
183 - for(i = 0; i < nfacct_list->len ; i++) {
184 - if(nfacct_list->data[i].updated) {
185 - if(unlikely(!nfacct_list->data[i].rd_packets))
186 - nfacct_list->data[i].rd_packets = rrddim_add(
170 + for(d = nfacct_root.nfacct_metrics; d ; d = d->next) {
171 + if(likely(d->updated)) {
172 + if(unlikely(!d->rd_packets))
173 + d->rd_packets = rrddim_add(
174 st_packets
188 - , nfacct_list->data[i].name
175 + , d->name
176 , NULL
177 , 1
178 , update_every
@@ -194,8 +181,8 @@ void *nfacct_main(void *ptr) {
181
182 rrddim_set_by_pointer(
183 st_packets
197 - , nfacct_list->data[i].rd_packets
198 - , (collected_number)nfacct_list->data[i].pkts
184 + , d->rd_packets
185 + , (collected_number)d->pkts
186 );
187 }
188 }
@@ -221,12 +208,12 @@ void *nfacct_main(void *ptr) {
208 }
209 else rrdset_next(st_bytes);
210
224 - for(i = 0; i < nfacct_list->len ; i++) {
225 - if(nfacct_list->data[i].updated) {
226 - if(unlikely(!nfacct_list->data[i].rd_bytes))
227 - nfacct_list->data[i].rd_bytes = rrddim_add(
211 + for(d = nfacct_root.nfacct_metrics; d ; d = d->next) {
212 + if(likely(d->updated)) {
213 + if(unlikely(!d->rd_bytes))
214 + d->rd_bytes = rrddim_add(
215 st_bytes
229 - , nfacct_list->data[i].name
216 + , d->name
217 , NULL
218 , 1
219 , 1000 * update_every
@@ -235,8 +222,8 @@ void *nfacct_main(void *ptr) {
222
223 rrddim_set_by_pointer(
224 st_bytes
238 - , nfacct_list->data[i].rd_bytes
239 - , (collected_number)nfacct_list->data[i].bytes
225 + , d->rd_bytes
226 + , (collected_number)d->bytes
227 );
228 }
229 }
@@ -247,8 +234,8 @@ void *nfacct_main(void *ptr) {
234 // ----------------------------------------------------------------
235 // prepare for the next loop
236
250 - for(i = 0; i < nfacct_list->len ; i++)
251 - nfacct_list->data[i].updated = 0;
237 + for(d = nfacct_root.nfacct_metrics; d ; d = d->next)
238 + d->updated = 0;
239 }
240 }
241