source: trunk/third/gdbm/testgdbm.c @ 15372

Revision 15372, 13.2 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15371, which included commits to RCS files with non-trunk default branches.
Line 
1/* testgdbm.c - Driver program to test the database routines and to
2   help debug gdbm.  Uses inside information to show "system" information */
3
4/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
5    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
6
7    GDBM is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2, or (at your option)
10    any later version.
11
12    GDBM is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GDBM; see the file COPYING.  If not, write to
19    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20
21    You may contact the author by:
22       e-mail:  phil@cs.wwu.edu
23      us-mail:  Philip A. Nelson
24                Computer Science Department
25                Western Washington University
26                Bellingham, WA 98226
27       
28*************************************************************************/
29
30
31/* include system configuration before all else. */
32#include "autoconf.h"
33
34#include "gdbmdefs.h"
35#include "gdbmerrno.h"
36#include "extern.h"
37
38#include "getopt.h"
39
40extern const char * gdbm_version;
41
42extern const char *gdbm_strerror __P((gdbm_error));
43
44gdbm_file_info *gdbm_file;
45
46/* Debug procedure to print the contents of the current hash bucket. */
47void
48print_bucket (bucket, mesg)
49     hash_bucket *bucket;
50     char *mesg;
51{
52  int  index;
53
54  printf ("******* %s **********\n\nbits = %d\ncount= %d\nHash Table:\n",
55         mesg, bucket->bucket_bits, bucket->count);
56  printf ("     #    hash value     key size    data size     data adr  home\n");
57  for (index = 0; index < gdbm_file->header->bucket_elems; index++)
58    printf ("  %4d  %12x  %11d  %11d  %11d %5d\n", index,
59           bucket->h_table[index].hash_value,
60           bucket->h_table[index].key_size,
61           bucket->h_table[index].data_size,
62           bucket->h_table[index].data_pointer,
63           bucket->h_table[index].hash_value % gdbm_file->header->bucket_elems);
64
65  printf ("\nAvail count = %1d\n", bucket->av_count);
66  printf ("Avail  adr     size\n");
67  for (index = 0; index < bucket->av_count; index++)
68    printf ("%9d%9d\n", bucket->bucket_avail[index].av_adr,
69                        bucket->bucket_avail[index].av_size);
70}
71
72
73void
74_gdbm_print_avail_list (dbf)
75     gdbm_file_info *dbf;
76{
77  int temp;
78  int size;
79  avail_block *av_stk;
80 
81  /* Print the the header avail block.  */
82  printf ("\nheader block\nsize  = %d\ncount = %d\n",
83          dbf->header->avail.size, dbf->header->avail.count);
84  for (temp = 0; temp < dbf->header->avail.count; temp++)
85    {
86      printf ("  %15d   %10d \n", dbf->header->avail.av_table[temp].av_size,
87              dbf->header->avail.av_table[temp].av_adr);
88    }
89
90  /* Initialize the variables for a pass throught the avail stack. */
91  temp = dbf->header->avail.next_block;
92  size = ( ( (dbf->header->avail.size * sizeof (avail_elem)) >> 1)
93          + sizeof (avail_block));
94  av_stk = (avail_block *) malloc (size);
95  if (av_stk == NULL)
96    {
97      printf("Out of memory\n");
98      exit (2);
99    }
100
101  /* Print the stack. */
102  while (FALSE)
103    {
104      lseek (dbf->desc, temp, L_SET);
105      read  (dbf->desc, av_stk, size);
106
107      /* Print the block! */
108      printf ("\nblock = %d\nsize  = %d\ncount = %d\n", temp,
109              av_stk->size, av_stk->count);
110      for (temp = 0; temp < av_stk->count; temp++)
111        {
112          printf ("  %15d   %10d \n", av_stk->av_table[temp].av_size,
113            av_stk->av_table[temp].av_adr);
114        }
115      temp = av_stk->next_block;
116    }
117}
118
119void
120_gdbm_print_bucket_cache (dbf)
121     gdbm_file_info *dbf;
122{
123  register int index;
124  char changed;
125 
126  if (dbf->bucket_cache != NULL) {
127    printf(
128      "Bucket Cache (size %d):\n  Index:  Address  Changed  Data_Hash \n",
129      dbf->cache_size);
130    for (index=0; index < dbf->cache_size; index++) {
131      changed = dbf->bucket_cache[index].ca_changed;
132      printf ("  %5d:  %7d  %7s  %x\n",
133              index,
134              dbf->bucket_cache[index].ca_adr,
135              (changed ? "True" : "False"),
136              dbf->bucket_cache[index].ca_data.hash_val);
137    }
138  } else
139    printf("Bucket cache has not been initialized.\n");
140}
141
142void
143usage (s)
144     char *s;
145{
146  printf(
147      "Usage: %s [-r or -ns] [-b block-size] [-c cache-size] [-g gdbm-file]\n",
148      s);
149  exit (2);
150}
151
152
153/* The test program allows one to call all the routines plus the hash function.
154   The commands are single letter commands.  The user is prompted for all other
155   information.  See the help command (?) for a list of all commands. */
156
157int
158main (argc, argv)
159     int argc;
160     char *argv[];
161
162{
163
164  char  cmd_ch;
165
166  datum key_data;
167  datum data_data;
168  datum return_data;
169
170  char key_line[500];
171  char data_line[1000];
172
173  char done = FALSE;
174  int  opt;
175  char reader = FALSE;
176  char newdb = FALSE;
177  int  fast  = 0;
178
179  int  cache_size = DEFAULT_CACHESIZE;
180  int  block_size = 0;
181
182  char *file_name = NULL;
183
184
185  /* Argument checking. */
186  opterr = 0;
187  while ((opt = getopt (argc, argv, "srnc:b:g:")) != -1)
188    switch (opt) {
189    case 's':  fast = GDBM_SYNC;
190               if (reader) usage (argv[0]);
191               break;
192    case 'r':  reader = TRUE;
193               if (newdb) usage (argv[0]);
194               break;
195    case 'n':  newdb = TRUE;
196               if (reader) usage (argv[0]);
197               break;
198    case 'c':  cache_size = atoi(optarg);
199               break;
200    case 'b':  block_size = atoi(optarg);
201               break;
202    case 'g':  file_name = optarg;
203               break;
204    default:  usage(argv[0]);
205    }
206
207  if(file_name == NULL)
208    file_name = "junk.gdbm";
209
210  /* Initialize variables. */
211  key_data.dptr = NULL;
212  data_data.dptr = data_line;
213
214  if (reader)
215    {
216      gdbm_file = gdbm_open (file_name, block_size, GDBM_READER, 00664, NULL);
217    }
218  else if (newdb)
219    {
220      gdbm_file =
221        gdbm_open (file_name, block_size, GDBM_NEWDB | fast, 00664, NULL);
222    }
223  else
224    {
225      gdbm_file =
226        gdbm_open (file_name, block_size, GDBM_WRCREAT | fast, 00664, NULL);
227    }
228  if (gdbm_file == NULL)
229    {
230      printf("gdbm_open failed, %s\n", gdbm_strerror(gdbm_errno));
231      exit (2);
232    }
233
234  if (gdbm_setopt(gdbm_file, GDBM_CACHESIZE, &cache_size, sizeof(int)) == -1)
235    {
236      printf("gdbm_setopt failed, %s\n", gdbm_strerror(gdbm_errno));
237      exit(2);
238    }
239
240  /* Welcome message. */
241  printf ("\nWelcome to the gdbm test program.  Type ? for help.\n\n");
242 
243  while (!done)
244    {
245      printf ("com -> ");
246      cmd_ch = getchar ();
247      if (cmd_ch != '\n')
248        {
249          char temp;
250          do
251              temp = getchar ();
252          while (temp != '\n' && temp != EOF);
253        }
254      if (cmd_ch == EOF) cmd_ch = 'q';
255      switch (cmd_ch)
256        {
257       
258        /* Standard cases found in all test{dbm,ndbm,gdbm} programs. */
259        case '\n':
260          printf ("\n");
261          break;
262
263        case 'c':
264          {
265            int temp;
266            temp = 0;
267            if (key_data.dptr != NULL) free (key_data.dptr);
268            return_data = gdbm_firstkey (gdbm_file);
269            while (return_data.dptr != NULL)
270              {
271                temp++;
272                key_data = return_data;
273                return_data = gdbm_nextkey (gdbm_file, key_data);
274                free (key_data.dptr);
275              }
276            printf ("There are %d items in the database.\n\n", temp);
277            key_data.dptr = NULL;
278          }
279          break;
280
281        case 'd':
282          if (key_data.dptr != NULL) free (key_data.dptr);
283          printf ("key -> ");
284          gets (key_line);
285          key_data.dptr = key_line;
286          key_data.dsize = strlen (key_line)+1;
287          if (gdbm_delete (gdbm_file, key_data) != 0)
288            printf ("Item not found or deleted\n");
289          printf ("\n");
290          key_data.dptr = NULL;
291          break;
292
293        case 'f':
294          if (key_data.dptr != NULL) free (key_data.dptr);
295          printf ("key -> ");
296          gets (key_line);
297          key_data.dptr = key_line;
298          key_data.dsize = strlen (key_line)+1;
299          return_data = gdbm_fetch (gdbm_file, key_data);
300          if (return_data.dptr != NULL)
301            {
302              printf ("data is ->%s\n\n", return_data.dptr);
303              free (return_data.dptr);
304            }
305          else
306            printf ("No such item found.\n\n");
307          key_data.dptr = NULL;
308          break;
309
310        case 'n':
311          if (key_data.dptr != NULL) free (key_data.dptr);
312          printf ("key -> ");
313          gets (key_line);
314          key_data.dptr = key_line;
315          key_data.dsize = strlen (key_line)+1;
316          return_data = gdbm_nextkey (gdbm_file, key_data);
317          if (return_data.dptr != NULL)
318            {
319              key_data = return_data;
320              printf ("key is  ->%s\n", key_data.dptr);
321              return_data = gdbm_fetch (gdbm_file, key_data);
322              printf ("data is ->%s\n\n", return_data.dptr);
323              free (return_data.dptr);
324            }
325          else
326            {
327              printf ("No such item found.\n\n");
328              key_data.dptr = NULL;
329            }
330          break;
331
332        case 'q':
333          done = TRUE;
334          break;
335
336        case 's':
337          if (key_data.dptr != NULL) free (key_data.dptr);
338          printf ("key -> ");
339          gets (key_line);
340          key_data.dptr = key_line;
341          key_data.dsize = strlen (key_line)+1;
342          printf ("data -> ");
343          gets (data_line);
344          data_data.dsize = strlen (data_line)+1;
345          if (gdbm_store (gdbm_file, key_data, data_data, GDBM_REPLACE) != 0)
346            printf ("Item not inserted. \n");
347          printf ("\n");
348          key_data.dptr = NULL;
349          break;
350
351        case '1':
352          if (key_data.dptr != NULL) free (key_data.dptr);
353          key_data = gdbm_firstkey (gdbm_file);
354          if (key_data.dptr != NULL)
355            {
356              printf ("key is  ->%s\n", key_data.dptr);
357              return_data = gdbm_fetch (gdbm_file, key_data);
358              printf ("data is ->%s\n\n", return_data.dptr);
359              free (return_data.dptr);
360            }
361          else
362            printf ("No such item found.\n\n");
363          break;
364
365        case '2':
366          return_data = gdbm_nextkey (gdbm_file, key_data);
367          if (return_data.dptr != NULL)
368            {
369              free (key_data.dptr);
370              key_data = return_data;
371              printf ("key is  ->%s\n", key_data.dptr);
372              return_data = gdbm_fetch (gdbm_file, key_data);
373              printf ("data is ->%s\n\n", return_data.dptr);
374              free (return_data.dptr);
375            }
376          else
377            printf ("No such item found.\n\n");
378          break;
379
380
381        /* Special cases for the testgdbm program. */
382        case 'r':
383          {
384            if (gdbm_reorganize (gdbm_file))
385              printf ("Reorganization failed. \n\n");
386            else
387              printf ("Reorganization succeeded. \n\n");
388          }
389          break;
390
391        case 'A':
392          _gdbm_print_avail_list (gdbm_file);
393          printf ("\n");
394          break;
395
396        case 'B':
397          {
398            int temp;
399            char number[80];
400
401            printf ("bucket? ");
402            gets (number);
403            sscanf (number,"%d",&temp);
404
405            if (temp >= gdbm_file->header->dir_size /4)
406              {
407                printf ("Not a bucket. \n\n");
408                break;
409              }
410            _gdbm_get_bucket (gdbm_file, temp);
411          }
412          printf ("Your bucket is now ");
413
414        case 'C':
415          print_bucket (gdbm_file->bucket, "Current bucket");
416          printf ("\n current directory entry = %d.\n", gdbm_file->bucket_dir);
417          printf (" current bucket address  = %d.\n\n",
418                  gdbm_file->cache_entry->ca_adr);
419          break;
420
421        case 'D':
422          printf ("Hash table directory.\n");
423          printf ("  Size =  %d.  Bits = %d. \n\n",gdbm_file->header->dir_size,
424                  gdbm_file->header->dir_bits);
425          {
426            int temp;
427
428            for (temp = 0; temp < gdbm_file->header->dir_size / 4; temp++)
429              {
430                printf ("  %10d:  %12d\n", temp, gdbm_file->dir[temp]);
431                if ( (temp+1) % 20 == 0 && isatty (0))
432                  {
433                    printf ("*** CR to continue: ");
434                    while (getchar () != '\n') /* Do nothing. */;
435                  }
436              }
437          }
438          printf ("\n");
439          break;
440
441        case 'F':
442          {
443            printf ("\nFile Header: \n\n");
444            printf ("  table        = %d\n", gdbm_file->header->dir);
445            printf ("  table size   = %d\n", gdbm_file->header->dir_size);
446            printf ("  table bits   = %d\n", gdbm_file->header->dir_bits);
447            printf ("  block size   = %d\n", gdbm_file->header->block_size);
448            printf ("  bucket elems = %d\n", gdbm_file->header->bucket_elems);
449            printf ("  bucket size  = %d\n", gdbm_file->header->bucket_size);
450            printf ("  header magic = %x\n", gdbm_file->header->header_magic);
451            printf ("  next block   = %d\n", gdbm_file->header->next_block);
452            printf ("  avail size   = %d\n", gdbm_file->header->avail.size);
453            printf ("  avail count  = %d\n", gdbm_file->header->avail.count);
454            printf ("  avail nx blk = %d\n", gdbm_file->header->avail.next_block);
455            printf ("\n");
456          }
457          break;
458
459        case 'H':
460          if (key_data.dptr != NULL) free (key_data.dptr);
461          printf ("key -> ");
462          gets (key_line);
463          key_data.dptr = key_line;
464          key_data.dsize = strlen (key_line)+1;
465          printf ("hash value = %x. \n\n", _gdbm_hash (key_data));
466          key_data.dptr = NULL;
467          break;
468
469        case 'K':
470          _gdbm_print_bucket_cache (gdbm_file);
471          break;
472
473        case 'V':
474          printf ("%s\n\n", gdbm_version);
475          break;
476
477        case '?':
478          printf ("c - count (number of entries)\n");
479          printf ("d - delete\n");
480          printf ("f - fetch\n");
481          printf ("n - nextkey\n");
482          printf ("q - quit\n");
483          printf ("s - store\n");
484          printf ("1 - firstkey\n");
485          printf ("2 - nextkey on last key (from n, 1 or 2)\n\n");
486
487          printf ("r - reorganize\n");
488          printf ("A - print avail list\n");
489          printf ("B - get and print current bucket n\n");
490          printf ("C - print current bucket\n");
491          printf ("D - print hash directory\n");
492          printf ("F - print file header\n");
493          printf ("H - hash value of key\n");
494          printf ("K - print the bucket cache\n");
495          printf ("V - print version of gdbm\n");
496          break;
497
498        default:
499          printf ("What? \n\n");
500          break;
501
502        }
503    }
504
505  /* Quit normally. */
506  exit (0);
507
508}
Note: See TracBrowser for help on using the repository browser.