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>
35 /* #define WorkDir "/xfs" */
36 #define DBNAME "DBtest"
40 typedef struct _myDB {
42 unsigned short checksum;
46 int InitDbmLookup(int);
47 int DoDbmLookup(void);
48 void CleanupDbmLookup(void);
49 void DoSysError(char *, int);
50 int creatDbRec(myDB *);
51 unsigned short calccksum(char *, int);
52 void CkSumError(char *, unsigned short, unsigned short);
53 int InsertKey(unsigned short *, int, unsigned short);
54 void DumpKeys(int, unsigned short);
57 int numDbmEntries, keyIdx, Dups = 0, Errors = 0;
58 unsigned short *KeyArray, *DupsArray;
59 int debugflg = 0; /* are we in debugging mode? */
60 int errflg = 0; /* usage option errors */
61 int ignoreflg = 1; /* ignore errors in lookup; default = on */
66 main(int argc, char *argv[])
68 int numrecs = DBRECS, c, l;
70 while ((c = getopt(argc, argv, "idn:l:s:")) != EOF) {
77 numrecs = atoi(optarg);
78 numrecs = (numrecs < 1) ? DBRECS : numrecs;
82 loops = (loops < 1) ? LOOPS : loops;
85 randseed = atoi(optarg);
86 randseed = (randseed < 0) ? 0 : randseed;
94 printf("Usage: dbtest [-di] [-n number] [-l loop] [-s randseed]\n");
98 printf("Extra arguments ignored\n");
99 for ( ; optind<argc; optind++)
100 printf("\t%s\n", argv[optind]);
103 printf("dbtest v1.0\n\n");
104 printf("Creating database containing %d records...\n", numrecs);
105 printf("\tperforming lookups for %d iterations...\n", loops);
107 printf("\tusing %d as seed for srandom()...\n\n", randseed);
109 InitDbmLookup(numrecs);
110 printf("\t\nThere were %d duplicate checksums generated\n", Dups);
111 for (l=0; l<loops; l++) {
112 printf("\nPerforming lookups on database...\n");
113 if (DoDbmLookup() != numrecs)
114 printf("\nError performing lookups!\n");
116 printf("\nLookups succeeded...\n");
118 printf("\nCleaning up database...\n");
119 printf("\t\nThere were %d duplicate checksums generated\n", Dups);
123 for (l=0; l<Dups; l++) {
126 printf("0x%x\t", DupsArray[l]);
133 int InitDbmLookup(int howmany)
140 sprintf(filename, "%s-%d", DBNAME, (int)getpid());
142 printf("dbm_open(%s, O_RDWR|O_CREAT, 0644)\n", filename);
145 dbm = dbm_open(filename, O_RDWR|O_CREAT, 0644);
147 DoSysError("\ndbm_open", -1);
149 if ((KeyArray = (unsigned short *)calloc( howmany,
150 sizeof(unsigned short))) == NULL)
151 DoSysError("\ncalloc:KeyArray", -1);
152 if ((DupsArray = (unsigned short *)calloc( 100,
153 sizeof(unsigned short))) == NULL)
154 DoSysError("\ncalloc:DupsArray", -1);
157 for(i=0; i<howmany; i++) {
159 if ( creatDbRec(&dbRec) )
160 DoSysError("\ncreatDbRec", -1);
162 printf("created rec #%-7d\t%x\r", i+1, dbRec.checksum);
166 if (InsertKey(KeyArray, keyIdx, dbRec.checksum))
169 key.dptr = (char *)&(dbRec.checksum);
170 key.dsize = sizeof(dbRec.checksum);
171 content.dptr = (char *)&dbRec;
172 content.dsize = sizeof(dbRec);
177 printf("dbm_store(dbm, key, content, DBM_INSERT)\n");
179 rc = dbm_store(dbm, key, content, DBM_INSERT);
181 DoSysError("\ndbm_store", rc);
183 keyIdx--; /* key is already in database */
184 DupsArray[Dups++] = dbRec.checksum;
189 printf("dbm_close(dbm)\n");
192 dbm_close(dbm); /* close to eliminate chance of in-memory caching */
194 printf("dbm_open(%s, O_RDONLY, 0)\n", filename);
197 dbm = dbm_open(filename, O_RDONLY, 0);
199 DoSysError("\ndbm_open", -1);
203 int DoDbmLookup(void)
210 printf("\n\tSequential lookups...\n");
212 for(i=0, j=0; i<numDbmEntries; i++) {
213 key.dptr = (char *)(KeyArray+j);
214 key.dsize = sizeof(KeyArray[0]);
218 printf("dbm_fetch(dbm, key = %d)\n", j);
221 content = dbm_fetch(dbm, key);
222 dbp = (myDB *)content.dptr;
223 if ( !content.dptr ) {
225 if (n) printf("\n\ndbm_error: %d\n", n);
226 printf("\n%d: Sequential Lookup of key %4x failed!\n",
228 DumpKeys(i, KeyArray[j]);
237 if (debugflg && dbp) {
238 printf("Seq rec #%-6d: checksum %4x (%4x)\r", i,
239 dbp->checksum, KeyArray[j]);
243 if (content.dsize == 0) {
244 printf("\nrec #%-8d: key = %4x (%d)\n", i, KeyArray[j], j);
246 DoSysError("\ndbm_fetch", content.dsize);
248 if (dbp->checksum != KeyArray[j])
249 CkSumError("KeySequential", dbp->checksum, KeyArray[j]);
250 if ((tmpck = calccksum(dbp->data, sizeof(dbp->data))) != KeyArray[j])
251 CkSumError("DataSequential", tmpck, KeyArray[j]);
255 printf("\n\n\tRandom lookups...\n");
257 for(i=0; i<numDbmEntries; i++) {
258 n = random() % keyIdx;
259 key.dptr = (char *)(KeyArray+n);
260 key.dsize = sizeof(KeyArray[0]);
262 printf("dbm_fetch(dbm, key = %d)\n", n);
265 content = dbm_fetch(dbm, key);
266 dbp = (myDB *)content.dptr;
267 if ( !content.dptr ) {
269 if (n) printf("\n\ndbm_error: %d\n", n);
270 printf("\n%d: Random Lookup of key %4x failed!\n",
272 DumpKeys(n, KeyArray[n]);
280 if (debugflg && dbp) {
281 printf("Rnd rec #%-6d: checksum %4x (%4x)\r", i,
282 dbp->checksum, KeyArray[n]);
286 if (content.dsize == 0)
287 DoSysError("\ndbm_fetch", content.dsize);
288 if (dbp->checksum != KeyArray[n])
289 CkSumError("KeyRand", dbp->checksum, KeyArray[n]);
290 if ((tmpck = calccksum(dbp->data, sizeof(dbp->data))) != KeyArray[n])
291 CkSumError("DataRand", tmpck, KeyArray[n]);
296 void CleanupDbmLookup(void)
302 printf("dbm_close(dbm)\n");
306 sprintf(filename, "%s-%d.dir", DBNAME, (int)getpid());
307 rc = unlink(filename);
308 if (rc) DoSysError("\nunlink", rc);
309 sprintf(filename, "%s-%d.pag", DBNAME, (int)getpid());
310 rc = unlink(filename);
311 if (rc) DoSysError("\nunlink", rc);
314 void DoSysError(char *msg, int rc)
317 fprintf(stderr, "Bailing out! status = %d\n", rc);
321 int creatDbRec(myDB *dbp)
332 printf("\tusing %ld as seed for srandom()...\n\n",
338 ptr = (long *)&(dbp->data);
339 j = sizeof(dbp->data) / sizeof(long);
340 for (i=0; i < j; i++, ptr++) {
343 for (i=(j*sizeof(long)); i<sizeof(dbp->data); i++)
344 dbp->data[i] = (char)time(0);
346 dbp->checksum = calccksum(dbp->data, sizeof(dbp->data));
350 unsigned short calccksum(char *ptr, int size)
356 n = ((size > 100) ? 100 : size);
357 for (i=0; i<n && ptr; i++, ptr++) {
359 sum = (sum >> 1) + 0x8000;
362 sum += (unsigned short)*ptr;
369 void CkSumError(char *msg, unsigned short ck1, unsigned short ck2)
372 printf("%s\n\tChecksum error, %u != %u, Total errors = %d\n",
373 msg, ck1, ck2, Errors);
377 int InsertKey(unsigned short *k, int idx, unsigned short val)
383 return( (k[idx] = val) );
386 for (i=0; i<idx; i++) {
400 void DumpKeys(int n, unsigned short key)
408 if ((f = fopen("keys", "a")) == NULL) {
409 perror("open(keys)");
413 for (i=0, p=arr; i<keyIdx && p; i++, p++)
415 fprintf(f, "%d: 0x%x\n", n, key);