#include #include #include "inbuf.h" #include "outbuf.h" #include "strerr.h" #include "seek.h" #include "cdb.h" #ifdef CDB64 #define FATAL "cdb64stats: fatal: " #else #define FATAL "cdbstats: fatal: " #endif static void die_read(void) { strerr_die2sys(111,FATAL,"unable to read input: "); } static void die_readformat(void) { strerr_die2x(111,FATAL,"unable to read input: truncated file"); } static void die_write(void) { strerr_die2sys(111,FATAL,"unable to write output: "); } static void put(char *buf,num len) { if (outbuf_put(outbuf_1small,buf,len) == -1) die_write(); } static void putflush(void) { if (outbuf_flush(outbuf_1small) == -1) die_write(); } static num pos = 0; static void get(char *buf,num len) { num r; while (len > 0) { r = inbuf_get(inbuf_0,buf,len); if (r == -1) die_read(); if (r == 0) die_readformat(); pos += r; buf += r; len -= r; } } static num getnum(void) { char buf[CDB_NUMBYTES]; num result; get(buf,CDB_NUMBYTES); result = cdb_unpacknum(buf); if (result < 0 || result > CDB_LIMIT) strerr_die2x(111,FATAL,"unable to read input: malformatted file"); return result; } static char strnum[NUM_TOSTRING_NONNEG]; static void putnum(char *label,num count) { num i; put(label,strlen(label)); for (i = num_tostring_nonneg(0,count);i < 10;++i) put(" ",1); put(strnum,num_tostring_nonneg(strnum,count)); put("\n",1); } static char key[1024]; static struct cdb c; static num numrecords; static num numd[11]; int main(int argc,char **argv) { num eod; num klen; num dlen; num rest; cdb_init(&c,0); eod = getnum(); while (pos < 256*2*CDB_NUMBYTES) dlen = getnum(); while (pos < eod) { klen = getnum(); dlen = getnum(); if (klen > sizeof key) { while (klen) { get(key,1); --klen; } } else { get(key,klen); rest = seek_cur(0); cdb_findstart(&c); do { switch(cdb_findnext(&c,key,klen)) { case -1: die_read(); case 0: die_readformat(); } } while (cdb_datapos(&c) != pos); if (!c.loop) die_readformat(); ++numrecords; if (c.loop > 10) ++numd[10]; else ++numd[c.loop - 1]; if (seek_set(0,rest) == -1) die_read(); } while (dlen) { get(key,1); --dlen; } } putnum("records ",numrecords); putnum("d0 ",numd[0]); putnum("d1 ",numd[1]); putnum("d2 ",numd[2]); putnum("d3 ",numd[3]); putnum("d4 ",numd[4]); putnum("d5 ",numd[5]); putnum("d6 ",numd[6]); putnum("d7 ",numd[7]); putnum("d8 ",numd[8]); putnum("d9 ",numd[9]); putnum(">9 ",numd[10]); putflush(); _exit(0); return 0; }