2 * Copyright (c) 2000-2001 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #ifdef HAVE_GDBM_NDBM_H_
22 #include <gdbm/ndbm.h>
23 #elif HAVE_GDBM_NDBM_H
24 #include <gdbm-ndbm.h>
32 /* #define WorkDir "/xfs" */
33 #define DBNAME "DBtest"
37 typedef struct _myDB {
39 unsigned short checksum;
43 int InitDbmLookup(int);
44 int DoDbmLookup(void);
45 void CleanupDbmLookup(void);
46 void DoSysError(char *, int);
47 int creatDbRec(myDB *);
48 unsigned short calccksum(char *, int);
49 void CkSumError(char *, unsigned short, unsigned short);
50 int InsertKey(unsigned short *, int, unsigned short);
51 void DumpKeys(int, unsigned short);
54 int numDbmEntries, keyIdx, Dups = 0, Errors = 0;
55 unsigned short *KeyArray, *DupsArray;
56 int debugflg = 0; /* are we in debugging mode? */
57 int errflg = 0; /* usage option errors */
58 int ignoreflg = 1; /* ignore errors in lookup; default = on */
63 main(int argc, char *argv[])
65 int numrecs = DBRECS, c, l;
67 while ((c = getopt(argc, argv, "idn:l:s:")) != EOF) {
74 numrecs = atoi(optarg);
75 numrecs = (numrecs < 1) ? DBRECS : numrecs;
79 loops = (loops < 1) ? LOOPS : loops;
82 randseed = atoi(optarg);
83 randseed = (randseed < 0) ? 0 : randseed;
91 printf("Usage: dbtest [-di] [-n number] [-l loop] [-s randseed]\n");
95 printf("Extra arguments ignored\n");
96 for ( ; optind<argc; optind++)
97 printf("\t%s\n", argv[optind]);
100 printf("dbtest v1.0\n\n");
101 printf("Creating database containing %d records...\n", numrecs);
102 printf("\tperforming lookups for %d iterations...\n", loops);
104 printf("\tusing %d as seed for srandom()...\n\n", randseed);
106 InitDbmLookup(numrecs);
107 printf("\t\nThere were %d duplicate checksums generated\n", Dups);
108 for (l=0; l<loops; l++) {
109 printf("\nPerforming lookups on database...\n");
110 if (DoDbmLookup() != numrecs)
111 printf("\nError performing lookups!\n");
113 printf("\nLookups succeeded...\n");
115 printf("\nCleaning up database...\n");
116 printf("\t\nThere were %d duplicate checksums generated\n", Dups);
120 for (l=0; l<Dups; l++) {
123 printf("0x%x\t", DupsArray[l]);
130 int InitDbmLookup(int howmany)
137 sprintf(filename, "%s-%d", DBNAME, (int)getpid());
139 printf("dbm_open(%s, O_RDWR|O_CREAT, 0644)\n", filename);
142 dbm = dbm_open(filename, O_RDWR|O_CREAT, 0644);
144 DoSysError("\ndbm_open", -1);
146 if ((KeyArray = (unsigned short *)calloc( howmany,
147 sizeof(unsigned short))) == NULL)
148 DoSysError("\ncalloc:KeyArray", -1);
149 if ((DupsArray = (unsigned short *)calloc( 100,
150 sizeof(unsigned short))) == NULL)
151 DoSysError("\ncalloc:DupsArray", -1);
154 for(i=0; i<howmany; i++) {
156 if ( creatDbRec(&dbRec) )
157 DoSysError("\ncreatDbRec", -1);
159 printf("created rec #%-7d\t%x\r", i+1, dbRec.checksum);
163 if (InsertKey(KeyArray, keyIdx, dbRec.checksum))
166 key.dptr = (char *)&(dbRec.checksum);
167 key.dsize = sizeof(dbRec.checksum);
168 content.dptr = (char *)&dbRec;
169 content.dsize = sizeof(dbRec);
174 printf("dbm_store(dbm, key, content, DBM_INSERT)\n");
176 rc = dbm_store(dbm, key, content, DBM_INSERT);
178 DoSysError("\ndbm_store", rc);
180 keyIdx--; /* key is already in database */
181 DupsArray[Dups++] = dbRec.checksum;
186 printf("dbm_close(dbm)\n");
189 dbm_close(dbm); /* close to eliminate chance of in-memory caching */
191 printf("dbm_open(%s, O_RDONLY, 0)\n", filename);
194 dbm = dbm_open(filename, O_RDONLY, 0);
196 DoSysError("\ndbm_open", -1);
200 int DoDbmLookup(void)
207 printf("\n\tSequential lookups...\n");
209 for(i=0, j=0; i<numDbmEntries; i++) {
210 key.dptr = (char *)(KeyArray+j);
211 key.dsize = sizeof(KeyArray[0]);
215 printf("dbm_fetch(dbm, key = %d)\n", j);
218 content = dbm_fetch(dbm, key);
219 dbp = (myDB *)content.dptr;
220 if ( !content.dptr ) {
222 if (n) printf("\n\ndbm_error: %d\n", n);
223 printf("\n%d: Sequential Lookup of key %4x failed!\n",
225 DumpKeys(i, KeyArray[j]);
234 if (debugflg && dbp) {
235 printf("Seq rec #%-6d: checksum %4x (%4x)\r", i,
236 dbp->checksum, KeyArray[j]);
240 if (content.dsize == 0) {
241 printf("\nrec #%-8d: key = %4x (%d)\n", i, KeyArray[j], j);
243 DoSysError("\ndbm_fetch", content.dsize);
245 if (dbp->checksum != KeyArray[j])
246 CkSumError("KeySequential", dbp->checksum, KeyArray[j]);
247 if ((tmpck = calccksum(dbp->data, sizeof(dbp->data))) != KeyArray[j])
248 CkSumError("DataSequential", tmpck, KeyArray[j]);
252 printf("\n\n\tRandom lookups...\n");
254 for(i=0; i<numDbmEntries; i++) {
255 n = random() % keyIdx;
256 key.dptr = (char *)(KeyArray+n);
257 key.dsize = sizeof(KeyArray[0]);
259 printf("dbm_fetch(dbm, key = %d)\n", n);
262 content = dbm_fetch(dbm, key);
263 dbp = (myDB *)content.dptr;
264 if ( !content.dptr ) {
266 if (n) printf("\n\ndbm_error: %d\n", n);
267 printf("\n%d: Random Lookup of key %4x failed!\n",
269 DumpKeys(n, KeyArray[n]);
277 if (debugflg && dbp) {
278 printf("Rnd rec #%-6d: checksum %4x (%4x)\r", i,
279 dbp->checksum, KeyArray[n]);
283 if (content.dsize == 0)
284 DoSysError("\ndbm_fetch", content.dsize);
285 if (dbp->checksum != KeyArray[n])
286 CkSumError("KeyRand", dbp->checksum, KeyArray[n]);
287 if ((tmpck = calccksum(dbp->data, sizeof(dbp->data))) != KeyArray[n])
288 CkSumError("DataRand", tmpck, KeyArray[n]);
293 void CleanupDbmLookup(void)
299 printf("dbm_close(dbm)\n");
303 sprintf(filename, "%s-%d.dir", DBNAME, (int)getpid());
304 rc = unlink(filename);
305 if (rc) DoSysError("\nunlink", rc);
306 sprintf(filename, "%s-%d.pag", DBNAME, (int)getpid());
307 rc = unlink(filename);
308 if (rc) DoSysError("\nunlink", rc);
311 void DoSysError(char *msg, int rc)
314 fprintf(stderr, "Bailing out! status = %d\n", rc);
318 int creatDbRec(myDB *dbp)
329 printf("\tusing %ld as seed for srandom()...\n\n",
335 ptr = (long *)&(dbp->data);
336 j = sizeof(dbp->data) / sizeof(long);
337 for (i=0; i < j; i++, ptr++) {
340 for (i=(j*sizeof(long)); i<sizeof(dbp->data); i++)
341 dbp->data[i] = (char)time(0);
343 dbp->checksum = calccksum(dbp->data, sizeof(dbp->data));
347 unsigned short calccksum(char *ptr, int size)
353 n = ((size > 100) ? 100 : size);
354 for (i=0; i<n && ptr; i++, ptr++) {
356 sum = (sum >> 1) + 0x8000;
359 sum += (unsigned short)*ptr;
366 void CkSumError(char *msg, unsigned short ck1, unsigned short ck2)
369 printf("%s\n\tChecksum error, %u != %u, Total errors = %d\n",
370 msg, ck1, ck2, Errors);
374 int InsertKey(unsigned short *k, int idx, unsigned short val)
380 return( (k[idx] = val) );
383 for (i=0; i<idx; i++) {
397 void DumpKeys(int n, unsigned short key)
405 if ((f = fopen("keys", "a")) == NULL) {
406 perror("open(keys)");
410 for (i=0, p=arr; i<keyIdx && p; i++, p++)
412 fprintf(f, "%d: 0x%x\n", n, key);