MDBX Containers
Loading...
Searching...
No Matches
mdbx_test.cpp
Go to the documentation of this file.
1#include <iostream>
2#include "mdbx.h"
3#include <vector>
4
5uint64_t generate_tick_key(uint32_t asset_id, uint16_t provider_id, uint16_t unix_hour) {
6 return ((uint64_t)asset_id << 32) | ((uint64_t)provider_id << 16) | (uint64_t)unix_hour;
7}
8
9int main() {
10 int rc;
11 MDBX_env *env = nullptr;
12 MDBX_dbi dbi;
13 MDBX_dbi dbi_ticks, dbi_metadata;
14 MDBX_val key, data;
15 MDBX_txn *txn = nullptr;
16 MDBX_cursor *cursor = nullptr;
17 char skey[32];
18 char sval[32];
19
20 std::vector<uint8_t> tick_data(16, 'D'); // Бинарные данные тиков
21 uint64_t tick_key = 0;
22
23
24 printf("MDBX limits:\n");
25#if UINTPTR_MAX > 0xffffFFFFul || ULONG_MAX > 0xffffFFFFul
26 const double scale_factor = 1099511627776.0;
27 const char *const scale_unit = "TiB";
28#else
29 const double scale_factor = 1073741824.0;
30 const char *const scale_unit = "GiB";
31#endif
32 const size_t pagesize_min = mdbx_limits_pgsize_min();
33 const size_t pagesize_max = mdbx_limits_pgsize_max();
34 const size_t pagesize_default = mdbx_default_pagesize();
35
36 printf("\tPage size: a power of 2, minimum %zu, maximum %zu bytes,"
37 " default %zu bytes.\n",
38 pagesize_min, pagesize_max, pagesize_default);
39 printf("\tKey size: minimum %zu, maximum ≈¼ pagesize (%zu bytes for default"
40 " %zuK pagesize, %zu bytes for %zuK pagesize).\n",
41 (size_t)0, mdbx_limits_keysize_max(-1, MDBX_DB_DEFAULTS), pagesize_default / 1024,
42 mdbx_limits_keysize_max(pagesize_max, MDBX_DB_DEFAULTS), pagesize_max / 1024);
43 printf("\tValue size: minimum %zu, maximum %zu (0x%08zX) bytes for maps,"
44 " ≈¼ pagesize for multimaps (%zu bytes for default %zuK pagesize,"
45 " %zu bytes for %zuK pagesize).\n",
46 (size_t)0, mdbx_limits_valsize_max(pagesize_min, MDBX_DB_DEFAULTS),
47 mdbx_limits_valsize_max(pagesize_min, MDBX_DB_DEFAULTS), mdbx_limits_valsize_max(-1, MDBX_DUPSORT),
48 pagesize_default / 1024, mdbx_limits_valsize_max(pagesize_max, MDBX_DUPSORT), pagesize_max / 1024);
49 printf("\tWrite transaction size: up to %zu (0x%zX) pages (%f %s for default "
50 "%zuK pagesize, %f %s for %zuK pagesize).\n",
51 mdbx_limits_txnsize_max(pagesize_min) / pagesize_min, mdbx_limits_txnsize_max(pagesize_min) / pagesize_min,
52 mdbx_limits_txnsize_max(-1) / scale_factor, scale_unit, pagesize_default / 1024,
53 mdbx_limits_txnsize_max(pagesize_max) / scale_factor, scale_unit, pagesize_max / 1024);
54 printf("\tDatabase size: up to %zu pages (%f %s for default %zuK "
55 "pagesize, %f %s for %zuK pagesize).\n",
56 mdbx_limits_dbsize_max(pagesize_min) / pagesize_min, mdbx_limits_dbsize_max(-1) / scale_factor, scale_unit,
57 pagesize_default / 1024, mdbx_limits_dbsize_max(pagesize_max) / scale_factor, scale_unit, pagesize_max / 1024);
58 printf("\tMaximum sub-databases: %u.\n", MDBX_MAX_DBI);
59 printf("-----\n");
60
61 // Создаем окружение
62 rc = mdbx_env_create(&env);
63 if (rc != MDBX_SUCCESS) {
64 fprintf(stderr, "mdbx_env_create: (%d) %s\n", rc, mdbx_strerror(rc));
65 goto bailout;
66 }
67
68 // Настраиваем геометрию базы данных
69 rc = mdbx_env_set_geometry(env,
70 -1, // size_lower
71 -1, // Размер в байтах для настройки размера базы данных на данный момент. Нулевое значение означает "минимально приемлемый", а отрицательное означает "сохранить текущий или использовать значение по умолчанию". Поэтому рекомендуется всегда передавать -1 в этом аргументе, за исключением некоторых особых случаев.
72 -1, // size_upper
73 16 * 1024 * 1024, // growth_step
74 16 * 1024 * 1024, // shrink_threshold
75 0); // pagesize (64 * 1024)
76 if (rc != MDBX_SUCCESS) {
77 fprintf(stderr, "mdbx_env_set_geometry: (%d) %s\n", rc, mdbx_strerror(rc));
78 goto bailout;
79 }
80
81 // Устанавливаем лимит на 10 карт
82 rc = mdbx_env_set_maxdbs(env, 10);
83 if (rc != MDBX_SUCCESS) {
84 fprintf(stderr, "mdbx_env_set_maxdbs: (%d) %s\n", rc, mdbx_strerror(rc));
85 goto bailout;
86 }
87
88 // Открываем окружение
89 rc = mdbx_env_open(env, "./example-db", MDBX_NOSUBDIR, 0664);
90 if (rc != MDBX_SUCCESS) {
91 fprintf(stderr, "mdbx_env_open: (%d) %s\n", rc, mdbx_strerror(rc));
92 goto bailout;
93 }
94
95 // Начинаем транзакцию
96 rc = mdbx_txn_begin(env, nullptr, MDBX_TXN_READWRITE, &txn);
97 if (rc != MDBX_SUCCESS) {
98 fprintf(stderr, "mdbx_txn_begin: (%d) %s\n", rc, mdbx_strerror(rc));
99 goto bailout;
100 }
101
102 // Открываем (или создаем) базу данных
103 rc = mdbx_dbi_open(txn, "temp", MDBX_DB_DEFAULTS | MDBX_CREATE, &dbi);
104 if (rc != MDBX_SUCCESS) {
105 fprintf(stderr, "mdbx_dbi_open: (%d) %s\n", rc, mdbx_strerror(rc));
106 goto bailout;
107 }
108
109 // Вставляем данные
110 sprintf(skey, "key");
111 sprintf(sval, "value");
112 key.iov_len = sizeof("key");
113 key.iov_base = skey;
114 data.iov_len = sizeof(sval);
115 data.iov_base = sval;
116 rc = mdbx_put(txn, dbi, &key, &data, MDBX_UPSERT);
117 if (rc != MDBX_SUCCESS) {
118 fprintf(stderr, "mdbx_put: (%d) %s\n", rc, mdbx_strerror(rc));
119 goto bailout;
120 }
121
122 // Завершаем транзакцию
123 rc = mdbx_txn_commit(txn);
124 if (rc != MDBX_SUCCESS) {
125 fprintf(stderr, "mdbx_txn_commit: (%d) %s\n", rc, mdbx_strerror(rc));
126 goto bailout;
127 }
128 txn = nullptr;
129
130 // Начинаем транзакцию для чтения данных
131 rc = mdbx_txn_begin(env, nullptr, MDBX_TXN_RDONLY, &txn);
132 if (rc != MDBX_SUCCESS) {
133 fprintf(stderr, "mdbx_txn_begin: (%d) %s\n", rc, mdbx_strerror(rc));
134 goto bailout;
135 }
136
137 // Открываем курсор для чтения данных
138 rc = mdbx_cursor_open(txn, dbi, &cursor);
139 if (rc != MDBX_SUCCESS) {
140 fprintf(stderr, "mdbx_cursor_open: (%d) %s\n", rc, mdbx_strerror(rc));
141 goto bailout;
142 }
143
144 // Читаем и выводим данные
145 while ((rc = mdbx_cursor_get(cursor, &key, &data, MDBX_NEXT)) == MDBX_SUCCESS) {
146 printf("key: %.*s, data: %.*s\n",
147 (int)key.iov_len, (char *)key.iov_base,
148 (int)data.iov_len, (char *)data.iov_base);
149 }
150 if (rc != MDBX_NOTFOUND) {
151 fprintf(stderr, "mdbx_cursor_get: (%d) %s\n", rc, mdbx_strerror(rc));
152 goto bailout;
153 }
154 if (cursor) mdbx_cursor_close(cursor);
155
156 // Завершаем транзакцию
157 rc = mdbx_txn_abort(txn);
158 if (rc != MDBX_SUCCESS) {
159 fprintf(stderr, "mdbx_txn_abort: (%d) %s\n", rc, mdbx_strerror(rc));
160 goto bailout;
161 }
162 txn = nullptr;
163
164
165//------------------------------------------------------------------------------
166
167 // Начинаем транзакцию
168 rc = mdbx_txn_begin(env, nullptr, MDBX_TXN_READWRITE, &txn);
169 if (rc != MDBX_SUCCESS) {
170 fprintf(stderr, "mdbx_txn_begin: (%d) %s\n", rc, mdbx_strerror(rc));
171 goto bailout;
172 }
173
174 // Открываем карту для тиков
175 rc = mdbx_dbi_open(txn, "ticks", MDBX_DB_DEFAULTS | MDBX_INTEGERKEY | MDBX_CREATE, &dbi_ticks);
176 if (rc != MDBX_SUCCESS) {
177 fprintf(stderr, "mdbx_dbi_open (ticks): (%d) %s\n", rc, mdbx_strerror(rc));
178 goto bailout;
179 }
180
181 tick_key = generate_tick_key(1, 1, 1);
182 MDBX_val mdbx_key, mdbx_data;
183 mdbx_key.iov_base = &tick_key;
184 mdbx_key.iov_len = sizeof(tick_key);
185
186 mdbx_data.iov_base = tick_data.data();
187 mdbx_data.iov_len = tick_data.size();
188
189 rc = mdbx_put(txn, dbi_ticks, &mdbx_key, &mdbx_data, MDBX_UPSERT);
190 if (rc != MDBX_SUCCESS) {
191 fprintf(stderr, "mdbx_put: (%d) %s\n", rc, mdbx_strerror(rc));
192 goto bailout;
193 }
194
195 tick_key = generate_tick_key(2, 1, 1);
196 mdbx_key.iov_base = &tick_key;
197 mdbx_key.iov_len = sizeof(tick_key);
198 tick_data[0] = 'F';
199
200 rc = mdbx_put(txn, dbi_ticks, &mdbx_key, &mdbx_data, MDBX_UPSERT);
201 if (rc != MDBX_SUCCESS) {
202 fprintf(stderr, "mdbx_put: (%d) %s\n", rc, mdbx_strerror(rc));
203 goto bailout;
204 }
205
206 // Завершаем транзакцию
207 rc = mdbx_txn_commit(txn);
208 if (rc != MDBX_SUCCESS) {
209 fprintf(stderr, "mdbx_txn_commit: (%d) %s\n", rc, mdbx_strerror(rc));
210 goto bailout;
211 }
212 txn = nullptr;
213
214 // Начинаем транзакцию для чтения данных
215 rc = mdbx_txn_begin(env, nullptr, MDBX_TXN_RDONLY, &txn);
216 if (rc != MDBX_SUCCESS) {
217 fprintf(stderr, "mdbx_txn_begin: (%d) %s\n", rc, mdbx_strerror(rc));
218 goto bailout;
219 }
220
221 // Открываем курсор для чтения данных
222 rc = mdbx_cursor_open(txn, dbi_ticks, &cursor);
223 if (rc != MDBX_SUCCESS) {
224 fprintf(stderr, "mdbx_cursor_open: (%d) %s\n", rc, mdbx_strerror(rc));
225 goto bailout;
226 }
227
228 // Читаем и выводим данные
229 while ((rc = mdbx_cursor_get(cursor, &key, &data, MDBX_NEXT)) == MDBX_SUCCESS) {
230 printf("key: %.*s, data: %.*s\n",
231 (int)key.iov_len, (char *)key.iov_base,
232 (int)data.iov_len, (char *)data.iov_base);
233 }
234 if (rc != MDBX_NOTFOUND) {
235 fprintf(stderr, "mdbx_cursor_get: (%d) %s\n", rc, mdbx_strerror(rc));
236 goto bailout;
237 }
238
239 // Завершаем транзакцию
240 rc = mdbx_txn_abort(txn);
241 if (rc != MDBX_SUCCESS) {
242 fprintf(stderr, "mdbx_txn_abort: (%d) %s\n", rc, mdbx_strerror(rc));
243 goto bailout;
244 }
245 txn = nullptr;
246
247
248//------------------------------------------------------------------------------
249
250bailout:
251 // Освобождаем ресурсы
252 if (cursor)
253 mdbx_cursor_close(cursor);
254 if (txn)
255 mdbx_txn_abort(txn);
256 if (env)
257 mdbx_env_close(env);
258
259 return (rc != MDBX_SUCCESS) ? EXIT_FAILURE : EXIT_SUCCESS;
260}
int main()
Definition mdbx_test.cpp:9
uint64_t generate_tick_key(uint32_t asset_id, uint16_t provider_id, uint16_t unix_hour)
Definition mdbx_test.cpp:5