File: cdbstats.c

package info (click to toggle)
freecdb 0.78.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 728 kB
  • sloc: ansic: 1,733; sh: 360; makefile: 25
file content (137 lines) | stat: -rw-r--r-- 3,543 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <sys/types.h>
#include <unistd.h>
#include "strerr.h"
#include "cdb.h"
#include "buffer.h"
#include "seek.h"
#include "fmt.h"

#define USAGE ""
#define FATAL "cdbstats: fatal: "

#define BUFSIZE 1024

const char *progname;
static struct cdb c;
char buf[BUFSIZE];

void usage() { strerr_die4x(100, "usage: ", progname, USAGE, "\n"); }

void getb(char *b, unsigned int len) {
  unsigned int l;

  while (len) {
    switch ((l =buffer_get(buffer_0, b, len))) {
    case 0: strerr_die2x(111, FATAL, "unable to read input: truncated file");
    case -1: strerr_die2sys(111, FATAL, "unable to read input: ");
    }
    len -=l; b +=l;
  }
}
void put1(char *s, unsigned int l) {
  if (buffer_put(buffer_1, s, l) == -1)
    strerr_die2sys(111, FATAL, "unable to write output: ");
}

int main(int argc, char **argv) {
  uint32 pos;
  uint32 eodata;
  uint32 keylen;
  uint32 datalen;
  char num[FMT_ULONG];
  unsigned long records;
  unsigned long distance[11];
  off_t rest;
  int i, j;

  progname =*argv++;
  if (*argv) usage();
  pos =0;
  records =0;
  for (i =0; i < 11; ++i) distance[i] =0;

  cdb_init(&c,0);

  /* read data size */
  getb(buf, 4);
  pos +=4;
  uint32_unpack(buf, &eodata);
  /* data starts after 2048 bytes */
  while (pos < 2048) {
    getb(buf, (2048 -pos) < BUFSIZE ? (2048 -pos) : BUFSIZE);
    pos +=(2048 -pos) < BUFSIZE ? (2048 -pos) : BUFSIZE;
  }
  while (pos < eodata) {
    /* keylen */
    getb(buf, 4);
    pos +=4;
    uint32_unpack(buf, &keylen);
    /* datalen */
    getb(buf, 4);
    pos +=4;
    uint32_unpack(buf, &datalen);

    /* skip keys with len > BUFSIZE */
    if (keylen > BUFSIZE) {
      while (keylen) {
	getb(buf, keylen < BUFSIZE ? keylen : BUFSIZE);
	pos +=keylen < BUFSIZE ? keylen : BUFSIZE;
	keylen -=keylen < BUFSIZE ? keylen : BUFSIZE;
      }
    }
    /* lookup records */
    else {
      /* get keylen */
      getb(buf, keylen);
      pos +=keylen;
      /* save file pos */
      rest =lseek(0, (off_t) 0, SEEK_CUR);
      /* lookup this record */
      cdb_findstart(&c);
      do {
        switch(cdb_findnext(&c, buf, keylen)) {
	case -1: strerr_die2sys(111, FATAL, "unable to read input: ");
	case 0: strerr_die2x(111,FATAL,"unable to read input: truncated file");
        }
      } while (cdb_datapos(&c) != pos);
      if (!c.loop)
	strerr_die2x(111,FATAL,"unable to read input: truncated file");
      /* count records */
      ++records;
      /* count records with specific distance */
      if (c.loop > 10) ++distance[10]; else ++distance[c.loop -1];
      /* reset file pos */
      if (seek_set(0, rest) == -1)
	strerr_die2sys(111, FATAL, "unable to read input: ");
    }
    /* skip data */
    while (datalen) {
      getb(buf, datalen < BUFSIZE ? datalen : BUFSIZE);
      pos +=datalen < BUFSIZE ? datalen : BUFSIZE;
      datalen -=datalen < BUFSIZE ? datalen : BUFSIZE;
    }
  }
  /* format output stats */
  put1("records ", 8);
  for (i =fmt_ulong(0, records); i < 10; ++i)
    put1(" ", 1);
  put1(num, fmt_ulong(num, records));
  put1("\n", 1);
  for (j =0; j < 10; ++j) {
    put1("d", 1);
    put1(num, fmt_ulong(num, j));
    put1("      ", 6);
    for (i =fmt_ulong(0, distance[j]); i < 10; ++i)
      put1(" ", 1);
    put1(num, fmt_ulong(num, distance[j]));
    put1("\n", 1);
  }
  put1(">9      ", 8);
  for (i =fmt_ulong(0, distance[j]); i < 10; ++i)
    put1(" ", 1);
  put1(num, fmt_ulong(num, distance[j]));
  put1("\n", 1);
  if (buffer_flush(buffer_1) == -1)
    strerr_die2sys(111, FATAL, "unable to flush output: ");
  _exit(0);
}