1 #include "bmbase.c"
2 #include <dirent.h>
3 #include <wiredtiger.h>
4
5 #define DEFAULT_DB "wiretiger_bench.sb"
6
7 struct BMWT {
8 WT_CONNECTION *conn;
9 WT_SESSION *session;
10 WT_CURSOR *cursor;
11 } bmwt;
12
13 typedef struct BMWT BMWT;
14
15 static bool db_close(BMCTX *ctx);
16
env_setup()17 static void env_setup() {
18 fprintf(stderr, " engine: %s\n", WIREDTIGER_VERSION_STRING);
19 }
20
db_size_bytes(BMCTX * ctx)21 uint64_t db_size_bytes(BMCTX *ctx) {
22 char buf[PATH_MAX + 1];
23 DIR *d;
24 uint64_t sz = 0;
25 struct dirent *dir;
26 const char *path = bm.param_db ? bm.param_db : DEFAULT_DB;
27 d = opendir(path);
28 if (d) {
29 while ((dir = readdir(d))) {
30 snprintf(buf, sizeof(buf), "%s/%s", path, dir->d_name);
31 IWP_FILE_STAT fst;
32 iwrc rc = iwp_fstat(buf, &fst);
33 if (rc) {
34 iwlog_ecode_error3(rc);
35 return 0;
36 }
37 if (fst.ftype == IWP_TYPE_FILE) {
38 sz += fst.size;
39 }
40 }
41 closedir(d);
42 }
43 return sz;
44 }
45
db_open(BMCTX * ctx)46 static void *db_open(BMCTX *ctx) {
47 if (ctx->db || bmwt.conn) {
48 return 0; // db is not closed properly
49 }
50 bool wal_enabled = false;
51 for (int i = 0; i < bm.argc; ++i) {
52 if (!strcmp(bm.argv[i], "-w")) {
53 wal_enabled = true;
54 }
55 }
56 const char *path = bm.param_db ? bm.param_db : DEFAULT_DB;
57 if (ctx->freshdb) {
58 iwp_removedir(path);
59 }
60 iwp_mkdirs(path);
61 const char *common_config = "create,cache_size=1Gb,transaction_sync=(enabled=false)";
62 const char *wal_config = "checkpoint_sync=false";
63 if (wal_enabled) {
64 wal_config = "log=(enabled,recover=on),checkpoint=(wait=300,log_size=1Gb),checkpoint_sync=true";
65 }
66 char config[512];
67 snprintf(config, sizeof(config), "%s,%s", common_config, wal_config);
68
69 // fprintf(stderr, "%s\n", config);
70
71 int rc = wiredtiger_open(path, 0, config, &bmwt.conn);
72 RCGO(rc, finish);
73
74 rc = bmwt.conn->open_session(bmwt.conn, 0, 0, &bmwt.session);
75 RCGO(rc, finish);
76
77 rc = bmwt.session->create(bmwt.session, "table:test",
78 "split_pct=100,leaf_item_max=1KB,"
79 "type=lsm,internal_page_max=4KB,leaf_page_max=4KB");
80 RCGO(rc, finish);
81
82 rc = bmwt.session->open_cursor(bmwt.session, "table:test", 0, 0, &bmwt.cursor);
83
84 finish:
85 if (rc) {
86 fprintf(stderr, "db_open %s\n", wiredtiger_strerror(rc));
87 ctx->db = &bmwt;
88 db_close(ctx);
89 ctx->db = 0;
90 return 0;
91 }
92 return &bmwt;
93 }
94
db_close(BMCTX * ctx)95 static bool db_close(BMCTX *ctx) {
96 if (!ctx->db) {
97 return false;
98 }
99 bool ret = true;
100 BMWT *bmwt = ctx->db;
101 if (bmwt->cursor) {
102 int rc = bmwt->cursor->close(bmwt->cursor);
103 if (rc) {
104 fprintf(stderr, "db_close cursor %s\n", wiredtiger_strerror(rc));
105 ret = false;
106 }
107 }
108 if (bmwt->session) {
109 int rc = bmwt->session->close(bmwt->session, 0);
110 if (rc) {
111 fprintf(stderr, "db_close session %s\n", wiredtiger_strerror(rc));
112 ret = false;
113 }
114 }
115 if (bmwt->conn) {
116 int rc = bmwt->conn->close(bmwt->conn, 0);
117 if (rc) {
118 fprintf(stderr, "db_close conn %s\n", wiredtiger_strerror(rc));
119 ret = false;
120 }
121 }
122 bmwt->conn = 0;
123 bmwt->session = 0;
124 bmwt->cursor = 0;
125 return ret;
126 }
127
db_put(BMCTX * ctx,const IWKV_val * key,const IWKV_val * val,bool sync)128 static bool db_put(BMCTX *ctx, const IWKV_val *key, const IWKV_val *val, bool sync) {
129 BMWT *bmwt = ctx->db;
130 WT_ITEM k, v;
131 k.data = key->data;
132 k.size = key->size;
133 v.data = val->data;
134 v.size = val->size;
135
136 bmwt->cursor->set_key(bmwt->cursor, &k);
137 bmwt->cursor->set_value(bmwt->cursor, &v);
138 int rc = bmwt->cursor->insert(bmwt->cursor);
139 RCGO(rc, finish);
140 if (sync) {
141 rc = bmwt->session->log_flush(bmwt->session, "background=off");
142 }
143 finish:
144 if (rc) {
145 fprintf(stderr, "db_put %s\n", wiredtiger_strerror(rc));
146 }
147 return rc == 0;
148 }
149
db_get(BMCTX * ctx,const IWKV_val * key,IWKV_val * val,bool * found)150 static bool db_get(BMCTX *ctx, const IWKV_val *key, IWKV_val *val, bool *found) {
151 BMWT *bmwt = ctx->db;
152 WT_ITEM k, v;
153 k.data = key->data;
154 k.size = key->size;
155 bmwt->cursor->set_key(bmwt->cursor, &k);
156 int rc = bmwt->cursor->search(bmwt->cursor);
157 if (rc == WT_NOTFOUND) {
158 rc = 0;
159 *found = false;
160 } else if (!rc) {
161 *found = true;
162 rc = bmwt->cursor->get_value(bmwt->cursor, &v);
163 }
164 if (rc) {
165 fprintf(stderr, "db_get %s\n", wiredtiger_strerror(rc));
166 }
167 return rc == 0;
168 }
169
db_del(BMCTX * ctx,const IWKV_val * key,bool sync)170 static bool db_del(BMCTX *ctx, const IWKV_val *key, bool sync) {
171 BMWT *bmwt = ctx->db;
172 WT_ITEM k;
173 k.data = key->data;
174 k.size = key->size;
175 bmwt->cursor->set_key(bmwt->cursor, &k);
176 int rc = bmwt->cursor->remove(bmwt->cursor);
177 if (rc == WT_NOTFOUND) {
178 rc = 0;
179 }
180 RCGO(rc, finish);
181 if (sync) {
182 rc = bmwt->session->log_flush(bmwt->session, "background=off");
183 }
184 finish:
185 if (rc) {
186 fprintf(stderr, "db_del %s\n", wiredtiger_strerror(rc));
187 }
188 return rc == 0;
189 }
190
db_read_seq(BMCTX * ctx,bool reverse)191 static bool db_read_seq(BMCTX *ctx, bool reverse) {
192 BMWT *bmwt = ctx->db;
193 WT_ITEM v;
194 int rc = bmwt->cursor->reset(bmwt->cursor);
195 RCGO(rc, finish);
196 for (int i = 0; i < bm.param_num && !rc; ++i) {
197 if (reverse) {
198 rc = bmwt->cursor->prev(bmwt->cursor);
199 } else {
200 rc = bmwt->cursor->next(bmwt->cursor);
201 }
202 if (rc == WT_NOTFOUND) {
203 rc = 0;
204 break;
205 }
206 if (!rc) {
207 rc = bmwt->cursor->get_value(bmwt->cursor, &v);
208 }
209 }
210 finish:
211 if (rc) {
212 fprintf(stderr, "db_read_seq %s\n", wiredtiger_strerror(rc));
213 }
214 return rc == 0;
215 }
216
db_cursor_to_key(BMCTX * ctx,const IWKV_val * key,IWKV_val * val,bool * found)217 static bool db_cursor_to_key(BMCTX *ctx, const IWKV_val *key, IWKV_val *val, bool *found) {
218 return db_get(ctx, key, val, found);
219 }
220
main(int argc,char ** argv)221 int main(int argc, char **argv) {
222 if (argc < 1) return -1;
223 g_program = argv[0];
224 bm.env_setup = env_setup;
225 bm.db_size_bytes = db_size_bytes;
226 bm.db_open = db_open;
227 bm.db_close = db_close;
228 bm.db_put = db_put;
229 bm.db_get = db_get;
230 bm.db_del = db_del;
231 bm.db_read_seq = db_read_seq;
232 bm.db_cursor_to_key = db_cursor_to_key;
233 if (!bm_bench_run(argc, argv)) {
234 return 1;
235 }
236 return 0;
237 }
238