1/* 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2005-2009 Oracle. All rights reserved. 5 * 6 * $Id$ 7 */ 8#include "bench.h" 9 10static int b_put_usage(void); 11static int b_put_secondary(DB *, const DBT *, const DBT *, DBT *); 12 13int 14b_put(int argc, char *argv[]) 15{ 16 extern char *optarg; 17 extern int optind, __db_getopt_reset; 18 DB_ENV *dbenv; 19 DB *dbp, **second; 20 DBTYPE type; 21 DBT key, data; 22 db_recno_t recno; 23 u_int32_t cachesize, dsize; 24 int ch, i, count, secondaries; 25 char *ts, buf[64]; 26 27 second = NULL; 28 type = DB_BTREE; 29 cachesize = MEGABYTE; 30 dsize = 20; 31 count = 100000; 32 secondaries = 0; 33 ts = "Btree"; 34 __db_getopt_reset = 1; 35 while ((ch = getopt(argc, argv, "C:c:d:s:t:")) != EOF) 36 switch (ch) { 37 case 'C': 38 cachesize = (u_int32_t)atoi(optarg); 39 break; 40 case 'c': 41 count = atoi(optarg); 42 break; 43 case 'd': 44 dsize = (u_int32_t)atoi(optarg); 45 break; 46 case 's': 47 secondaries = atoi(optarg); 48 break; 49 case 't': 50 switch (optarg[0]) { 51 case 'B': case 'b': 52 ts = "Btree"; 53 type = DB_BTREE; 54 break; 55 case 'H': case 'h': 56 if (b_util_have_hash()) 57 return (0); 58 ts = "Hash"; 59 type = DB_HASH; 60 break; 61 case 'Q': case 'q': 62 if (b_util_have_queue()) 63 return (0); 64 ts = "Queue"; 65 type = DB_QUEUE; 66 break; 67 case 'R': case 'r': 68 ts = "Recno"; 69 type = DB_RECNO; 70 break; 71 default: 72 return (b_put_usage()); 73 } 74 break; 75 case '?': 76 default: 77 return (b_put_usage()); 78 } 79 argc -= optind; 80 argv += optind; 81 if (argc != 0) 82 return (b_put_usage()); 83 84#if DB_VERSION_MAJOR < 3 || DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR < 3 85 /* 86 * Secondaries were added after DB 3.2.9. 87 */ 88 if (secondaries) 89 return (0); 90#endif 91 92 /* Create the environment. */ 93 DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0); 94 dbenv->set_errfile(dbenv, stderr); 95 DB_BENCH_ASSERT(dbenv->set_cachesize(dbenv, 0, cachesize, 0) == 0); 96#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR < 1 97 DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, 98 NULL, DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE, 0666) == 0); 99#else 100 DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, 101 DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE, 0666) == 0); 102#endif 103 104 /* 105 * Create the database. 106 * Optionally set the record length for Queue. 107 */ 108 DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0); 109 if (type == DB_QUEUE) 110 DB_BENCH_ASSERT(dbp->set_re_len(dbp, dsize) == 0); 111#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 112 DB_BENCH_ASSERT( 113 dbp->open(dbp, NULL, TESTFILE, NULL, type, DB_CREATE, 0666) == 0); 114#else 115 DB_BENCH_ASSERT( 116 dbp->open(dbp, TESTFILE, NULL, type, DB_CREATE, 0666) == 0); 117#endif 118 119 /* Optionally create the secondaries. */ 120 if (secondaries != 0) { 121 DB_BENCH_ASSERT((second = 122 calloc(sizeof(DB *), (size_t)secondaries)) != NULL); 123 for (i = 0; i < secondaries; ++i) { 124 DB_BENCH_ASSERT(db_create(&second[i], dbenv, 0) == 0); 125 (void)snprintf(buf, sizeof(buf), "%d.db", i); 126#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 127 DB_BENCH_ASSERT(second[i]->open(second[i], NULL, 128 buf, NULL, DB_BTREE, DB_CREATE, 0600) == 0); 129#else 130 DB_BENCH_ASSERT(second[i]->open(second[i], 131 buf, NULL, DB_BTREE, DB_CREATE, 0600) == 0); 132#endif 133#if DB_VERSION_MAJOR > 3 || DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR >= 3 134#if DB_VERSION_MAJOR > 3 && DB_VERSION_MINOR > 0 135 /* 136 * The DB_TXN argument to Db.associate was added in 137 * 4.1.25. 138 */ 139 DB_BENCH_ASSERT(dbp->associate( 140 dbp, NULL, second[i], b_put_secondary, 0) == 0); 141#else 142 DB_BENCH_ASSERT(dbp->associate( 143 dbp, second[i], b_put_secondary, 0) == 0); 144#endif 145#endif 146 } 147 } 148 149 /* Store a key/data pair. */ 150 memset(&key, 0, sizeof(key)); 151 memset(&data, 0, sizeof(data)); 152 switch (type) { 153 case DB_BTREE: 154 case DB_HASH: 155 key.data = "01234567890123456789"; 156 key.size = 20; 157 break; 158 case DB_QUEUE: 159 case DB_RECNO: 160 recno = 1; 161 key.data = &recno; 162 key.size = sizeof(recno); 163 break; 164 case DB_UNKNOWN: 165 b_util_abort(); 166 break; 167 } 168 169 data.size = dsize; 170 DB_BENCH_ASSERT( 171 (data.data = malloc((size_t)dsize)) != NULL); 172 173 /* Store the key/data pair count times. */ 174 TIMER_START; 175 for (i = 0; i < count; ++i) { 176 /* Change data value so the secondaries are updated. */ 177 (void)snprintf(data.data, data.size, "%10lu", (u_long)i); 178 DB_BENCH_ASSERT(dbp->put(dbp, NULL, &key, &data, 0) == 0); 179 } 180 TIMER_STOP; 181 182 if (type == DB_BTREE || type == DB_HASH) 183 printf( 184 "# %d %s database put of 10 byte key, %lu byte data", 185 count, ts, (u_long)dsize); 186 else 187 printf("# %d %s database put of key, %lu byte data", 188 count, ts, (u_long)dsize); 189 if (secondaries) 190 printf(" with %d secondaries", secondaries); 191 printf("\n"); 192 TIMER_DISPLAY(count); 193 194 if (second != NULL) { 195 for (i = 0; i < secondaries; ++i) 196 DB_BENCH_ASSERT(second[i]->close(second[i], 0) == 0); 197 free(second); 198 } 199 200 DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0); 201 DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0); 202 203 return (0); 204} 205 206static int 207b_put_secondary(dbp, pkey, pdata, skey) 208 DB *dbp; 209 const DBT *pkey, *pdata; 210 DBT *skey; 211{ 212 skey->data = pdata->data; 213 skey->size = pdata->size; 214 215 COMPQUIET(dbp, NULL); 216 COMPQUIET(pkey, NULL); 217 return (0); 218} 219 220static int 221b_put_usage() 222{ 223 (void)fprintf(stderr, "usage: b_put %s\n", 224 "[-C cachesz] [-c count] [-d bytes] [-s secondaries] [-t type]"); 225 return (EXIT_FAILURE); 226} 227