1 #include "bmbase.c"
2 #include <tcbdb.h>
3
4 #define DEFAULT_DB "tc_bench.tc"
5
6 struct BMTC {
7 TCBDB *db;
8 } btc;
9 typedef struct BMTC BMTC;
10
env_setup()11 static void env_setup() {
12 fprintf(stderr, " engine: TokyoCabinet %s\n", _TC_VERSION);
13 }
14
db_size_bytes(BMCTX * ctx)15 uint64_t db_size_bytes(BMCTX *ctx) {
16 const char *path = bm.param_db ? bm.param_db : DEFAULT_DB;
17 IWP_FILE_STAT fst;
18 iwrc rc = iwp_fstat(path, &fst);
19 if (rc) {
20 iwlog_ecode_error3(rc);
21 return 0;
22 }
23 return fst.size;
24 }
25
db_open(BMCTX * ctx)26 static void *db_open(BMCTX *ctx) {
27 if (ctx->db || btc.db) {
28 return 0; // db is not closed properly
29 }
30 const char *path = bm.param_db ? bm.param_db : DEFAULT_DB;
31 int omode = BDBOWRITER | BDBOCREAT;
32 if (ctx->freshdb) {
33 omode |= BDBOTRUNC;
34 }
35 btc.db = tcbdbnew();
36 if (!btc.db) {
37 return 0;
38 }
39 tcbdbsetxmsiz(btc.db, 1024ULL * 1024 * 1024 * 10);
40 tcbdbtune(btc.db, 0, 0, 32749 * 4, 8, 10, BDBTLARGE);
41 if (!tcbdbopen(btc.db, path, omode)) {
42 tcbdbdel(btc.db);
43 btc.db = 0;
44 return 0;
45 }
46 return &btc;
47 }
48
db_close(BMCTX * ctx)49 static bool db_close(BMCTX *ctx) {
50 if (!ctx->db) {
51 return false;
52 }
53 BMTC *btc = ctx->db;
54 bool ret = tcbdbclose(btc->db);
55 tcbdbdel(btc->db);
56 btc->db = 0;
57 return ret;
58 }
59
db_put(BMCTX * ctx,const IWKV_val * key,const IWKV_val * val,bool sync)60 static bool db_put(BMCTX *ctx, const IWKV_val *key, const IWKV_val *val, bool sync) {
61 BMTC *btc = ctx->db;
62 if (!tcbdbput(btc->db, key->data, key->size, val->data, val->size)) {
63 fprintf(stderr, "db_put: %s\n", tcbdberrmsg(tcbdbecode(btc->db)));
64 return false;
65 }
66 if (sync) {
67 return tcbdbsync(btc->db);
68 }
69 return true;
70 }
71
db_get(BMCTX * ctx,const IWKV_val * key,IWKV_val * val,bool * found)72 static bool db_get(BMCTX *ctx, const IWKV_val *key, IWKV_val *val, bool *found) {
73 BMTC *btc = ctx->db;
74 int sp = 0;
75 char *vbuf = tcbdbget(btc->db, key->data, key->size, &sp);
76 val->data = vbuf;
77 val->size = sp;
78 *found = (val->data != 0);
79 return true;
80 }
81
db_del(BMCTX * ctx,const IWKV_val * key,bool sync)82 static bool db_del(BMCTX *ctx, const IWKV_val *key, bool sync) {
83 BMTC *btc = ctx->db;
84 tcbdbout(btc->db, key->data, key->size);
85 if (sync) {
86 if (!tcbdbsync(btc->db)) {
87 fprintf(stderr, "db_del: %s\n", tcbdberrmsg(tcbdbecode(btc->db)));
88 return false;
89 }
90 }
91 return true;
92 }
93
db_read_seq(BMCTX * ctx,bool reverse)94 static bool db_read_seq(BMCTX *ctx, bool reverse) {
95 BMTC *btc = ctx->db;
96 BDBCUR *cur = tcbdbcurnew(btc->db);
97 if (!cur) {
98 return false;
99 }
100 if (reverse) {
101 tcbdbcurlast(cur);
102 } else {
103 tcbdbcurfirst(cur);
104 }
105 for (int i = 0; i < bm.param_num; ++i) {
106 if (reverse) {
107 tcbdbcurprev(cur);
108 } else {
109 tcbdbcurnext(cur);
110 }
111 }
112 tcbdbcurdel(cur);
113 return true;
114 }
115
db_cursor_to_key(BMCTX * ctx,const IWKV_val * key,IWKV_val * val,bool * found)116 static bool db_cursor_to_key(BMCTX *ctx, const IWKV_val *key, IWKV_val *val, bool *found) {
117 BMTC *btc = ctx->db;
118 BDBCUR *cur = tcbdbcurnew(btc->db);
119 if (!cur) {
120 return false;
121 }
122 if (!tcbdbcurjump(cur, key->data, key->size)) {
123 *found = false;
124 } else {
125 *found = true;
126 int sp;
127 val->data = tcbdbcurval(cur, &sp);
128 val->size = sp;
129 }
130 tcbdbcurdel(cur);
131 return true;
132 }
133
main(int argc,char ** argv)134 int main(int argc, char **argv) {
135 if (argc < 1) {
136 return -1;
137 }
138 g_program = argv[0];
139 bm.env_setup = env_setup;
140 bm.db_size_bytes = db_size_bytes;
141 bm.val_free = free;
142 bm.db_open = db_open;
143 bm.db_close = db_close;
144 bm.db_put = db_put;
145 bm.db_get = db_get;
146 bm.db_del = db_del;
147 bm.db_read_seq = db_read_seq;
148 bm.db_cursor_to_key = db_cursor_to_key;
149 if (!bm_bench_run(argc, argv)) {
150 return 1;
151 }
152 return 0;
153 }
154