align block sizes for isam sys. Better plot for test
[idzebra-moved-to-github.git] / index / invstat.c
1 /*
2  * Copyright (C) 1994-1999, Index Data
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss, Heikki Levanto
5  * log at eof
6  *
7  */
8 #include <stdio.h>
9 #include <assert.h>
10 #include <string.h>
11
12 #include "index.h"
13 #include "../isamc/isamd-p.h"
14
15 struct inv_stat_info {
16     ZebraHandle zh;
17     int no_isam_entries[9];
18     int no_dict_entries;
19     int no_dict_bytes;
20     int isam_bounds[20];
21     int isam_occurrences[20];
22     char tmp[128];
23     int isamb_levels[10][5];
24     int isamb_sizes[10];
25     int isamb_blocks[10];
26     unsigned long cksum;
27 };
28
29 #define SINGLETON_TYPE 8 /* the type to use for singletons that */ 
30                          /* have no block and no block type */
31
32 static int inv_stat_handle (char *name, const char *info, int pos,
33                             void *client)
34 {
35     int occur = 0;
36     int i = 0;
37     struct inv_stat_info *stat_info = (struct inv_stat_info*) client;
38     ISAMS_P isam_p;
39
40     stat_info->no_dict_entries++;
41     stat_info->no_dict_bytes += strlen(name);
42
43     assert (*info == sizeof(ISAMS_P));
44     memcpy (&isam_p, info+1, sizeof(ISAMS_P));
45
46     if (stat_info->zh->reg->isams)
47     {
48         ISAMS_PP pp;
49         int occurx = 0;
50         struct it_key key;
51
52         pp = isams_pp_open (stat_info->zh->reg->isams, isam_p);
53         occur = isams_pp_num (pp);
54         while (isams_pp_read(pp, &key))
55         {
56             stat_info->cksum = stat_info->cksum * 65509 + 
57                 key.sysno + 11 * key.seqno;
58             occurx++;
59         }
60         assert (occurx == occur);
61         stat_info->no_isam_entries[0] += occur;
62         isams_pp_close (pp);
63     }
64     if (stat_info->zh->reg->isam)
65     {
66         ISPT ispt;
67
68         ispt = is_position (stat_info->zh->reg->isam, isam_p);
69         occur = is_numkeys (ispt);
70         stat_info->no_isam_entries[is_type(isam_p)] += occur;
71         is_pt_free (ispt);
72     }
73     if (stat_info->zh->reg->isamc)
74     {
75         ISAMC_PP pp;
76         int occurx = 0;
77         struct it_key key;
78
79         pp = isc_pp_open (stat_info->zh->reg->isamc, isam_p);
80         occur = isc_pp_num (pp);
81         while (isc_pp_read(pp, &key))
82         {
83             stat_info->cksum = stat_info->cksum * 65509 + 
84                 key.sysno + 11 * key.seqno;
85             occurx++;
86         }
87         assert (occurx == occur);
88         stat_info->no_isam_entries[isc_type(isam_p)] += occur;
89         isc_pp_close (pp);
90     }
91     if (stat_info->zh->reg->isamd)
92     {
93         ISAMD_PP pp;
94         int occurx = 0;
95         struct it_key key;
96
97         pp = isamd_pp_open (stat_info->zh->reg->isamd, isam_p);
98         
99         occur = isamd_pp_num (pp);
100         while (isamd_pp_read(pp, &key))
101         {
102             stat_info->cksum = stat_info->cksum * 65509 + 
103                 key.sysno + 11 * key.seqno;
104             occurx++;
105             if ( pp->is->method->debug >8 )
106                logf (LOG_LOG,"sysno=%d seqno=%d (%x/%x) oc=%d/%d ofs=%d ",
107                    key.sysno, key.seqno,
108                    key.sysno, key.seqno,
109                    occur,occurx, pp->offset);
110         }
111         if ( pp->is->method->debug >7 )
112            logf(LOG_LOG,"item %d=%d:%d says %d keys, counted %d",
113               isam_p, isamd_type(isam_p), isamd_block(isam_p),
114               occur, occurx); 
115         if (occurx != occur) 
116           logf(LOG_LOG,"Count error!!! read %d, counted %d", occur, occurx);
117         assert (occurx == occur);
118         if ( is_singleton(isam_p) )
119             stat_info->no_isam_entries[SINGLETON_TYPE] += occur;
120         else
121             stat_info->no_isam_entries[isamd_type(isam_p)] += occur;
122         isamd_pp_close (pp);
123     }
124     if (stat_info->zh->reg->isamb)
125     {
126         ISAMB_PP pp;
127         struct it_key key;
128         int cat = isam_p & 3;
129         int level;
130         int size;
131         int blocks;
132         
133         pp = isamb_pp_open_x(stat_info->zh->reg->isamb, isam_p, &level);
134
135         while (isamb_pp_read(pp, &key))
136         {
137             stat_info->cksum = stat_info->cksum * 65509 + 
138                 key.sysno + 11 * key.seqno;
139             occur++;
140         }
141         isamb_pp_close_x (pp, &size, &blocks);
142         stat_info->isamb_blocks[cat] += blocks;
143         stat_info->isamb_sizes[cat] += size;
144         if (level > 4)
145             level = 4;
146         stat_info->isamb_levels[cat][level] ++;
147         stat_info->no_isam_entries[cat] += occur;
148     }
149
150     while (occur > stat_info->isam_bounds[i] && stat_info->isam_bounds[i])
151         i++;
152     ++(stat_info->isam_occurrences[i]);
153     return 0;
154 }
155
156 void zebra_register_statistics (ZebraHandle zh)
157 {
158     int blocks;
159     int size;
160     int count;
161     int i, prev;
162     int before = 0;
163     int occur;
164     int after = 1000000000;
165     struct inv_stat_info stat_info;
166     char term_dict[2*IT_MAX_WORD+2];
167
168     if (zebra_begin_read (zh))
169         return;
170
171     stat_info.zh = zh;
172
173     term_dict[0] = 1;
174     term_dict[1] = 0;
175
176     for (i = 0; i<=SINGLETON_TYPE; i++)
177         stat_info.no_isam_entries[i] = 0;
178     stat_info.no_dict_entries = 0;
179     stat_info.no_dict_bytes = 0;
180     stat_info.isam_bounds[0] = 1;
181     stat_info.isam_bounds[1] = 2;
182     stat_info.isam_bounds[2] = 3;
183     stat_info.isam_bounds[3] = 6;
184     stat_info.isam_bounds[4] = 10;
185     stat_info.isam_bounds[5] = 20;
186     stat_info.isam_bounds[6] = 30;
187     stat_info.isam_bounds[7] = 50;
188     stat_info.isam_bounds[8] = 100;
189     stat_info.isam_bounds[9] = 200;
190     stat_info.isam_bounds[10] = 5000;
191     stat_info.isam_bounds[11] = 10000;
192     stat_info.isam_bounds[12] = 20000;
193     stat_info.isam_bounds[13] = 50000;
194     stat_info.isam_bounds[14] = 100000;
195     stat_info.isam_bounds[15] = 200000;
196     stat_info.isam_bounds[16] = 500000;
197     stat_info.isam_bounds[17] = 1000000;
198     stat_info.isam_bounds[18] = 0;
199
200     stat_info.cksum = 0;
201
202     for (i = 0; i<20; i++)
203         stat_info.isam_occurrences[i] = 0;
204
205     for (i = 0; i<10; i++)
206     {
207         int j;
208         for (j = 0; j<5; j++)
209             stat_info.isamb_levels[i][j] = 0;
210         stat_info.isamb_sizes[i] = 0;
211         stat_info.isamb_blocks[i] = 0;
212     }
213
214     dict_scan (zh->reg->dict, term_dict, &before, &after, &stat_info,
215                inv_stat_handle);
216
217     if (zh->reg->isamc)
218     {
219         fprintf (stdout, "   Blocks    Occur  Size KB   Bytes/Entry\n");
220         for (i = 0; isc_block_used (zh->reg->isamc, i) >= 0; i++)
221         {
222             fprintf (stdout, " %8d %8d", isc_block_used (zh->reg->isamc, i),
223                      stat_info.no_isam_entries[i]);
224
225             if (stat_info.no_isam_entries[i])
226                 fprintf (stdout, " %8d   %f",
227                          (int) ((1023.0 + (double)
228                                  isc_block_used(zh->reg->isamc, i) *
229                                  isc_block_size(zh->reg->isamc,i))/1024),
230                          ((double) isc_block_used(zh->reg->isamc, i) *
231                           isc_block_size(zh->reg->isamc,i))/
232                          stat_info.no_isam_entries[i]);
233             fprintf (stdout, "\n");
234         }
235     }
236     if (zh->reg->isamd)
237     {
238         fprintf (stdout, "   Blocks   Occur      KB Bytes/Entry\n");
239         if (zh->reg->isamd->method->debug >0) 
240             logf(LOG_LOG,"   Blocks   Occur      KB Bytes/Entry");
241         for (i = 0; i<=SINGLETON_TYPE; i++)
242         {
243             blocks= isamd_block_used(zh->reg->isamd,i);
244             size= isamd_block_size(zh->reg->isamd,i);
245             count=stat_info.no_isam_entries[i];
246             if (i==SINGLETON_TYPE) 
247                 blocks=size=0;
248             if (stat_info.no_isam_entries[i]) 
249             {
250                 fprintf (stdout, "%c %7d %7d %7d %5.2f\n",
251                          (i==SINGLETON_TYPE)?('z'):('A'+i),
252                          blocks,
253                          count,
254                          (int) ((1023.0 + (double) blocks * size)/1024),
255                          ((double) blocks * size)/count);
256                 if (zh->reg->isamd->method->debug >0) 
257                     logf(LOG_LOG, "%c %7d %7d %7d %5.2f",
258                          (i==SINGLETON_TYPE)?('z'):('A'+i),
259                          blocks,
260                          count,
261                          (int) ((1023.0 + (double) blocks * size)/1024),
262                          ((double) blocks * size)/count);
263             } /* entries */
264         } /* for */
265     } /* isamd */
266     if ( (zh->reg->isamd) && (zh->reg->isamd->method->debug>0))
267         fprintf (stdout, "\n%d words using %d bytes\n",
268              stat_info.no_dict_entries, stat_info.no_dict_bytes);
269
270     if (zh->reg->isamb)
271     {
272         for (i = 0; i<4; i++)
273         {
274             int j;
275             int bsize = isamb_block_info(zh->reg->isamb, i);
276             if (bsize < 0)
277                 break;
278             fprintf (stdout, "Category   %d\n", i);
279             fprintf (stdout, "Block size %d\n", bsize);
280             fprintf (stdout, "Blocks:    %d\n", stat_info.isamb_blocks[i]);
281             fprintf (stdout, "Size:      %d\n", stat_info.isamb_sizes[i]);
282             fprintf (stdout, "Entries:   %d\n", stat_info.no_isam_entries[i]);
283             fprintf (stdout, "Total      %d\n", stat_info.isamb_blocks[i]*
284                      bsize);
285             for (j = 0; j<5; j++)
286                 if (stat_info.isamb_levels[i][j])
287                     fprintf (stdout, "Level%d     %d\n", j,
288                              stat_info.isamb_levels[i][j]);
289             fprintf (stdout, "\n");
290         }
291     }
292     fprintf (stdout, "Checksum       %08lX\n", stat_info.cksum);
293
294     fprintf (stdout, "Distinct words %d\n", stat_info.no_dict_entries);
295     occur = 0;
296     for (i = 0; i<9; i++)
297         occur += stat_info.no_isam_entries[i];
298     fprintf (stdout, "Word pos       %d\n", occur);
299     fprintf (stdout, "    Occurrences     Words\n");
300     prev = 1;
301     for (i = 0; stat_info.isam_bounds[i]; i++)
302     {
303         int here = stat_info.isam_bounds[i];
304         fprintf (stdout, "%7d-%-7d %7d\n",
305                  prev, here, stat_info.isam_occurrences[i]);
306         prev = here+1;
307     }
308     fprintf (stdout, "%7d-        %7d\n",
309              prev, stat_info.isam_occurrences[i]);
310     xmalloc_trav("unfreed"); /*! while hunting memory leaks */    
311     zebra_end_read (zh);
312 }
313
314
315 /*
316  *
317  * $Log: invstat.c,v $
318  * Revision 1.29  2002-06-19 10:29:17  adam
319  * align block sizes for isam sys. Better plot for test
320  *
321  * Revision 1.28  2002/04/30 19:31:09  adam
322  * isamb delete; more statistics
323  *
324  * Revision 1.27  2002/04/30 08:28:37  adam
325  * isamb fixes for pp_read. Statistics
326  *
327  * Revision 1.26  2002/04/29 18:03:46  adam
328  * More isamb statistics
329  *
330  * Revision 1.25  2002/04/26 08:44:47  adam
331  * Index statistics working again
332  *
333  * Revision 1.24  2002/04/05 08:46:26  adam
334  * Zebra with full functionality
335  *
336  * Revision 1.23  2002/04/04 14:14:13  adam
337  * Multiple registers (alpha early)
338  *
339  * Revision 1.22  2002/02/20 17:30:01  adam
340  * Work on new API. Locking system re-implemented
341  *
342  * Revision 1.21  2000/07/13 10:14:20  heikki
343  * Removed compiler warnings when making zebra
344  *
345  * Revision 1.20  1999/12/01 13:30:30  adam
346  * Updated configure for Zmbol/Zebra dependent settings.
347  *
348  * Revision 1.19  1999/11/30 13:48:03  adam
349  * Improved installation. Updated for inclusion of YAZ header files.
350  *
351  * Revision 1.18  1999/10/06 11:46:36  heikki
352  * mproved statistics on isam-d
353  *
354  * Revision 1.17  1999/08/20 08:28:37  heikki
355  * Log levels
356  *
357  * Revision 1.16  1999/08/18 08:38:22  heikki
358  * Memory leak hunting
359  *
360  * Revision 1.15  1999/08/18 08:34:53  heikki
361  * isamd
362  *
363  * Revision 1.14  1999/07/14 10:59:26  adam
364  * Changed functions isc_getmethod, isams_getmethod.
365  * Improved fatal error handling (such as missing EXPLAIN schema).
366  *
367  * Revision 1.13  1999/07/08 14:23:27  heikki
368  * Fixed a bug in isamh_pp_read and cleaned up a bit
369  *
370  * Revision 1.12  1999/07/06 12:28:04  adam
371  * Updated record index structure. Format includes version ID. Compression
372  * algorithm ID is stored for each record block.
373  *
374  * Revision 1.11  1999/05/15 14:36:38  adam
375  * Updated dictionary. Implemented "compression" of dictionary.
376  *
377  * Revision 1.10  1999/05/12 13:08:06  adam
378  * First version of ISAMS.
379  *
380  * Revision 1.9  1999/02/12 13:29:23  adam
381  * Implemented position-flag for registers.
382  *
383  * Revision 1.8  1999/02/02 14:50:53  adam
384  * Updated WIN32 code specific sections. Changed header.
385  *
386  * Revision 1.7  1998/03/13 15:30:50  adam
387  * New functions isc_block_used and isc_block_size. Fixed 'leak'
388  * in isc_alloc_block.
389  *
390  * Revision 1.6  1998/03/06 13:54:02  adam
391  * Fixed two nasty bugs in isc_merge.
392  *
393  * Revision 1.5  1997/09/17 12:19:13  adam
394  * Zebra version corresponds to YAZ version 1.4.
395  * Changed Zebra server so that it doesn't depend on global common_resource.
396  *
397  * Revision 1.4  1996/11/08 11:10:21  adam
398  * Buffers used during file match got bigger.
399  * Compressed ISAM support everywhere.
400  * Bug fixes regarding masking characters in queries.
401  * Redesigned Regexp-2 queries.
402  *
403  * Revision 1.3  1996/06/04 10:18:58  adam
404  * Minor changes - removed include of ctype.h.
405  *
406  * Revision 1.2  1996/05/22  08:25:56  adam
407  * Minor change.
408  *
409  * Revision 1.1  1996/05/14 14:04:34  adam
410  * In zebraidx, the 'stat' command is improved. Statistics about ISAM/DICT
411  * is collected.
412  */