mtest4.c 4.65 KB
Newer Older
Howard Chu's avatar
Howard Chu committed
1
2
/* mtest4.c - memory-mapped database tester/toy */
/*
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
3
 * Copyright 2011-2015 Howard Chu, Symas Corp.
Howard Chu's avatar
Howard Chu committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted only as authorized by the OpenLDAP
 * Public License.
 *
 * A copy of this license is available in the file LICENSE in the
 * top-level directory of the distribution or, alternatively, at
 * <http://www.OpenLDAP.org/license.html>.
 */

/* Tests for sorted duplicate DBs with fixed-size keys */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
Howard Chu's avatar
Howard Chu committed
20
#include "lmdb.h"
Howard Chu's avatar
Howard Chu committed
21

22
23
24
25
26
#define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr)
#define RES(err, expr) ((rc = expr) == (err) || (CHECK(!rc, #expr), 0))
#define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \
	"%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort()))

Howard Chu's avatar
Howard Chu committed
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
int main(int argc,char * argv[])
{
	int i = 0, j = 0, rc;
	MDB_env *env;
	MDB_dbi dbi;
	MDB_val key, data;
	MDB_txn *txn;
	MDB_stat mst;
	MDB_cursor *cursor;
	int count;
	int *values;
	char sval[8];
	char kval[sizeof(int)];

	memset(sval, 0, sizeof(sval));

	count = 510;
	values = (int *)malloc(count*sizeof(int));

	for(i = 0;i<count;i++) {
		values[i] = i*5;
	}

50
51
52
53
54
55
	E(mdb_env_create(&env));
	E(mdb_env_set_mapsize(env, 10485760));
	E(mdb_env_set_maxdbs(env, 4));
	E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664));
	E(mdb_txn_begin(env, NULL, 0, &txn));
	E(mdb_open(txn, "id4", MDB_CREATE|MDB_DUPSORT|MDB_DUPFIXED, &dbi));
Howard Chu's avatar
Howard Chu committed
56
57
58
59
60
61
62
63
64
65

	key.mv_size = sizeof(int);
	key.mv_data = kval;
	data.mv_size = sizeof(sval);
	data.mv_data = sval;

	printf("Adding %d values\n", count);
	strcpy(kval, "001");
	for (i=0;i<count;i++) {
		sprintf(sval, "%07x", values[i]);
66
67
		if (RES(MDB_KEYEXIST, mdb_put(txn, dbi, &key, &data, MDB_NODUPDATA)))
			j++;
Howard Chu's avatar
Howard Chu committed
68
69
	}
	if (j) printf("%d duplicates skipped\n", j);
70
71
	E(mdb_txn_commit(txn));
	E(mdb_env_stat(env, &mst));
Howard Chu's avatar
Howard Chu committed
72
73
74

	/* there should be one full page of dups now.
	 */
75
76
	E(mdb_txn_begin(env, NULL, 1, &txn));
	E(mdb_cursor_open(txn, dbi, &cursor));
Howard Chu's avatar
Howard Chu committed
77
78
79
80
81
	while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
		printf("key: %p %.*s, data: %p %.*s\n",
			key.mv_data,  (int) key.mv_size,  (char *) key.mv_data,
			data.mv_data, (int) data.mv_size, (char *) data.mv_data);
	}
82
	CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
Howard Chu's avatar
Howard Chu committed
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
	mdb_cursor_close(cursor);
	mdb_txn_abort(txn);

	/* test all 3 branches of split code:
	 * 1: new key in lower half
	 * 2: new key at split point
	 * 3: new key in upper half
	 */

	key.mv_size = sizeof(int);
	key.mv_data = kval;
	data.mv_size = sizeof(sval);
	data.mv_data = sval;

	sprintf(sval, "%07x", values[3]+1);
98
99
	E(mdb_txn_begin(env, NULL, 0, &txn));
	(void)RES(MDB_KEYEXIST, mdb_put(txn, dbi, &key, &data, MDB_NODUPDATA));
Howard Chu's avatar
Howard Chu committed
100
101
102
	mdb_txn_abort(txn);

	sprintf(sval, "%07x", values[255]+1);
103
104
	E(mdb_txn_begin(env, NULL, 0, &txn));
	(void)RES(MDB_KEYEXIST, mdb_put(txn, dbi, &key, &data, MDB_NODUPDATA));
Howard Chu's avatar
Howard Chu committed
105
106
107
	mdb_txn_abort(txn);

	sprintf(sval, "%07x", values[500]+1);
108
109
110
	E(mdb_txn_begin(env, NULL, 0, &txn));
	(void)RES(MDB_KEYEXIST, mdb_put(txn, dbi, &key, &data, MDB_NODUPDATA));
	E(mdb_txn_commit(txn));
Howard Chu's avatar
Howard Chu committed
111
112

	/* Try MDB_NEXT_MULTIPLE */
113
114
	E(mdb_txn_begin(env, NULL, 0, &txn));
	E(mdb_cursor_open(txn, dbi, &cursor));
Howard Chu's avatar
Howard Chu committed
115
116
117
118
119
	while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT_MULTIPLE)) == 0) {
		printf("key: %.*s, data: %.*s\n",
			(int) key.mv_size,  (char *) key.mv_data,
			(int) data.mv_size, (char *) data.mv_data);
	}
120
	CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
Howard Chu's avatar
Howard Chu committed
121
122
123
124
	mdb_cursor_close(cursor);
	mdb_txn_abort(txn);
	j=0;

125
	for (i= count - 1; i > -1; i-= (rand()%3)) {
Howard Chu's avatar
Howard Chu committed
126
127
		j++;
		txn=NULL;
128
		E(mdb_txn_begin(env, NULL, 0, &txn));
Howard Chu's avatar
Howard Chu committed
129
130
131
132
133
		sprintf(sval, "%07x", values[i]);
		key.mv_size = sizeof(int);
		key.mv_data = kval;
		data.mv_size = sizeof(sval);
		data.mv_data = sval;
134
		if (RES(MDB_NOTFOUND, mdb_del(txn, dbi, &key, &data))) {
Howard Chu's avatar
Howard Chu committed
135
136
137
			j--;
			mdb_txn_abort(txn);
		} else {
138
			E(mdb_txn_commit(txn));
Howard Chu's avatar
Howard Chu committed
139
140
141
142
143
		}
	}
	free(values);
	printf("Deleted %d values\n", j);

144
145
146
	E(mdb_env_stat(env, &mst));
	E(mdb_txn_begin(env, NULL, 1, &txn));
	E(mdb_cursor_open(txn, dbi, &cursor));
Howard Chu's avatar
Howard Chu committed
147
148
149
150
151
152
	printf("Cursor next\n");
	while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
		printf("key: %.*s, data: %.*s\n",
			(int) key.mv_size,  (char *) key.mv_data,
			(int) data.mv_size, (char *) data.mv_data);
	}
153
	CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
Howard Chu's avatar
Howard Chu committed
154
155
156
157
158
159
	printf("Cursor prev\n");
	while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_PREV)) == 0) {
		printf("key: %.*s, data: %.*s\n",
			(int) key.mv_size,  (char *) key.mv_data,
			(int) data.mv_size, (char *) data.mv_data);
	}
160
	CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
Howard Chu's avatar
Howard Chu committed
161
	mdb_cursor_close(cursor);
Howard Chu's avatar
Howard Chu committed
162
	mdb_close(env, dbi);
Howard Chu's avatar
Howard Chu committed
163
164
165
166
167
168

	mdb_txn_abort(txn);
	mdb_env_close(env);

	return 0;
}