10 typedef struct ANode ANode;
21 static Avltree **trees;
26 aggcmp(Avl *ap, Avl *bp)
32 return memcmp(a->key, b->key, a->keysize);
36 createrecord(int type, ANode *n, s64int *q)
39 case AGGCNT: n->cnt = q[0]; break;
40 case AGGSUM: case AGGMIN: case AGGMAX: n->val = q[0]; break;
41 case AGGAVG: n->cnt = q[1]; n->val = q[0]; break;
42 case AGGSTD: n->cnt = q[1]; n->val = q[0]; n->sq[0] = q[2]; n->sq[1] = q[3]; break;
48 updaterecord(int type, ANode *n, s64int *q)
53 case AGGCNT: n->cnt += q[0]; break;
54 case AGGSUM: n->val += q[0]; break;
55 case AGGAVG: n->cnt += q[1]; n->val += q[0]; break;
60 if(r < q[2]) n->sq[1]++;
70 aggparsebuf(uchar *p, int n)
79 for(; p + 8 < e; p += a->recsize){
81 if((u16int)id >= aggid){
83 fprint(2, "invalid record in aggregation buffer\n");
86 a = &aggs[(u16int)id];
87 if(a->type != id>>28) goto inval;
88 if(a->keysize != (id>>13&0x7ff8)) goto inval;
89 if(p + a->recsize > e) goto inval;
90 tp = trees[(u16int)id];
91 key->keysize = a->keysize;
92 memcpy(key->key, &p[8], a->keysize);
93 np = (ANode *) avllookup(tp, key, 0);
95 np = emalloc(sizeof(ANode) - 1 + a->keysize);
97 createrecord(a->type, np, (s64int*)&p[8+a->keysize]);
100 updaterecord(a->type, np, (s64int*)&p[8+a->keysize]);
110 trees = emalloc(sizeof(Avltree *) * aggid);
112 for(i = 0; i < aggid; i++){
113 trees[i] = avlcreate(aggcmp);
114 if(aggs[i].keysize > m)
117 key = emalloc(sizeof(ANode) - 1 + m);
121 aggnote(void *, char *note)
123 if(strcmp(note, "interrupt") != 0 || interrupted)
130 aggkeyprint(Fmt *f, Agg *, ANode *a)
132 fmtprint(f, "%20lld ", *(u64int*)a->key);
141 x = vtomp(a->val, nil);
142 y = uvtomp(a->sq[0], nil);
143 z = vtomp(a->sq[1], nil);
150 r = mptod(x) / a->cnt;
158 aggvalprint(Fmt *f, int type, ANode *a)
163 case AGGCNT: fmtprint(f, "%20lld", a->cnt); break;
164 case AGGSUM: case AGGMIN: case AGGMAX: fmtprint(f, "%20lld", a->val); break;
165 case AGGAVG: fmtprint(f, "%20g", (double)a->val / a->cnt); break;
167 x = (double)a->val / a->cnt;
170 fmtprint(f, "%20g %20s", x, "NaN");
172 fmtprint(f, "%20g %20g", x, sqrt(s));
188 fmtfdinit(&f, 1, buf, sizeof(buf));
189 for(i = 0; i < aggid; i++){
190 a = (ANode *) avlmin(trees[i]);
191 for(; a != nil; a = (ANode *) avlnext(a)){
192 fmtprint(&f, "%s\t", aggs[i].name);
193 aggkeyprint(&f, &aggs[i], a);
194 aggvalprint(&f, aggs[i].type, a);