2cdf9b12fb5ae16dc92ae7c6f2eabdcca8f75027
[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 "recindex.h"
14 #include "../isamc/isamd-p.h"
15
16 struct inv_stat_info {
17     ISAMS isams;
18 #if ZMBOL
19     ISAM isam;
20     ISAMC isamc;
21     ISAMD isamd;
22 #endif
23     int no_isam_entries[9];
24     int no_dict_entries;
25     int no_dict_bytes;
26     int isam_bounds[20];
27     int isam_occurrences[20];
28     char tmp[128];
29 };
30
31 #define SINGLETON_TYPE 8 /* the type to use for singletons that */ 
32                          /* have no block and no block type */
33
34 static int inv_stat_handle (char *name, const char *info, int pos,
35                             void *client)
36 {
37     int occur = 0;
38     int i = 0;
39     struct inv_stat_info *stat_info = (struct inv_stat_info*) client;
40     ISAMS_P isam_p;
41
42     stat_info->no_dict_entries++;
43     stat_info->no_dict_bytes += strlen(name);
44
45     assert (*info == sizeof(ISAMS_P));
46     memcpy (&isam_p, info+1, sizeof(ISAMS_P));
47
48     if (stat_info->isams)
49     {
50         ISAMS_PP pp;
51         int occurx = 0;
52         struct it_key key;
53
54         pp = isams_pp_open (stat_info->isams, isam_p);
55         occur = isams_pp_num (pp);
56         while (isams_pp_read(pp, &key))
57         {
58             //printf ("sysno=%d seqno=%d\n", key.sysno, key.seqno);
59             occurx++;
60         }
61         assert (occurx == occur);
62         stat_info->no_isam_entries[0] += occur;
63         isams_pp_close (pp);
64     }
65 #if ZMBOL
66     if (stat_info->isam)
67     {
68         ISPT ispt;
69
70         ispt = is_position (stat_info->isam, isam_p);
71         occur = is_numkeys (ispt);
72         is_pt_free (ispt);
73     }
74     if (stat_info->isamc)
75     {
76         ISAMC_PP pp;
77         int occurx = 0;
78         struct it_key key;
79
80         pp = isc_pp_open (stat_info->isamc, isam_p);
81         occur = isc_pp_num (pp);
82         while (isc_pp_read(pp, &key))
83         {
84             //printf ("sysno=%d seqno=%d\n", key.sysno, 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->isamd)
92     {
93         ISAMD_PP pp;
94         int occurx = 0;
95         struct it_key key;
96
97         pp = isamd_pp_open (stat_info->isamd, isam_p);
98         
99         occur = isamd_pp_num (pp);
100         while (isamd_pp_read(pp, &key))
101         {
102             occurx++;
103             if ( pp->is->method->debug >8 )
104                logf (LOG_LOG,"sysno=%d seqno=%d (%x/%x) oc=%d/%d ofs=%d ",
105                    key.sysno, key.seqno,
106                    key.sysno, key.seqno,
107                    occur,occurx, pp->offset);
108         }
109         if ( pp->is->method->debug >7 )
110            logf(LOG_LOG,"item %d=%d:%d says %d keys, counted %d",
111               isam_p, isamd_type(isam_p), isamd_block(isam_p),
112               occur, occurx); 
113         if (occurx != occur) 
114           logf(LOG_LOG,"Count error!!! read %d, counted %d", occur, occurx);
115         assert (occurx == occur);
116         if ( is_singleton(isam_p) )
117             stat_info->no_isam_entries[SINGLETON_TYPE] += occur;
118         else
119             stat_info->no_isam_entries[isamd_type(isam_p)] += occur;
120         isamd_pp_close (pp);
121     }
122 #endif
123     while (occur > stat_info->isam_bounds[i] && stat_info->isam_bounds[i])
124         i++;
125     ++(stat_info->isam_occurrences[i]);
126     return 0;
127 }
128
129 void inv_prstat (BFiles bfs)
130 {
131     Dict dict;
132     ISAMS isams = NULL;
133 #if ZMBOL
134     ISAM  isam  = NULL;
135     ISAMC isamc = NULL;
136     ISAMD isamd = NULL;
137 #endif
138     Records records;
139     int i, prev;
140     int before = 0;
141     int after = 1000000000;
142     struct inv_stat_info stat_info;
143     char term_dict[2*IT_MAX_WORD+2];
144     int blocks;
145     int size;
146     int count;
147         
148     term_dict[0] = 1;
149     term_dict[1] = 0;
150
151     dict = dict_open (bfs, FNAME_DICT, 100, 0, 0);
152     if (!dict)
153     {
154         logf (LOG_FATAL, "dict_open fail");
155         exit (1);
156     }
157     if (res_get_match (common_resource, "isam", "s", ISAM_DEFAULT))
158     {
159         struct ISAMS_M_s isams_m;
160         isams = isams_open (bfs, FNAME_ISAMS, 0,
161                             key_isams_m(common_resource, &isams_m));
162         if (!isams)
163         {
164             logf (LOG_FATAL, "isams_open fail");
165             exit (1);
166         }
167     }
168 #if ZMBOL
169     else if (res_get_match (common_resource, "isam", "i", ISAM_DEFAULT))
170     {
171         isam = is_open (bfs, FNAME_ISAM, key_compare, 0,
172                         sizeof(struct it_key), common_resource);
173         if (!isam)
174         {
175             logf (LOG_FATAL, "is_open fail");
176             exit (1);
177         }
178     }
179     else if (res_get_match (common_resource, "isam", "d", ISAM_DEFAULT))
180     {
181         struct ISAMD_M_s isamd_m;
182         isamd = isamd_open (bfs, FNAME_ISAMD, 0, 
183                             key_isamd_m(common_resource,&isamd_m));
184         if (!isamd)
185         {
186             logf (LOG_FATAL, "isamd_open fail");
187             exit (1);
188         }
189     }
190     else if (res_get_match (common_resource, "isam", "c", ISAM_DEFAULT))
191     {
192         struct ISAMC_M_s isamc_m;
193         isamc = isc_open (bfs, FNAME_ISAMC, 0,
194                           key_isamc_m (common_resource, &isamc_m));
195         if (!isamc)
196         {
197             logf (LOG_FATAL, "isc_open fail");
198             exit (1);
199         }
200     }
201 #endif
202     records = rec_open (bfs, 0, 0);
203
204     for (i = 0; i<=SINGLETON_TYPE; i++)
205         stat_info.no_isam_entries[i] = 0;
206     stat_info.no_dict_entries = 0;
207     stat_info.no_dict_bytes = 0;
208     stat_info.isams = isams;
209 #if ZMBOL
210     stat_info.isam = isam;
211     stat_info.isamc = isamc;
212     stat_info.isamd = isamd;
213 #endif
214     stat_info.isam_bounds[0] = 1;
215     stat_info.isam_bounds[1] = 2;
216     stat_info.isam_bounds[2] = 3;
217     stat_info.isam_bounds[3] = 6;
218     stat_info.isam_bounds[4] = 10;
219     stat_info.isam_bounds[5] = 20;
220     stat_info.isam_bounds[6] = 30;
221     stat_info.isam_bounds[7] = 50;
222     stat_info.isam_bounds[8] = 100;
223     stat_info.isam_bounds[9] = 200;
224     stat_info.isam_bounds[10] = 5000;
225     stat_info.isam_bounds[11] = 10000;
226     stat_info.isam_bounds[12] = 20000;
227     stat_info.isam_bounds[13] = 50000;
228     stat_info.isam_bounds[14] = 100000;
229     stat_info.isam_bounds[15] = 200000;
230     stat_info.isam_bounds[16] = 500000;
231     stat_info.isam_bounds[17] = 1000000;
232     stat_info.isam_bounds[18] = 0;
233
234     for (i = 0; i<20; i++)
235         stat_info.isam_occurrences[i] = 0;
236
237     dict_scan (dict, term_dict, &before, &after, &stat_info, inv_stat_handle);
238
239 #if ZMBOL
240     if (isamc)
241     {
242         fprintf (stderr, "   Blocks    Occur  Size KB   Bytes/Entry\n");
243         for (i = 0; isc_block_used (isamc, i) >= 0; i++)
244         {
245             fprintf (stderr, " %8d %8d", isc_block_used (isamc, i),
246                      stat_info.no_isam_entries[i]);
247
248             if (stat_info.no_isam_entries[i])
249                 fprintf (stderr, " %8d   %f",
250                          (int) ((1023.0 + (double) isc_block_used(isamc, i) *
251                                  isc_block_size(isamc,i))/1024),
252                          ((double) isc_block_used(isamc, i) *
253                           isc_block_size(isamc,i))/
254                          stat_info.no_isam_entries[i]);
255             fprintf (stderr, "\n");
256         }
257     }
258     if (isamd)
259     {
260         fprintf (stderr, "   Blocks   Occur      KB Bytes/Entry\n");
261         if (isamd->method->debug >0) 
262             logf(LOG_LOG,"   Blocks   Occur      KB Bytes/Entry");
263         for (i = 0; i<=SINGLETON_TYPE; i++)
264         {
265             blocks= isamd_block_used(isamd,i);
266             size= isamd_block_size(isamd,i);
267             count=stat_info.no_isam_entries[i];
268             if (i==SINGLETON_TYPE) 
269                 blocks=size=0;
270             if (stat_info.no_isam_entries[i]) 
271             {
272                 fprintf (stderr, "%c %7d %7d %7d %5.2f\n",
273                          (i==SINGLETON_TYPE)?('z'):('A'+i),
274                          blocks,
275                          count,
276                          (int) ((1023.0 + (double) blocks * size)/1024),
277                          ((double) blocks * size)/count);
278                 if (isamd->method->debug >0) 
279                     logf(LOG_LOG, "%c %7d %7d %7d %5.2f",
280                          (i==SINGLETON_TYPE)?('z'):('A'+i),
281                          blocks,
282                          count,
283                          (int) ((1023.0 + (double) blocks * size)/1024),
284                          ((double) blocks * size)/count);
285             } /* entries */
286         } /* for */
287     } /* isamd */
288     if ( (isamd) && (isamd->method->debug>0))
289         fprintf (stderr, "\n%d words using %d bytes\n",
290              stat_info.no_dict_entries, stat_info.no_dict_bytes);
291 #endif
292     fprintf (stderr, "    Occurrences     Words\n");
293     prev = 1;
294     for (i = 0; stat_info.isam_bounds[i]; i++)
295     {
296         int here = stat_info.isam_bounds[i];
297         fprintf (stderr, "%7d-%-7d %7d\n",
298                  prev, here, stat_info.isam_occurrences[i]);
299         prev = here+1;
300     }
301     fprintf (stderr, "%7d-        %7d\n",
302              prev, stat_info.isam_occurrences[i]);
303     rec_close (&records);
304     dict_close (dict);
305
306     if (isams)
307         isams_close (isams);
308 #if ZMBOL
309     if (isam)
310         is_close (isam);
311     if (isamc)
312         isc_close (isamc);
313     if (isamd)
314         isamd_close (isamd);
315 #endif
316
317     xmalloc_trav("unfreed"); /*! while hunting memory leaks */    
318 }
319
320
321 /*
322  *
323  * $Log: invstat.c,v $
324  * Revision 1.19  1999-11-30 13:48:03  adam
325  * Improved installation. Updated for inclusion of YAZ header files.
326  *
327  * Revision 1.18  1999/10/06 11:46:36  heikki
328  * mproved statistics on isam-d
329  *
330  * Revision 1.17  1999/08/20 08:28:37  heikki
331  * Log levels
332  *
333  * Revision 1.16  1999/08/18 08:38:22  heikki
334  * Memory leak hunting
335  *
336  * Revision 1.15  1999/08/18 08:34:53  heikki
337  * isamd
338  *
339  * Revision 1.14  1999/07/14 10:59:26  adam
340  * Changed functions isc_getmethod, isams_getmethod.
341  * Improved fatal error handling (such as missing EXPLAIN schema).
342  *
343  * Revision 1.13  1999/07/08 14:23:27  heikki
344  * Fixed a bug in isamh_pp_read and cleaned up a bit
345  *
346  * Revision 1.12  1999/07/06 12:28:04  adam
347  * Updated record index structure. Format includes version ID. Compression
348  * algorithm ID is stored for each record block.
349  *
350  * Revision 1.11  1999/05/15 14:36:38  adam
351  * Updated dictionary. Implemented "compression" of dictionary.
352  *
353  * Revision 1.10  1999/05/12 13:08:06  adam
354  * First version of ISAMS.
355  *
356  * Revision 1.9  1999/02/12 13:29:23  adam
357  * Implemented position-flag for registers.
358  *
359  * Revision 1.8  1999/02/02 14:50:53  adam
360  * Updated WIN32 code specific sections. Changed header.
361  *
362  * Revision 1.7  1998/03/13 15:30:50  adam
363  * New functions isc_block_used and isc_block_size. Fixed 'leak'
364  * in isc_alloc_block.
365  *
366  * Revision 1.6  1998/03/06 13:54:02  adam
367  * Fixed two nasty bugs in isc_merge.
368  *
369  * Revision 1.5  1997/09/17 12:19:13  adam
370  * Zebra version corresponds to YAZ version 1.4.
371  * Changed Zebra server so that it doesn't depend on global common_resource.
372  *
373  * Revision 1.4  1996/11/08 11:10:21  adam
374  * Buffers used during file match got bigger.
375  * Compressed ISAM support everywhere.
376  * Bug fixes regarding masking characters in queries.
377  * Redesigned Regexp-2 queries.
378  *
379  * Revision 1.3  1996/06/04 10:18:58  adam
380  * Minor changes - removed include of ctype.h.
381  *
382  * Revision 1.2  1996/05/22  08:25:56  adam
383  * Minor change.
384  *
385  * Revision 1.1  1996/05/14 14:04:34  adam
386  * In zebraidx, the 'stat' command is improved. Statistics about ISAM/DICT
387  * is collected.
388  */