• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "bmbase.c"
2 #include "iowow.h"
3 
4 #define DEFAULT_DB "iwkv_bench.db"
5 
6 typedef struct BM_IWKVDB {
7   IWKV iwkv;
8   IWDB db;
9 } BM_IWKVDB;
10 
env_setup()11 static void env_setup() {
12   iwrc rc = iw_init();
13   if (rc) {
14     iwlog_ecode_error2(rc, "Failed to init iwkv: iwkv_init()");
15     exit(1);
16   }
17   fprintf(stderr, " engine: IWKV %s\n", iowow_version_full());
18 }
19 
db_size_bytes(BMCTX * ctx)20 static uint64_t db_size_bytes(BMCTX *ctx) {
21   const char *path = bm.param_db ? bm.param_db : DEFAULT_DB;
22   IWP_FILE_STAT fst;
23   iwrc rc = iwp_fstat(path, &fst);
24   if (rc) {
25     iwlog_ecode_error3(rc);
26     return 0;
27   }
28   return fst.size;
29 }
30 
db_open(BMCTX * ctx)31 static void *db_open(BMCTX *ctx) {
32   if (ctx->db) {
33     return 0; // db is not closed properly
34   }
35   bool wal_enabled = false;
36   for (int i = 0; i <  bm.argc; ++i) {
37     if (!strcmp(bm.argv[i], "-w")) {
38       wal_enabled = true;
39     }
40   }
41   IWKV_OPTS opts = {
42     .wal = {
43       .enabled = wal_enabled,
44       .check_crc_on_checkpoint = false,
45       .savepoint_timeout_sec = 10, // 10 sec
46       .checkpoint_timeout_sec = 300, // 5 min
47       .wal_buffer_sz = 8 * 1024 * 1024, // 8M
48       .checkpoint_buffer_sz = 500ULL * 1024 * 1024 // 500MB
49     }
50   };
51   opts.path = bm.param_db ? bm.param_db : DEFAULT_DB;
52 
53   if (ctx->freshdb) {
54     opts.oflags = IWKV_TRUNC;
55   }
56   BM_IWKVDB *bmdb = malloc(sizeof(*bmdb));
57   iwrc rc = iwkv_open(&opts, &bmdb->iwkv);
58   if (rc) {
59     iwlog_ecode_error2(rc, "Failed to open iwkv file");
60     return 0;
61   }
62   rc = iwkv_db(bmdb->iwkv, 1, 0, &bmdb->db);
63   if (rc) {
64     iwlog_ecode_error2(rc, "Failed to open iwkv db: 1");
65     return 0;
66   }
67   return bmdb;
68 }
69 
db_close(BMCTX * ctx)70 static bool db_close(BMCTX *ctx) {
71   if (!ctx->db) {
72     return false;
73   }
74   BM_IWKVDB *bmdb = ctx->db;
75   iwrc rc = iwkv_close(&bmdb->iwkv);
76   if (rc) {
77     iwlog_ecode_error2(rc, "db_close");
78     return false;
79   }
80   free(bmdb);
81   return true;
82 }
83 
db_put(BMCTX * ctx,const IWKV_val * key,const IWKV_val * val,bool sync)84 static bool db_put(BMCTX *ctx, const IWKV_val *key, const IWKV_val *val, bool sync) {
85   BM_IWKVDB *bmdb = ctx->db;
86   iwrc rc = iwkv_put(bmdb->db, key, val, sync ? IWKV_SYNC : 0);
87   if (rc) {
88     iwlog_ecode_error2(rc, "db_put");
89     return false;
90   }
91   return true;
92 }
93 
db_get(BMCTX * ctx,const IWKV_val * key,IWKV_val * val,bool * found)94 static bool db_get(BMCTX *ctx, const IWKV_val *key, IWKV_val *val, bool *found) {
95   BM_IWKVDB *bmdb = ctx->db;
96   *found = true;
97   iwrc rc = iwkv_get(bmdb->db, key, val);
98   if (rc == IWKV_ERROR_NOTFOUND) {
99     *found = false;
100     rc = 0;
101   }
102   if (rc) {
103     iwlog_ecode_error2(rc, "db_get");
104     return false;
105   }
106   return true;
107 }
108 
db_del(BMCTX * ctx,const IWKV_val * key,bool sync)109 static bool db_del(BMCTX *ctx, const IWKV_val *key, bool sync) {
110   BM_IWKVDB *bmdb = ctx->db;
111   iwrc rc = iwkv_del(bmdb->db, key, sync ? IWKV_SYNC : 0);
112   if (rc == IWKV_ERROR_NOTFOUND) {
113     rc = 0;
114   }
115   if (rc) {
116     iwlog_ecode_error2(rc, "db_del");
117     return false;
118   }
119   return true;
120 }
121 
db_read_seq(BMCTX * ctx,bool reverse)122 static bool db_read_seq(BMCTX *ctx, bool reverse) {
123   BM_IWKVDB *bmdb = ctx->db;
124   bool ret = true;
125   IWKV_cursor cur;
126   iwrc rc = iwkv_cursor_open(bmdb->db, &cur,
127                              (reverse ? IWKV_CURSOR_AFTER_LAST : IWKV_CURSOR_BEFORE_FIRST), 0);
128   if (rc) {
129     iwlog_ecode_error2(rc, "db_read_seq::iwkv_cursor_open failed");
130     return false;
131   }
132   for (int i = 0; i < bm.param_num && !rc; ++i) {
133     rc = iwkv_cursor_to(cur, reverse ? IWKV_CURSOR_PREV : IWKV_CURSOR_NEXT);
134   }
135   iwkv_cursor_close(&cur);
136   if (rc == IWKV_ERROR_NOTFOUND) {
137     rc = 0;
138   }
139   if (rc) {
140     ret = false;
141     iwlog_ecode_error2(rc, "db_read_seq");
142   }
143   return ret;
144 }
145 
db_cursor_to_key(BMCTX * ctx,const IWKV_val * key,IWKV_val * val,bool * found)146 static bool db_cursor_to_key(BMCTX *ctx, const IWKV_val *key, IWKV_val *val, bool *found) {
147   BM_IWKVDB *bmdb = ctx->db;
148   bool ret = true;
149   IWKV_cursor cur;
150   *found = true;
151   iwrc rc = iwkv_cursor_open(bmdb->db, &cur, IWKV_CURSOR_EQ, key);
152   if (!rc) {
153     rc = iwkv_cursor_val(cur, val);
154     if (rc) {
155       ret = false;
156       iwlog_ecode_error2(rc, "db_cursor_to_key::iwkv_cursor_val failed");
157     }
158     iwkv_cursor_close(&cur);
159   } else if (rc == IWKV_ERROR_NOTFOUND) {
160     *found = false;
161     iwkv_cursor_close(&cur);
162   } else {
163     iwlog_ecode_error2(rc, "db_cursor_to_key::iwkv_cursor_open failed");
164     ret = false;
165   }
166   return ret;
167 }
168 
main(int argc,char * argv[])169 int main(int argc, char *argv[]) {
170   if (argc < 1) return -1;
171   g_program = argv[0];
172   bm.env_setup = env_setup;
173   bm.db_size_bytes = db_size_bytes;
174   bm.db_open = db_open;
175   bm.db_close = db_close;
176   bm.db_put = db_put;
177   bm.db_get = db_get;
178   bm.db_del = db_del;
179   bm.db_read_seq = db_read_seq;
180   bm.db_cursor_to_key = db_cursor_to_key;
181   if (!bm_bench_run(argc, argv)) {
182     return 1;
183   }
184   return 0;
185 }
186