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>
34 /* #define WorkDir "/xfs" */
35 #define DBNAME "DBtest"
39 typedef struct _myDB {
41 unsigned short checksum;
45 int InitDbmLookup(int);
46 int DoDbmLookup(void);
47 void CleanupDbmLookup(void);
48 void DoSysError(char *, int);
49 int creatDbRec(myDB *);
50 unsigned short calccksum(char *, int);
51 void CkSumError(char *, unsigned short, unsigned short);
52 int InsertKey(unsigned short *, int, unsigned short);
53 void DumpKeys(int, unsigned short);
56 int numDbmEntries, keyIdx, Dups = 0, Errors = 0;
57 unsigned short *KeyArray, *DupsArray;
58 int debugflg = 0; /* are we in debugging mode? */
59 int errflg = 0; /* usage option errors */
60 int ignoreflg = 1; /* ignore errors in lookup; default = on */
65 main(int argc, char *argv[])
67 int numrecs = DBRECS, c, l;
69 while ((c = getopt(argc, argv, "idn:l:s:")) != EOF) {
76 numrecs = atoi(optarg);
77 numrecs = (numrecs < 1) ? DBRECS : numrecs;
81 loops = (loops < 1) ? LOOPS : loops;
84 randseed = atoi(optarg);
85 randseed = (randseed < 0) ? 0 : randseed;
93 printf("Usage: dbtest [-di] [-n number] [-l loop] [-s randseed]\n");
97 printf("Extra arguments ignored\n");
98 for ( ; optind<argc; optind++)
99 printf("\t%s\n", argv[optind]);
102 printf("dbtest v1.0\n\n");
103 printf("Creating database containing %d records...\n", numrecs);
104 printf("\tperforming lookups for %d iterations...\n", loops);
106 printf("\tusing %d as seed for srandom()...\n\n", randseed);
108 InitDbmLookup(numrecs);
109 printf("\t\nThere were %d duplicate checksums generated\n", Dups);
110 for (l=0; l<loops; l++) {
111 printf("\nPerforming lookups on database...\n");
112 if (DoDbmLookup() != numrecs)
113 printf("\nError performing lookups!\n");
115 printf("\nLookups succeeded...\n");
117 printf("\nCleaning up database...\n");
118 printf("\t\nThere were %d duplicate checksums generated\n", Dups);
122 for (l=0; l<Dups; l++) {
125 printf("0x%x\t", DupsArray[l]);
132 int InitDbmLookup(int howmany)
139 sprintf(filename, "%s-%d", DBNAME, (int)getpid());
141 printf("dbm_open(%s, O_RDWR|O_CREAT, 0644)\n", filename);
144 dbm = dbm_open(filename, O_RDWR|O_CREAT, 0644);
146 DoSysError("\ndbm_open", -1);
148 if ((KeyArray = (unsigned short *)calloc( howmany,
149 sizeof(unsigned short))) == NULL)
150 DoSysError("\ncalloc:KeyArray", -1);
151 if ((DupsArray = (unsigned short *)calloc( 100,
152 sizeof(unsigned short))) == NULL)
153 DoSysError("\ncalloc:DupsArray", -1);
156 for(i=0; i<howmany; i++) {
158 if ( creatDbRec(&dbRec) )
159 DoSysError("\ncreatDbRec", -1);
161 printf("created rec #%-7d\t%x\r", i+1, dbRec.checksum);
165 if (InsertKey(KeyArray, keyIdx, dbRec.checksum))
168 key.dptr = (char *)&(dbRec.checksum);
169 key.dsize = sizeof(dbRec.checksum);
170 content.dptr = (char *)&dbRec;
171 content.dsize = sizeof(dbRec);
176 printf("dbm_store(dbm, key, content, DBM_INSERT)\n");
178 rc = dbm_store(dbm, key, content, DBM_INSERT);
180 DoSysError("\ndbm_store", rc);
182 keyIdx--; /* key is already in database */
183 DupsArray[Dups++] = dbRec.checksum;
188 printf("dbm_close(dbm)\n");
191 dbm_close(dbm); /* close to eliminate chance of in-memory caching */
193 printf("dbm_open(%s, O_RDONLY, 0)\n", filename);
196 dbm = dbm_open(filename, O_RDONLY, 0);
198 DoSysError("\ndbm_open", -1);
202 int DoDbmLookup(void)
209 printf("\n\tSequential lookups...\n");
211 for(i=0, j=0; i<numDbmEntries; i++) {
212 key.dptr = (char *)(KeyArray+j);
213 key.dsize = sizeof(KeyArray[0]);
217 printf("dbm_fetch(dbm, key = %d)\n", j);
220 content = dbm_fetch(dbm, key);
221 dbp = (myDB *)content.dptr;
222 if ( !content.dptr ) {
224 if (n) printf("\n\ndbm_error: %d\n", n);
225 printf("\n%d: Sequential Lookup of key %4x failed!\n",
227 DumpKeys(i, KeyArray[j]);
236 if (debugflg && dbp) {
237 printf("Seq rec #%-6d: checksum %4x (%4x)\r", i,
238 dbp->checksum, KeyArray[j]);
242 if (content.dsize == 0) {
243 printf("\nrec #%-8d: key = %4x (%d)\n", i, KeyArray[j], j);
245 DoSysError("\ndbm_fetch", content.dsize);
247 if (dbp->checksum != KeyArray[j])
248 CkSumError("KeySequential", dbp->checksum, KeyArray[j]);
249 if ((tmpck = calccksum(dbp->data, sizeof(dbp->data))) != KeyArray[j])
250 CkSumError("DataSequential", tmpck, KeyArray[j]);
254 printf("\n\n\tRandom lookups...\n");
256 for(i=0; i<numDbmEntries; i++) {
257 n = random() % keyIdx;
258 key.dptr = (char *)(KeyArray+n);
259 key.dsize = sizeof(KeyArray[0]);
261 printf("dbm_fetch(dbm, key = %d)\n", n);
264 content = dbm_fetch(dbm, key);
265 dbp = (myDB *)content.dptr;
266 if ( !content.dptr ) {
268 if (n) printf("\n\ndbm_error: %d\n", n);
269 printf("\n%d: Random Lookup of key %4x failed!\n",
271 DumpKeys(n, KeyArray[n]);
279 if (debugflg && dbp) {
280 printf("Rnd rec #%-6d: checksum %4x (%4x)\r", i,
281 dbp->checksum, KeyArray[n]);
285 if (content.dsize == 0)
286 DoSysError("\ndbm_fetch", content.dsize);
287 if (dbp->checksum != KeyArray[n])
288 CkSumError("KeyRand", dbp->checksum, KeyArray[n]);
289 if ((tmpck = calccksum(dbp->data, sizeof(dbp->data))) != KeyArray[n])
290 CkSumError("DataRand", tmpck, KeyArray[n]);
295 void CleanupDbmLookup(void)
301 printf("dbm_close(dbm)\n");
305 sprintf(filename, "%s-%d.dir", DBNAME, (int)getpid());
306 rc = unlink(filename);
307 if (rc) DoSysError("\nunlink", rc);
308 sprintf(filename, "%s-%d.pag", DBNAME, (int)getpid());
309 rc = unlink(filename);
310 if (rc) DoSysError("\nunlink", rc);
313 void DoSysError(char *msg, int rc)
316 fprintf(stderr, "Bailing out! status = %d\n", rc);
320 int creatDbRec(myDB *dbp)
331 printf("\tusing %ld as seed for srandom()...\n\n",
337 ptr = (long *)&(dbp->data);
338 j = sizeof(dbp->data) / sizeof(long);
339 for (i=0; i < j; i++, ptr++) {
342 for (i=(j*sizeof(long)); i<sizeof(dbp->data); i++)
343 dbp->data[i] = (char)time(0);
345 dbp->checksum = calccksum(dbp->data, sizeof(dbp->data));
349 unsigned short calccksum(char *ptr, int size)
355 n = ((size > 100) ? 100 : size);
356 for (i=0; i<n && ptr; i++, ptr++) {
358 sum = (sum >> 1) + 0x8000;
361 sum += (unsigned short)*ptr;
368 void CkSumError(char *msg, unsigned short ck1, unsigned short ck2)
371 printf("%s\n\tChecksum error, %u != %u, Total errors = %d\n",
372 msg, ck1, ck2, Errors);
376 int InsertKey(unsigned short *k, int idx, unsigned short val)
382 return( (k[idx] = val) );
385 for (i=0; i<idx; i++) {
399 void DumpKeys(int n, unsigned short key)
407 if ((f = fopen("keys", "a")) == NULL) {
408 perror("open(keys)");
412 for (i=0, p=arr; i<keyIdx && p; i++, p++)
414 fprintf(f, "%d: 0x%x\n", n, key);