root/lib/tdb/tools/tdbtest.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _start_timer
  2. _end_timer
  3. fatal
  4. tdb_log
  5. compare_db
  6. randbuf
  7. addrec_db
  8. addrec_gdbm
  9. traverse_fn
  10. merge_test
  11. main

   1 /* a test program for tdb - the trivial database */
   2 
   3 #include "replace.h"
   4 #include "tdb.h"
   5 #include "system/filesys.h"
   6 #include "system/time.h"
   7 
   8 #include <gdbm.h>
   9 
  10 
  11 #define DELETE_PROB 7
  12 #define STORE_PROB 5
  13 
  14 static struct tdb_context *db;
  15 static GDBM_FILE gdbm;
  16 
  17 struct timeval tp1,tp2;
  18 
  19 static void _start_timer(void)
     /* [<][>][^][v][top][bottom][index][help] */
  20 {
  21         gettimeofday(&tp1,NULL);
  22 }
  23 
  24 static double _end_timer(void)
     /* [<][>][^][v][top][bottom][index][help] */
  25 {
  26         gettimeofday(&tp2,NULL);
  27         return((tp2.tv_sec - tp1.tv_sec) + 
  28                (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
  29 }
  30 
  31 static void fatal(const char *why)
     /* [<][>][^][v][top][bottom][index][help] */
  32 {
  33         perror(why);
  34         exit(1);
  35 }
  36 
  37 #ifdef PRINTF_ATTRIBUTE
  38 static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...) PRINTF_ATTRIBUTE(3,4);
     /* [<][>][^][v][top][bottom][index][help] */
  39 #endif
  40 static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...)
  41 {
  42         va_list ap;
  43     
  44         va_start(ap, format);
  45         vfprintf(stdout, format, ap);
  46         va_end(ap);
  47         fflush(stdout);
  48 }
  49 
  50 static void compare_db(void)
     /* [<][>][^][v][top][bottom][index][help] */
  51 {
  52         TDB_DATA d, key, nextkey;
  53         datum gd, gkey, gnextkey;
  54 
  55         key = tdb_firstkey(db);
  56         while (key.dptr) {
  57                 d = tdb_fetch(db, key);
  58                 gkey.dptr = key.dptr;
  59                 gkey.dsize = key.dsize;
  60 
  61                 gd = gdbm_fetch(gdbm, gkey);
  62 
  63                 if (!gd.dptr) fatal("key not in gdbm");
  64                 if (gd.dsize != d.dsize) fatal("data sizes differ");
  65                 if (memcmp(gd.dptr, d.dptr, d.dsize)) {
  66                         fatal("data differs");
  67                 }
  68 
  69                 nextkey = tdb_nextkey(db, key);
  70                 free(key.dptr);
  71                 free(d.dptr);
  72                 free(gd.dptr);
  73                 key = nextkey;
  74         }
  75 
  76         gkey = gdbm_firstkey(gdbm);
  77         while (gkey.dptr) {
  78                 gd = gdbm_fetch(gdbm, gkey);
  79                 key.dptr = gkey.dptr;
  80                 key.dsize = gkey.dsize;
  81 
  82                 d = tdb_fetch(db, key);
  83 
  84                 if (!d.dptr) fatal("key not in db");
  85                 if (d.dsize != gd.dsize) fatal("data sizes differ");
  86                 if (memcmp(d.dptr, gd.dptr, gd.dsize)) {
  87                         fatal("data differs");
  88                 }
  89 
  90                 gnextkey = gdbm_nextkey(gdbm, gkey);
  91                 free(gkey.dptr);
  92                 free(gd.dptr);
  93                 free(d.dptr);
  94                 gkey = gnextkey;
  95         }
  96 }
  97 
  98 static char *randbuf(int len)
     /* [<][>][^][v][top][bottom][index][help] */
  99 {
 100         char *buf;
 101         int i;
 102         buf = (char *)malloc(len+1);
 103 
 104         for (i=0;i<len;i++) {
 105                 buf[i] = 'a' + (rand() % 26);
 106         }
 107         buf[i] = 0;
 108         return buf;
 109 }
 110 
 111 static void addrec_db(void)
     /* [<][>][^][v][top][bottom][index][help] */
 112 {
 113         int klen, dlen;
 114         char *k, *d;
 115         TDB_DATA key, data;
 116 
 117         klen = 1 + (rand() % 4);
 118         dlen = 1 + (rand() % 100);
 119 
 120         k = randbuf(klen);
 121         d = randbuf(dlen);
 122 
 123         key.dptr = k;
 124         key.dsize = klen+1;
 125 
 126         data.dptr = d;
 127         data.dsize = dlen+1;
 128 
 129         if (rand() % DELETE_PROB == 0) {
 130                 tdb_delete(db, key);
 131         } else if (rand() % STORE_PROB == 0) {
 132                 if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
 133                         fatal("tdb_store failed");
 134                 }
 135         } else {
 136                 data = tdb_fetch(db, key);
 137                 if (data.dptr) free(data.dptr);
 138         }
 139 
 140         free(k);
 141         free(d);
 142 }
 143 
 144 static void addrec_gdbm(void)
     /* [<][>][^][v][top][bottom][index][help] */
 145 {
 146         int klen, dlen;
 147         char *k, *d;
 148         datum key, data;
 149 
 150         klen = 1 + (rand() % 4);
 151         dlen = 1 + (rand() % 100);
 152 
 153         k = randbuf(klen);
 154         d = randbuf(dlen);
 155 
 156         key.dptr = k;
 157         key.dsize = klen+1;
 158 
 159         data.dptr = d;
 160         data.dsize = dlen+1;
 161 
 162         if (rand() % DELETE_PROB == 0) {
 163                 gdbm_delete(gdbm, key);
 164         } else if (rand() % STORE_PROB == 0) {
 165                 if (gdbm_store(gdbm, key, data, GDBM_REPLACE) != 0) {
 166                         fatal("gdbm_store failed");
 167                 }
 168         } else {
 169                 data = gdbm_fetch(gdbm, key);
 170                 if (data.dptr) free(data.dptr);
 171         }
 172 
 173         free(k);
 174         free(d);
 175 }
 176 
 177 static int traverse_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
     /* [<][>][^][v][top][bottom][index][help] */
 178 {
 179 #if 0
 180         printf("[%s] [%s]\n", key.dptr, dbuf.dptr);
 181 #endif
 182         tdb_delete(tdb, key);
 183         return 0;
 184 }
 185 
 186 static void merge_test(void)
     /* [<][>][^][v][top][bottom][index][help] */
 187 {
 188         int i;
 189         char keys[5][2];
 190         char tdata[] = "test";
 191         TDB_DATA key, data;
 192         
 193         for (i = 0; i < 5; i++) {
 194                 snprintf(keys[i],2, "%d", i);
 195                 key.dptr = keys[i];
 196                 key.dsize = 2;
 197                 
 198                 data.dptr = tdata;
 199                 data.dsize = 4;
 200                 
 201                 if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
 202                         fatal("tdb_store failed");
 203                 }
 204         }
 205 
 206         key.dptr = keys[0];
 207         tdb_delete(db, key);
 208         key.dptr = keys[4];
 209         tdb_delete(db, key);
 210         key.dptr = keys[2];
 211         tdb_delete(db, key);
 212         key.dptr = keys[1];
 213         tdb_delete(db, key);
 214         key.dptr = keys[3];
 215         tdb_delete(db, key);
 216 }
 217 
 218  int main(int argc, const char *argv[])
     /* [<][>][^][v][top][bottom][index][help] */
 219 {
 220         int i, seed=0;
 221         int loops = 10000;
 222         int num_entries;
 223         char test_gdbm[] = "test.gdbm";
 224 
 225         unlink("test.gdbm");
 226 
 227         db = tdb_open("test.tdb", 0, TDB_CLEAR_IF_FIRST, 
 228                       O_RDWR | O_CREAT | O_TRUNC, 0600);
 229         gdbm = gdbm_open(test_gdbm, 512, GDBM_WRITER|GDBM_NEWDB|GDBM_FAST, 
 230                          0600, NULL);
 231 
 232         if (!db || !gdbm) {
 233                 fatal("db open failed");
 234         }
 235 
 236 #if 1
 237         srand(seed);
 238         _start_timer();
 239         for (i=0;i<loops;i++) addrec_gdbm();
 240         printf("gdbm got %.2f ops/sec\n", i/_end_timer());
 241 #endif
 242 
 243         merge_test();
 244 
 245         srand(seed);
 246         _start_timer();
 247         for (i=0;i<loops;i++) addrec_db();
 248         printf("tdb got %.2f ops/sec\n", i/_end_timer());
 249 
 250         if (tdb_validate_freelist(db, &num_entries) == -1) {
 251                 printf("tdb freelist is corrupt\n");
 252         } else {
 253                 printf("tdb freelist is good (%d entries)\n", num_entries);
 254         }
 255 
 256         compare_db();
 257 
 258         printf("traversed %d records\n", tdb_traverse(db, traverse_fn, NULL));
 259         printf("traversed %d records\n", tdb_traverse(db, traverse_fn, NULL));
 260 
 261         tdb_close(db);
 262         gdbm_close(gdbm);
 263 
 264         return 0;
 265 }

/* [<][>][^][v][top][bottom][index][help] */