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