#include <u.h>
#include <libc.h>
#include <thread.h>
#include <bio.h>
#include "collectd.h"
Packet *phead;
Lock plock;
Packet *
palloc(void)
{
Packet *pp;
if(phead == nil)
return emalloc(sizeof *pp);
lock(&plock);
pp = phead;
phead = pp->next;
unlock(&plock);
memset(pp, 0, sizeof *pp);
return pp;
}
void
pfree(Packet *pp)
{
Value *p, *v;
free(pp->host);
free(pp->plugin);
free(pp->pinst);
free(pp->type);
free(pp->tinst);
v = pp->head;
while(p = v){
v = v->next;
free(p);
}
lock(&plock);
pp->next = phead;
phead = pp;
unlock(&plock);
}
static Value *
nextvalue(Packet *pp)
{
Value *v;
v = emalloc(sizeof *v);
if(pp->head == nil)
pp->head = v;
else
pp->tail->next = v;
pp->tail = v;
pp->nval++;
return v;
}
void
addcounter(Packet *pp, uvlong counter)
{
Value *v;
v = nextvalue(pp);
v->type = DS_TYPE_COUNTER;
v->lval = counter;
}
void
addgauge(Packet *pp, double gauge)
{
Value *v;
v = nextvalue(pp);
v->type = DS_TYPE_GAUGE;
v->dval = gauge;
}
void
addderive(Packet *pp, vlong derive)
{
Value *v;
v = nextvalue(pp);
v->type = DS_TYPE_DERIVE;
v->lval = derive;
}
void
addabs(Packet *pp, uvlong abs)
{
Value *v;
v = nextvalue(pp);
v->type = DS_TYPE_ABSOLUTE;
v->lval = abs;
}
static uchar *
putbe(uchar *p, uchar *e, uvlong lval, uint nbytes)
{
while(p < e && nbytes--)
*p++ = lval>>8*nbytes;
return p;
}
static uchar *
putle(uchar *p, uchar *e, uvlong lval, uint nbytes)
{
while(p < e && nbytes--){
*p++ = lval;
lval >>= 8;
}
return p;
}
static uchar *
putstr(uchar *p, uchar *e, char *s)
{
uint nbytes;
nbytes = strlen(s)+1;
while(p < e && nbytes--)
*p++ = *s++;
return p;
}
uint
convS2P(Packet *pp, uchar *buf, uint nbytes)
{
uchar *p, *e;
Value *v;
p = buf;
e = p + nbytes;
p = putbe(p, e, TYPE_HOST, sizeof(u16int));
p = putbe(p, e, sizeSP2P(pp->host), sizeof(u16int));
p = putstr(p, e, pp->host);
p = putbe(p, e, TYPE_TIME, sizeof(u16int));
p = putbe(p, e, sizeNP2P(pp->time), sizeof(u16int));
p = putbe(p, e, pp->time, sizeof(u64int));
p = putbe(p, e, TYPE_PLUGIN, sizeof(u16int));
p = putbe(p, e, sizeSP2P(pp->plugin), sizeof(u16int));
p = putstr(p, e, pp->plugin);
if(pp->pinst){
p = putbe(p, e, TYPE_PLUGIN_INSTANCE, sizeof(u16int));
p = putbe(p, e, sizeSP2P(pp->pinst), sizeof(u16int));
p = putstr(p, e, pp->pinst);
}
p = putbe(p, e, TYPE_TYPE, sizeof(u16int));
p = putbe(p, e, sizeSP2P(pp->type), sizeof(u16int));
p = putstr(p, e, pp->type);
if(pp->tinst){
p = putbe(p, e, TYPE_TYPE_INSTANCE, sizeof(u16int));
p = putbe(p, e, sizeSP2P(pp->tinst), sizeof(u16int));
p = putstr(p, e, pp->tinst);
}
p = putbe(p, e, TYPE_VALUES, sizeof(u16int));
p = putbe(p, e, sizeVP2P(pp->nval), sizeof(u16int));
p = putbe(p, e, pp->nval, sizeof(u16int));
for(v = pp->head; v != nil; v = v->next)
if(p < e) *p++ = v->type;
for(v = pp->head; v != nil; v = v->next)
if(v->type == DS_TYPE_GAUGE)
p = putle(p, e, v->lval, sizeof(u64int));
else
p = putbe(p, e, v->lval, sizeof(u64int));
p = putbe(p, e, TYPE_INTERVAL, sizeof(u16int));
p = putbe(p, e, sizeNP2P(pp->interval), sizeof(u16int));
p = putbe(p, e, pp->interval, sizeof(u64int));
return p - buf;
}
uint
sizeNP2P(uvlong)
{
return sizeof(u16int) + /* Type */
sizeof(u16int) + /* Length */
sizeof(u64int); /* Number */
}
uint
sizeSP2P(char *s)
{
return sizeof(u16int) + /* Type */
sizeof(u16int) + /* Length */
strlen(s)+1; /* String */
}
uint
sizeVP2P(uint nval)
{
return sizeof(u16int) + /* Type */
sizeof(u16int) + /* Length */
sizeof(u16int) + /* Num Values */
sizeof(u8int)*nval + /* Data Types */
sizeof(u64int)*nval; /* Values */
}
|