xref: /netbsd-src/external/bsd/openldap/dist/libraries/liblmdb/mtest.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
1 /*	$NetBSD: mtest.c,v 1.3 2021/08/14 16:14:57 christos Exp $	*/
2 
3 /* mtest.c - memory-mapped database tester/toy */
4 /*
5  * Copyright 2011-2021 Howard Chu, Symas Corp.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
12  * A copy of this license is available in the file LICENSE in the
13  * top-level directory of the distribution or, alternatively, at
14  * <http://www.OpenLDAP.org/license.html>.
15  */
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <time.h>
19 #include "lmdb.h"
20 
21 #define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr)
22 #define RES(err, expr) ((rc = expr) == (err) || (CHECK(!rc, #expr), 0))
23 #define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \
24 	"%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort()))
25 
main(int argc,char * argv[])26 int main(int argc,char * argv[])
27 {
28 	int i = 0, j = 0, rc;
29 	MDB_env *env;
30 	MDB_dbi dbi;
31 	MDB_val key, data;
32 	MDB_txn *txn;
33 	MDB_stat mst;
34 	MDB_cursor *cursor, *cur2;
35 	MDB_cursor_op op;
36 	int count;
37 	int *values;
38 	char sval[32] = "";
39 
40 	srand(time(NULL));
41 
42 	    count = (rand()%384) + 64;
43 	    values = (int *)malloc(count*sizeof(int));
44 
45 	    for(i = 0;i<count;i++) {
46 			values[i] = rand()%1024;
47 	    }
48 
49 		E(mdb_env_create(&env));
50 		E(mdb_env_set_maxreaders(env, 1));
51 		E(mdb_env_set_mapsize(env, 10485760));
52 		E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP /*|MDB_NOSYNC*/, 0664));
53 
54 		E(mdb_txn_begin(env, NULL, 0, &txn));
55 		E(mdb_dbi_open(txn, NULL, 0, &dbi));
56 
57 		key.mv_size = sizeof(int);
58 		key.mv_data = sval;
59 
60 		printf("Adding %d values\n", count);
61 	    for (i=0;i<count;i++) {
62 			sprintf(sval, "%03x %d foo bar", values[i], values[i]);
63 			/* Set <data> in each iteration, since MDB_NOOVERWRITE may modify it */
64 			data.mv_size = sizeof(sval);
65 			data.mv_data = sval;
66 			if (RES(MDB_KEYEXIST, mdb_put(txn, dbi, &key, &data, MDB_NOOVERWRITE))) {
67 				j++;
68 				data.mv_size = sizeof(sval);
69 				data.mv_data = sval;
70 			}
71 	    }
72 		if (j) printf("%d duplicates skipped\n", j);
73 		E(mdb_txn_commit(txn));
74 		E(mdb_env_stat(env, &mst));
75 
76 		E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
77 		E(mdb_cursor_open(txn, dbi, &cursor));
78 		while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
79 			printf("key: %p %.*s, data: %p %.*s\n",
80 				key.mv_data,  (int) key.mv_size,  (char *) key.mv_data,
81 				data.mv_data, (int) data.mv_size, (char *) data.mv_data);
82 		}
83 		CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
84 		mdb_cursor_close(cursor);
85 		mdb_txn_abort(txn);
86 
87 		j=0;
88 		key.mv_data = sval;
89 	    for (i= count - 1; i > -1; i-= (rand()%5)) {
90 			j++;
91 			txn=NULL;
92 			E(mdb_txn_begin(env, NULL, 0, &txn));
93 			sprintf(sval, "%03x ", values[i]);
94 			if (RES(MDB_NOTFOUND, mdb_del(txn, dbi, &key, NULL))) {
95 				j--;
96 				mdb_txn_abort(txn);
97 			} else {
98 				E(mdb_txn_commit(txn));
99 			}
100 	    }
101 	    free(values);
102 		printf("Deleted %d values\n", j);
103 
104 		E(mdb_env_stat(env, &mst));
105 		E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
106 		E(mdb_cursor_open(txn, dbi, &cursor));
107 		printf("Cursor next\n");
108 		while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
109 			printf("key: %.*s, data: %.*s\n",
110 				(int) key.mv_size,  (char *) key.mv_data,
111 				(int) data.mv_size, (char *) data.mv_data);
112 		}
113 		CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
114 		printf("Cursor last\n");
115 		E(mdb_cursor_get(cursor, &key, &data, MDB_LAST));
116 		printf("key: %.*s, data: %.*s\n",
117 			(int) key.mv_size,  (char *) key.mv_data,
118 			(int) data.mv_size, (char *) data.mv_data);
119 		printf("Cursor prev\n");
120 		while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_PREV)) == 0) {
121 			printf("key: %.*s, data: %.*s\n",
122 				(int) key.mv_size,  (char *) key.mv_data,
123 				(int) data.mv_size, (char *) data.mv_data);
124 		}
125 		CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
126 		printf("Cursor last/prev\n");
127 		E(mdb_cursor_get(cursor, &key, &data, MDB_LAST));
128 			printf("key: %.*s, data: %.*s\n",
129 				(int) key.mv_size,  (char *) key.mv_data,
130 				(int) data.mv_size, (char *) data.mv_data);
131 		E(mdb_cursor_get(cursor, &key, &data, MDB_PREV));
132 			printf("key: %.*s, data: %.*s\n",
133 				(int) key.mv_size,  (char *) key.mv_data,
134 				(int) data.mv_size, (char *) data.mv_data);
135 
136 		mdb_cursor_close(cursor);
137 		mdb_txn_abort(txn);
138 
139 		printf("Deleting with cursor\n");
140 		E(mdb_txn_begin(env, NULL, 0, &txn));
141 		E(mdb_cursor_open(txn, dbi, &cur2));
142 		for (i=0; i<50; i++) {
143 			if (RES(MDB_NOTFOUND, mdb_cursor_get(cur2, &key, &data, MDB_NEXT)))
144 				break;
145 			printf("key: %p %.*s, data: %p %.*s\n",
146 				key.mv_data,  (int) key.mv_size,  (char *) key.mv_data,
147 				data.mv_data, (int) data.mv_size, (char *) data.mv_data);
148 			E(mdb_del(txn, dbi, &key, NULL));
149 		}
150 
151 		printf("Restarting cursor in txn\n");
152 		for (op=MDB_FIRST, i=0; i<=32; op=MDB_NEXT, i++) {
153 			if (RES(MDB_NOTFOUND, mdb_cursor_get(cur2, &key, &data, op)))
154 				break;
155 			printf("key: %p %.*s, data: %p %.*s\n",
156 				key.mv_data,  (int) key.mv_size,  (char *) key.mv_data,
157 				data.mv_data, (int) data.mv_size, (char *) data.mv_data);
158 		}
159 		mdb_cursor_close(cur2);
160 		E(mdb_txn_commit(txn));
161 
162 		printf("Restarting cursor outside txn\n");
163 		E(mdb_txn_begin(env, NULL, 0, &txn));
164 		E(mdb_cursor_open(txn, dbi, &cursor));
165 		for (op=MDB_FIRST, i=0; i<=32; op=MDB_NEXT, i++) {
166 			if (RES(MDB_NOTFOUND, mdb_cursor_get(cursor, &key, &data, op)))
167 				break;
168 			printf("key: %p %.*s, data: %p %.*s\n",
169 				key.mv_data,  (int) key.mv_size,  (char *) key.mv_data,
170 				data.mv_data, (int) data.mv_size, (char *) data.mv_data);
171 		}
172 		mdb_cursor_close(cursor);
173 		mdb_txn_abort(txn);
174 
175 		mdb_dbi_close(env, dbi);
176 		mdb_env_close(env);
177 
178 	return 0;
179 }
180