mtest5.c 3.73 KB
Newer Older
Howard Chu's avatar
Howard Chu committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* mtest5.c - memory-mapped database tester/toy */
/*
 * Copyright 2011 Howard Chu, Symas Corp.
 * 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 using cursor_put */
#define _XOPEN_SOURCE 500		/* srandom(), random() */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
Howard Chu's avatar
Howard Chu committed
21
#include "lmdb.h"
Howard Chu's avatar
Howard Chu committed
22

23
24
25
26
27
#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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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[32];
	char kval[sizeof(int)];

	srandom(time(NULL));

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

	count = (random()%384) + 64;
	values = (int *)malloc(count*sizeof(int));

	for(i = 0;i<count;i++) {
		values[i] = random()%1024;
	}

53
54
55
56
57
58
59
	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, "id2", MDB_CREATE|MDB_DUPSORT, &dbi));
	E(mdb_cursor_open(txn, dbi, &cursor));
Howard Chu's avatar
Howard Chu committed
60
61
62
63
64
65
66
67
68
69
70

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

	printf("Adding %d values\n", count);
	for (i=0;i<count;i++) {
		if (!(i & 0x0f))
			sprintf(kval, "%03x", values[i]);
		sprintf(sval, "%03x %d foo bar", values[i], values[i]);
71
72
		if (RES(MDB_KEYEXIST, mdb_cursor_put(cursor, &key, &data, MDB_NODUPDATA)))
			j++;
Howard Chu's avatar
Howard Chu committed
73
74
75
	}
	if (j) printf("%d duplicates skipped\n", j);
	mdb_cursor_close(cursor);
76
77
	E(mdb_txn_commit(txn));
	E(mdb_env_stat(env, &mst));
Howard Chu's avatar
Howard Chu committed
78

79
80
	E(mdb_txn_begin(env, NULL, 1, &txn));
	E(mdb_cursor_open(txn, dbi, &cursor));
Howard Chu's avatar
Howard Chu committed
81
82
83
84
85
	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);
	}
86
	CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
Howard Chu's avatar
Howard Chu committed
87
88
89
90
91
92
93
94
	mdb_cursor_close(cursor);
	mdb_txn_abort(txn);

	j=0;

	for (i= count - 1; i > -1; i-= (random()%5)) {
		j++;
		txn=NULL;
95
		E(mdb_txn_begin(env, NULL, 0, &txn));
Howard Chu's avatar
Howard Chu committed
96
97
98
99
100
101
		sprintf(kval, "%03x", values[i & ~0x0f]);
		sprintf(sval, "%03x %d foo bar", values[i], values[i]);
		key.mv_size = sizeof(int);
		key.mv_data = kval;
		data.mv_size = sizeof(sval);
		data.mv_data = sval;
102
		if (RES(MDB_NOTFOUND, mdb_del(txn, dbi, &key, &data))) {
Howard Chu's avatar
Howard Chu committed
103
104
105
			j--;
			mdb_txn_abort(txn);
		} else {
106
			E(mdb_txn_commit(txn));
Howard Chu's avatar
Howard Chu committed
107
108
109
110
111
		}
	}
	free(values);
	printf("Deleted %d values\n", j);

112
113
114
	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
115
116
117
118
119
120
	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);
	}
121
	CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
Howard Chu's avatar
Howard Chu committed
122
123
124
125
126
127
	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);
	}
128
	CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
Howard Chu's avatar
Howard Chu committed
129
	mdb_cursor_close(cursor);
Howard Chu's avatar
Howard Chu committed
130
	mdb_close(env, dbi);
Howard Chu's avatar
Howard Chu committed
131
132
133
134
135
136

	mdb_txn_abort(txn);
	mdb_env_close(env);

	return 0;
}