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>
36 /* #define WorkDir "/xfs" */
37 #define DBNAME "DBtest"
41 typedef struct _myDB {
43 unsigned short checksum;
47 int InitDbmLookup(int);
48 int DoDbmLookup(void);
49 void CleanupDbmLookup(void);
50 void DoSysError(char *, int);
51 int creatDbRec(myDB *);
52 unsigned short calccksum(char *, int);
53 void CkSumError(char *, unsigned short, unsigned short);
54 int InsertKey(unsigned short *, int, unsigned short);
55 void DumpKeys(int, unsigned short);
58 int numDbmEntries, keyIdx, Dups = 0, Errors = 0;
59 unsigned short *KeyArray, *DupsArray;
60 int debugflg = 0; /* are we in debugging mode? */
61 int errflg = 0; /* usage option errors */
62 int ignoreflg = 1; /* ignore errors in lookup; default = on */
67 main(int argc, char *argv[])
69 int numrecs = DBRECS, c, l;
71 while ((c = getopt(argc, argv, "idn:l:s:")) != EOF) {
78 numrecs = atoi(optarg);
79 numrecs = (numrecs < 1) ? DBRECS : numrecs;
83 loops = (loops < 1) ? LOOPS : loops;
86 randseed = atoi(optarg);
87 randseed = (randseed < 0) ? 0 : randseed;
95 printf("Usage: dbtest [-di] [-n number] [-l loop] [-s randseed]\n");
99 printf("Extra arguments ignored\n");
100 for ( ; optind<argc; optind++)
101 printf("\t%s\n", argv[optind]);
104 printf("dbtest v1.0\n\n");
105 printf("Creating database containing %d records...\n", numrecs);
106 printf("\tperforming lookups for %d iterations...\n", loops);
108 printf("\tusing %d as seed for srandom()...\n\n", randseed);
110 InitDbmLookup(numrecs);
111 printf("\t\nThere were %d duplicate checksums generated\n", Dups);
112 for (l=0; l<loops; l++) {
113 printf("\nPerforming lookups on database...\n");
114 if (DoDbmLookup() != numrecs)
115 printf("\nError performing lookups!\n");
117 printf("\nLookups succeeded...\n");
119 printf("\nCleaning up database...\n");
120 printf("\t\nThere were %d duplicate checksums generated\n", Dups);
124 for (l=0; l<Dups; l++) {
127 printf("0x%x\t", DupsArray[l]);
134 int InitDbmLookup(int howmany)
141 sprintf(filename, "%s-%d", DBNAME, (int)getpid());
143 printf("dbm_open(%s, O_WRONLY|O_CREAT, 0644)\n", filename);
146 dbm = dbm_open(filename, O_WRONLY|O_CREAT, 0644);
147 if(dbm == NULL) DoSysError("\ndbm_open", (int)dbm);
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_RDNLY, 0)\n", filename);
197 dbm = dbm_open(filename, O_RDONLY, 0);
198 if(dbm == NULL) DoSysError("\ndbm_open", (int)dbm);
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);