source: main/trunk/greenstone2/common-src/packages/gdbm/gdbm-1.8.3/testgdbm.c@ 21356

Last change on this file since 21356 was 18019, checked in by mdewsnip, 15 years ago

Added gdbm-1.8.3 (downloaded as gdbm-1.8.3.tar.gz and unpacked), in preparation for adding code for reading both little and big endian databases.

File size: 13.2 KB
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: [email protected]
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.