lmdb 0.6 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/lmdb_ext/extconf.rb +7 -3
- data/ext/lmdb_ext/lmdb_ext.c +120 -110
- data/lib/lmdb/version.rb +1 -1
- data/lmdb.gemspec +4 -4
- data/{ext/lmdb_ext → vendor/libraries}/liblmdb/.gitignore +8 -0
- data/{ext/lmdb_ext → vendor/libraries}/liblmdb/COPYRIGHT +1 -1
- data/vendor/libraries/liblmdb/Doxyfile +1631 -0
- data/{ext/lmdb_ext → vendor/libraries}/liblmdb/LICENSE +0 -0
- data/vendor/libraries/liblmdb/Makefile +118 -0
- data/vendor/libraries/liblmdb/intro.doc +192 -0
- data/{ext/lmdb_ext → vendor/libraries}/liblmdb/lmdb.h +161 -61
- data/{ext/lmdb_ext → vendor/libraries}/liblmdb/mdb.c +3244 -1302
- data/vendor/libraries/liblmdb/mdb_copy.1 +61 -0
- data/vendor/libraries/liblmdb/mdb_copy.c +84 -0
- data/vendor/libraries/liblmdb/mdb_drop.1 +40 -0
- data/vendor/libraries/liblmdb/mdb_drop.c +135 -0
- data/vendor/libraries/liblmdb/mdb_dump.1 +81 -0
- data/vendor/libraries/liblmdb/mdb_dump.c +319 -0
- data/vendor/libraries/liblmdb/mdb_load.1 +84 -0
- data/vendor/libraries/liblmdb/mdb_load.c +492 -0
- data/vendor/libraries/liblmdb/mdb_stat.1 +70 -0
- data/vendor/libraries/liblmdb/mdb_stat.c +264 -0
- data/{ext/lmdb_ext → vendor/libraries}/liblmdb/midl.c +66 -5
- data/{ext/lmdb_ext → vendor/libraries}/liblmdb/midl.h +19 -5
- data/vendor/libraries/liblmdb/mtest.c +177 -0
- data/vendor/libraries/liblmdb/mtest2.c +124 -0
- data/vendor/libraries/liblmdb/mtest3.c +133 -0
- data/vendor/libraries/liblmdb/mtest4.c +168 -0
- data/vendor/libraries/liblmdb/mtest5.c +135 -0
- data/vendor/libraries/liblmdb/mtest6.c +141 -0
- data/vendor/libraries/liblmdb/sample-bdb.txt +73 -0
- data/vendor/libraries/liblmdb/sample-mdb.txt +62 -0
- data/vendor/libraries/liblmdb/tooltag +27 -0
- metadata +34 -14
- data/.gitignore +0 -15
- data/.travis.yml +0 -14
- data/ext/lmdb_ext/liblmdb/CHANGES +0 -112
@@ -0,0 +1,84 @@
|
|
1
|
+
.TH MDB_LOAD 1 "2015/09/30" "LMDB 0.9.17"
|
2
|
+
.\" Copyright 2014-2021 Howard Chu, Symas Corp. All Rights Reserved.
|
3
|
+
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
|
4
|
+
.SH NAME
|
5
|
+
mdb_load \- LMDB environment import tool
|
6
|
+
.SH SYNOPSIS
|
7
|
+
.B mdb_load
|
8
|
+
[\c
|
9
|
+
.BR \-V ]
|
10
|
+
[\c
|
11
|
+
.BI \-f \ file\fR]
|
12
|
+
[\c
|
13
|
+
.BR \-n ]
|
14
|
+
[\c
|
15
|
+
.BI \-s \ subdb\fR]
|
16
|
+
[\c
|
17
|
+
.BR \-N ]
|
18
|
+
[\c
|
19
|
+
.BR \-T ]
|
20
|
+
.BR \ envpath
|
21
|
+
.SH DESCRIPTION
|
22
|
+
The
|
23
|
+
.B mdb_load
|
24
|
+
utility reads from the standard input and loads it into the
|
25
|
+
LMDB environment
|
26
|
+
.BR envpath .
|
27
|
+
|
28
|
+
The input to
|
29
|
+
.B mdb_load
|
30
|
+
must be in the output format specified by the
|
31
|
+
.BR mdb_dump (1)
|
32
|
+
utility or as specified by the
|
33
|
+
.B -T
|
34
|
+
option below.
|
35
|
+
.SH OPTIONS
|
36
|
+
.TP
|
37
|
+
.BR \-V
|
38
|
+
Write the library version number to the standard output, and exit.
|
39
|
+
.TP
|
40
|
+
.BR \-a
|
41
|
+
Append all records in the order they appear in the input. The input is assumed to already be
|
42
|
+
in correctly sorted order and no sorting or checking for redundant values will be performed.
|
43
|
+
This option must be used to reload data that was produced by running
|
44
|
+
.B mdb_dump
|
45
|
+
on a database that uses custom compare functions.
|
46
|
+
.TP
|
47
|
+
.BR \-f \ file
|
48
|
+
Read from the specified file instead of from the standard input.
|
49
|
+
.TP
|
50
|
+
.BR \-n
|
51
|
+
Load an LMDB database which does not use subdirectories.
|
52
|
+
.TP
|
53
|
+
.BR \-s \ subdb
|
54
|
+
Load a specific subdatabase. If no database is specified, data is loaded into the main database.
|
55
|
+
.TP
|
56
|
+
.BR \-N
|
57
|
+
Don't overwrite existing records when loading into an already existing database; just skip them.
|
58
|
+
.TP
|
59
|
+
.BR \-T
|
60
|
+
Load data from simple text files. The input must be paired lines of text, where the first
|
61
|
+
line of the pair is the key item, and the second line of the pair is its corresponding
|
62
|
+
data item.
|
63
|
+
|
64
|
+
A simple escape mechanism, where newline and backslash (\\) characters are special, is
|
65
|
+
applied to the text input. Newline characters are interpreted as record separators.
|
66
|
+
Backslash characters in the text will be interpreted in one of two ways: If the backslash
|
67
|
+
character precedes another backslash character, the pair will be interpreted as a literal
|
68
|
+
backslash. If the backslash character precedes any other character, the two characters
|
69
|
+
following the backslash will be interpreted as a hexadecimal specification of a single
|
70
|
+
character; for example, \\0a is a newline character in the ASCII character set.
|
71
|
+
|
72
|
+
For this reason, any backslash or newline characters that naturally occur in the text
|
73
|
+
input must be escaped to avoid misinterpretation by
|
74
|
+
.BR mdb_load .
|
75
|
+
|
76
|
+
.SH DIAGNOSTICS
|
77
|
+
Exit status is zero if no errors occur.
|
78
|
+
Errors result in a non-zero exit status and
|
79
|
+
a diagnostic message being written to standard error.
|
80
|
+
|
81
|
+
.SH "SEE ALSO"
|
82
|
+
.BR mdb_dump (1)
|
83
|
+
.SH AUTHOR
|
84
|
+
Howard Chu of Symas Corporation <http://www.symas.com>
|
@@ -0,0 +1,492 @@
|
|
1
|
+
/* mdb_load.c - memory-mapped database load tool */
|
2
|
+
/*
|
3
|
+
* Copyright 2011-2021 Howard Chu, Symas Corp.
|
4
|
+
* All rights reserved.
|
5
|
+
*
|
6
|
+
* Redistribution and use in source and binary forms, with or without
|
7
|
+
* modification, are permitted only as authorized by the OpenLDAP
|
8
|
+
* Public License.
|
9
|
+
*
|
10
|
+
* A copy of this license is available in the file LICENSE in the
|
11
|
+
* top-level directory of the distribution or, alternatively, at
|
12
|
+
* <http://www.OpenLDAP.org/license.html>.
|
13
|
+
*/
|
14
|
+
#include <stdio.h>
|
15
|
+
#include <stdlib.h>
|
16
|
+
#include <errno.h>
|
17
|
+
#include <string.h>
|
18
|
+
#include <ctype.h>
|
19
|
+
#include <unistd.h>
|
20
|
+
#include "lmdb.h"
|
21
|
+
|
22
|
+
#define PRINT 1
|
23
|
+
#define NOHDR 2
|
24
|
+
static int mode;
|
25
|
+
|
26
|
+
static char *subname = NULL;
|
27
|
+
|
28
|
+
static mdb_size_t lineno;
|
29
|
+
static int version;
|
30
|
+
|
31
|
+
static int flags;
|
32
|
+
|
33
|
+
static char *prog;
|
34
|
+
|
35
|
+
static int Eof;
|
36
|
+
|
37
|
+
static MDB_envinfo info;
|
38
|
+
|
39
|
+
static MDB_val kbuf, dbuf;
|
40
|
+
static MDB_val k0buf;
|
41
|
+
|
42
|
+
#define Yu MDB_PRIy(u)
|
43
|
+
|
44
|
+
#define STRLENOF(s) (sizeof(s)-1)
|
45
|
+
|
46
|
+
typedef struct flagbit {
|
47
|
+
int bit;
|
48
|
+
char *name;
|
49
|
+
int len;
|
50
|
+
} flagbit;
|
51
|
+
|
52
|
+
#define S(s) s, STRLENOF(s)
|
53
|
+
|
54
|
+
flagbit dbflags[] = {
|
55
|
+
{ MDB_REVERSEKEY, S("reversekey") },
|
56
|
+
{ MDB_DUPSORT, S("dupsort") },
|
57
|
+
{ MDB_INTEGERKEY, S("integerkey") },
|
58
|
+
{ MDB_DUPFIXED, S("dupfixed") },
|
59
|
+
{ MDB_INTEGERDUP, S("integerdup") },
|
60
|
+
{ MDB_REVERSEDUP, S("reversedup") },
|
61
|
+
{ 0, NULL, 0 }
|
62
|
+
};
|
63
|
+
|
64
|
+
static void readhdr(void)
|
65
|
+
{
|
66
|
+
char *ptr;
|
67
|
+
|
68
|
+
flags = 0;
|
69
|
+
while (fgets(dbuf.mv_data, dbuf.mv_size, stdin) != NULL) {
|
70
|
+
lineno++;
|
71
|
+
if (!strncmp(dbuf.mv_data, "VERSION=", STRLENOF("VERSION="))) {
|
72
|
+
version=atoi((char *)dbuf.mv_data+STRLENOF("VERSION="));
|
73
|
+
if (version > 3) {
|
74
|
+
fprintf(stderr, "%s: line %"Yu": unsupported VERSION %d\n",
|
75
|
+
prog, lineno, version);
|
76
|
+
exit(EXIT_FAILURE);
|
77
|
+
}
|
78
|
+
} else if (!strncmp(dbuf.mv_data, "HEADER=END", STRLENOF("HEADER=END"))) {
|
79
|
+
break;
|
80
|
+
} else if (!strncmp(dbuf.mv_data, "format=", STRLENOF("format="))) {
|
81
|
+
if (!strncmp((char *)dbuf.mv_data+STRLENOF("FORMAT="), "print", STRLENOF("print")))
|
82
|
+
mode |= PRINT;
|
83
|
+
else if (strncmp((char *)dbuf.mv_data+STRLENOF("FORMAT="), "bytevalue", STRLENOF("bytevalue"))) {
|
84
|
+
fprintf(stderr, "%s: line %"Yu": unsupported FORMAT %s\n",
|
85
|
+
prog, lineno, (char *)dbuf.mv_data+STRLENOF("FORMAT="));
|
86
|
+
exit(EXIT_FAILURE);
|
87
|
+
}
|
88
|
+
} else if (!strncmp(dbuf.mv_data, "database=", STRLENOF("database="))) {
|
89
|
+
ptr = memchr(dbuf.mv_data, '\n', dbuf.mv_size);
|
90
|
+
if (ptr) *ptr = '\0';
|
91
|
+
if (subname) free(subname);
|
92
|
+
subname = strdup((char *)dbuf.mv_data+STRLENOF("database="));
|
93
|
+
} else if (!strncmp(dbuf.mv_data, "type=", STRLENOF("type="))) {
|
94
|
+
if (strncmp((char *)dbuf.mv_data+STRLENOF("type="), "btree", STRLENOF("btree"))) {
|
95
|
+
fprintf(stderr, "%s: line %"Yu": unsupported type %s\n",
|
96
|
+
prog, lineno, (char *)dbuf.mv_data+STRLENOF("type="));
|
97
|
+
exit(EXIT_FAILURE);
|
98
|
+
}
|
99
|
+
} else if (!strncmp(dbuf.mv_data, "mapaddr=", STRLENOF("mapaddr="))) {
|
100
|
+
int i;
|
101
|
+
ptr = memchr(dbuf.mv_data, '\n', dbuf.mv_size);
|
102
|
+
if (ptr) *ptr = '\0';
|
103
|
+
i = sscanf((char *)dbuf.mv_data+STRLENOF("mapaddr="), "%p", &info.me_mapaddr);
|
104
|
+
if (i != 1) {
|
105
|
+
fprintf(stderr, "%s: line %"Yu": invalid mapaddr %s\n",
|
106
|
+
prog, lineno, (char *)dbuf.mv_data+STRLENOF("mapaddr="));
|
107
|
+
exit(EXIT_FAILURE);
|
108
|
+
}
|
109
|
+
} else if (!strncmp(dbuf.mv_data, "mapsize=", STRLENOF("mapsize="))) {
|
110
|
+
int i;
|
111
|
+
ptr = memchr(dbuf.mv_data, '\n', dbuf.mv_size);
|
112
|
+
if (ptr) *ptr = '\0';
|
113
|
+
i = sscanf((char *)dbuf.mv_data+STRLENOF("mapsize="),
|
114
|
+
"%" MDB_SCNy(u), &info.me_mapsize);
|
115
|
+
if (i != 1) {
|
116
|
+
fprintf(stderr, "%s: line %"Yu": invalid mapsize %s\n",
|
117
|
+
prog, lineno, (char *)dbuf.mv_data+STRLENOF("mapsize="));
|
118
|
+
exit(EXIT_FAILURE);
|
119
|
+
}
|
120
|
+
} else if (!strncmp(dbuf.mv_data, "maxreaders=", STRLENOF("maxreaders="))) {
|
121
|
+
int i;
|
122
|
+
ptr = memchr(dbuf.mv_data, '\n', dbuf.mv_size);
|
123
|
+
if (ptr) *ptr = '\0';
|
124
|
+
i = sscanf((char *)dbuf.mv_data+STRLENOF("maxreaders="), "%u", &info.me_maxreaders);
|
125
|
+
if (i != 1) {
|
126
|
+
fprintf(stderr, "%s: line %"Yu": invalid maxreaders %s\n",
|
127
|
+
prog, lineno, (char *)dbuf.mv_data+STRLENOF("maxreaders="));
|
128
|
+
exit(EXIT_FAILURE);
|
129
|
+
}
|
130
|
+
} else {
|
131
|
+
int i;
|
132
|
+
for (i=0; dbflags[i].bit; i++) {
|
133
|
+
if (!strncmp(dbuf.mv_data, dbflags[i].name, dbflags[i].len) &&
|
134
|
+
((char *)dbuf.mv_data)[dbflags[i].len] == '=') {
|
135
|
+
flags |= dbflags[i].bit;
|
136
|
+
break;
|
137
|
+
}
|
138
|
+
}
|
139
|
+
if (!dbflags[i].bit) {
|
140
|
+
ptr = memchr(dbuf.mv_data, '=', dbuf.mv_size);
|
141
|
+
if (!ptr) {
|
142
|
+
fprintf(stderr, "%s: line %"Yu": unexpected format\n",
|
143
|
+
prog, lineno);
|
144
|
+
exit(EXIT_FAILURE);
|
145
|
+
} else {
|
146
|
+
*ptr = '\0';
|
147
|
+
fprintf(stderr, "%s: line %"Yu": unrecognized keyword ignored: %s\n",
|
148
|
+
prog, lineno, (char *)dbuf.mv_data);
|
149
|
+
}
|
150
|
+
}
|
151
|
+
}
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
static void badend(void)
|
156
|
+
{
|
157
|
+
fprintf(stderr, "%s: line %"Yu": unexpected end of input\n",
|
158
|
+
prog, lineno);
|
159
|
+
}
|
160
|
+
|
161
|
+
static int unhex(unsigned char *c2)
|
162
|
+
{
|
163
|
+
int x, c;
|
164
|
+
x = *c2++ & 0x4f;
|
165
|
+
if (x & 0x40)
|
166
|
+
x -= 55;
|
167
|
+
c = x << 4;
|
168
|
+
x = *c2 & 0x4f;
|
169
|
+
if (x & 0x40)
|
170
|
+
x -= 55;
|
171
|
+
c |= x;
|
172
|
+
return c;
|
173
|
+
}
|
174
|
+
|
175
|
+
static int readline(MDB_val *out, MDB_val *buf)
|
176
|
+
{
|
177
|
+
unsigned char *c1, *c2, *end;
|
178
|
+
size_t len, l2;
|
179
|
+
int c;
|
180
|
+
|
181
|
+
if (!(mode & NOHDR)) {
|
182
|
+
c = fgetc(stdin);
|
183
|
+
if (c == EOF) {
|
184
|
+
Eof = 1;
|
185
|
+
return EOF;
|
186
|
+
}
|
187
|
+
if (c != ' ') {
|
188
|
+
lineno++;
|
189
|
+
if (fgets(buf->mv_data, buf->mv_size, stdin) == NULL) {
|
190
|
+
badend:
|
191
|
+
Eof = 1;
|
192
|
+
badend();
|
193
|
+
return EOF;
|
194
|
+
}
|
195
|
+
if (c == 'D' && !strncmp(buf->mv_data, "ATA=END", STRLENOF("ATA=END")))
|
196
|
+
return EOF;
|
197
|
+
goto badend;
|
198
|
+
}
|
199
|
+
}
|
200
|
+
if (fgets(buf->mv_data, buf->mv_size, stdin) == NULL) {
|
201
|
+
Eof = 1;
|
202
|
+
return EOF;
|
203
|
+
}
|
204
|
+
lineno++;
|
205
|
+
|
206
|
+
c1 = buf->mv_data;
|
207
|
+
len = strlen((char *)c1);
|
208
|
+
l2 = len;
|
209
|
+
|
210
|
+
/* Is buffer too short? */
|
211
|
+
while (c1[len-1] != '\n') {
|
212
|
+
buf->mv_data = realloc(buf->mv_data, buf->mv_size*2);
|
213
|
+
if (!buf->mv_data) {
|
214
|
+
Eof = 1;
|
215
|
+
fprintf(stderr, "%s: line %"Yu": out of memory, line too long\n",
|
216
|
+
prog, lineno);
|
217
|
+
return EOF;
|
218
|
+
}
|
219
|
+
c1 = buf->mv_data;
|
220
|
+
c1 += l2;
|
221
|
+
if (fgets((char *)c1, buf->mv_size+1, stdin) == NULL) {
|
222
|
+
Eof = 1;
|
223
|
+
badend();
|
224
|
+
return EOF;
|
225
|
+
}
|
226
|
+
buf->mv_size *= 2;
|
227
|
+
len = strlen((char *)c1);
|
228
|
+
l2 += len;
|
229
|
+
}
|
230
|
+
c1 = c2 = buf->mv_data;
|
231
|
+
len = l2;
|
232
|
+
c1[--len] = '\0';
|
233
|
+
end = c1 + len;
|
234
|
+
|
235
|
+
if (mode & PRINT) {
|
236
|
+
while (c2 < end) {
|
237
|
+
if (*c2 == '\\') {
|
238
|
+
if (c2[1] == '\\') {
|
239
|
+
*c1++ = *c2;
|
240
|
+
} else {
|
241
|
+
if (c2+3 > end || !isxdigit(c2[1]) || !isxdigit(c2[2])) {
|
242
|
+
Eof = 1;
|
243
|
+
badend();
|
244
|
+
return EOF;
|
245
|
+
}
|
246
|
+
*c1++ = unhex(++c2);
|
247
|
+
}
|
248
|
+
c2 += 2;
|
249
|
+
} else {
|
250
|
+
/* copies are redundant when no escapes were used */
|
251
|
+
*c1++ = *c2++;
|
252
|
+
}
|
253
|
+
}
|
254
|
+
} else {
|
255
|
+
/* odd length not allowed */
|
256
|
+
if (len & 1) {
|
257
|
+
Eof = 1;
|
258
|
+
badend();
|
259
|
+
return EOF;
|
260
|
+
}
|
261
|
+
while (c2 < end) {
|
262
|
+
if (!isxdigit(*c2) || !isxdigit(c2[1])) {
|
263
|
+
Eof = 1;
|
264
|
+
badend();
|
265
|
+
return EOF;
|
266
|
+
}
|
267
|
+
*c1++ = unhex(c2);
|
268
|
+
c2 += 2;
|
269
|
+
}
|
270
|
+
}
|
271
|
+
c2 = out->mv_data = buf->mv_data;
|
272
|
+
out->mv_size = c1 - c2;
|
273
|
+
|
274
|
+
return 0;
|
275
|
+
}
|
276
|
+
|
277
|
+
static void usage(void)
|
278
|
+
{
|
279
|
+
fprintf(stderr, "usage: %s [-V] [-a] [-f input] [-n] [-s name] [-N] [-T] dbpath\n", prog);
|
280
|
+
exit(EXIT_FAILURE);
|
281
|
+
}
|
282
|
+
|
283
|
+
static int greater(const MDB_val *a, const MDB_val *b)
|
284
|
+
{
|
285
|
+
return 1;
|
286
|
+
}
|
287
|
+
|
288
|
+
int main(int argc, char *argv[])
|
289
|
+
{
|
290
|
+
int i, rc;
|
291
|
+
MDB_env *env;
|
292
|
+
MDB_txn *txn;
|
293
|
+
MDB_cursor *mc;
|
294
|
+
MDB_dbi dbi;
|
295
|
+
char *envname;
|
296
|
+
int envflags = MDB_NOSYNC, putflags = 0;
|
297
|
+
int dohdr = 0, append = 0;
|
298
|
+
MDB_val prevk;
|
299
|
+
|
300
|
+
prog = argv[0];
|
301
|
+
|
302
|
+
if (argc < 2) {
|
303
|
+
usage();
|
304
|
+
}
|
305
|
+
|
306
|
+
/* -a: append records in input order
|
307
|
+
* -f: load file instead of stdin
|
308
|
+
* -n: use NOSUBDIR flag on env_open
|
309
|
+
* -s: load into named subDB
|
310
|
+
* -N: use NOOVERWRITE on puts
|
311
|
+
* -T: read plaintext
|
312
|
+
* -V: print version and exit
|
313
|
+
*/
|
314
|
+
while ((i = getopt(argc, argv, "af:ns:NTV")) != EOF) {
|
315
|
+
switch(i) {
|
316
|
+
case 'V':
|
317
|
+
printf("%s\n", MDB_VERSION_STRING);
|
318
|
+
exit(0);
|
319
|
+
break;
|
320
|
+
case 'a':
|
321
|
+
append = 1;
|
322
|
+
break;
|
323
|
+
case 'f':
|
324
|
+
if (freopen(optarg, "r", stdin) == NULL) {
|
325
|
+
fprintf(stderr, "%s: %s: reopen: %s\n",
|
326
|
+
prog, optarg, strerror(errno));
|
327
|
+
exit(EXIT_FAILURE);
|
328
|
+
}
|
329
|
+
break;
|
330
|
+
case 'n':
|
331
|
+
envflags |= MDB_NOSUBDIR;
|
332
|
+
break;
|
333
|
+
case 's':
|
334
|
+
subname = strdup(optarg);
|
335
|
+
break;
|
336
|
+
case 'N':
|
337
|
+
putflags = MDB_NOOVERWRITE|MDB_NODUPDATA;
|
338
|
+
break;
|
339
|
+
case 'T':
|
340
|
+
mode |= NOHDR | PRINT;
|
341
|
+
break;
|
342
|
+
default:
|
343
|
+
usage();
|
344
|
+
}
|
345
|
+
}
|
346
|
+
|
347
|
+
if (optind != argc - 1)
|
348
|
+
usage();
|
349
|
+
|
350
|
+
dbuf.mv_size = 4096;
|
351
|
+
dbuf.mv_data = malloc(dbuf.mv_size);
|
352
|
+
|
353
|
+
if (!(mode & NOHDR))
|
354
|
+
readhdr();
|
355
|
+
|
356
|
+
envname = argv[optind];
|
357
|
+
rc = mdb_env_create(&env);
|
358
|
+
if (rc) {
|
359
|
+
fprintf(stderr, "mdb_env_create failed, error %d %s\n", rc, mdb_strerror(rc));
|
360
|
+
return EXIT_FAILURE;
|
361
|
+
}
|
362
|
+
|
363
|
+
mdb_env_set_maxdbs(env, 2);
|
364
|
+
|
365
|
+
if (info.me_maxreaders)
|
366
|
+
mdb_env_set_maxreaders(env, info.me_maxreaders);
|
367
|
+
|
368
|
+
if (info.me_mapsize)
|
369
|
+
mdb_env_set_mapsize(env, info.me_mapsize);
|
370
|
+
|
371
|
+
if (info.me_mapaddr)
|
372
|
+
envflags |= MDB_FIXEDMAP;
|
373
|
+
|
374
|
+
rc = mdb_env_open(env, envname, envflags, 0664);
|
375
|
+
if (rc) {
|
376
|
+
fprintf(stderr, "mdb_env_open failed, error %d %s\n", rc, mdb_strerror(rc));
|
377
|
+
goto env_close;
|
378
|
+
}
|
379
|
+
|
380
|
+
kbuf.mv_size = mdb_env_get_maxkeysize(env) * 2 + 2;
|
381
|
+
kbuf.mv_data = malloc(kbuf.mv_size * 2);
|
382
|
+
k0buf.mv_size = kbuf.mv_size;
|
383
|
+
k0buf.mv_data = (char *)kbuf.mv_data + kbuf.mv_size;
|
384
|
+
prevk.mv_data = k0buf.mv_data;
|
385
|
+
|
386
|
+
while(!Eof) {
|
387
|
+
MDB_val key, data;
|
388
|
+
int batch = 0;
|
389
|
+
int appflag;
|
390
|
+
|
391
|
+
if (!dohdr) {
|
392
|
+
dohdr = 1;
|
393
|
+
} else if (!(mode & NOHDR))
|
394
|
+
readhdr();
|
395
|
+
|
396
|
+
rc = mdb_txn_begin(env, NULL, 0, &txn);
|
397
|
+
if (rc) {
|
398
|
+
fprintf(stderr, "mdb_txn_begin failed, error %d %s\n", rc, mdb_strerror(rc));
|
399
|
+
goto env_close;
|
400
|
+
}
|
401
|
+
|
402
|
+
rc = mdb_open(txn, subname, flags|MDB_CREATE, &dbi);
|
403
|
+
if (rc) {
|
404
|
+
fprintf(stderr, "mdb_open failed, error %d %s\n", rc, mdb_strerror(rc));
|
405
|
+
goto txn_abort;
|
406
|
+
}
|
407
|
+
prevk.mv_size = 0;
|
408
|
+
if (append) {
|
409
|
+
mdb_set_compare(txn, dbi, greater);
|
410
|
+
if (flags & MDB_DUPSORT)
|
411
|
+
mdb_set_dupsort(txn, dbi, greater);
|
412
|
+
}
|
413
|
+
|
414
|
+
rc = mdb_cursor_open(txn, dbi, &mc);
|
415
|
+
if (rc) {
|
416
|
+
fprintf(stderr, "mdb_cursor_open failed, error %d %s\n", rc, mdb_strerror(rc));
|
417
|
+
goto txn_abort;
|
418
|
+
}
|
419
|
+
|
420
|
+
while(1) {
|
421
|
+
rc = readline(&key, &kbuf);
|
422
|
+
if (rc) /* rc == EOF */
|
423
|
+
break;
|
424
|
+
|
425
|
+
rc = readline(&data, &dbuf);
|
426
|
+
if (rc) {
|
427
|
+
fprintf(stderr, "%s: line %"Yu": failed to read key value\n", prog, lineno);
|
428
|
+
goto txn_abort;
|
429
|
+
}
|
430
|
+
|
431
|
+
if (append) {
|
432
|
+
appflag = MDB_APPEND;
|
433
|
+
if (flags & MDB_DUPSORT) {
|
434
|
+
if (prevk.mv_size == key.mv_size && !memcmp(prevk.mv_data, key.mv_data, key.mv_size))
|
435
|
+
appflag = MDB_CURRENT|MDB_APPENDDUP;
|
436
|
+
else {
|
437
|
+
memcpy(prevk.mv_data, key.mv_data, key.mv_size);
|
438
|
+
prevk.mv_size = key.mv_size;
|
439
|
+
}
|
440
|
+
}
|
441
|
+
} else {
|
442
|
+
appflag = 0;
|
443
|
+
}
|
444
|
+
rc = mdb_cursor_put(mc, &key, &data, putflags|appflag);
|
445
|
+
if (rc == MDB_KEYEXIST && putflags)
|
446
|
+
continue;
|
447
|
+
if (rc) {
|
448
|
+
fprintf(stderr, "mdb_cursor_put failed, error %d %s\n", rc, mdb_strerror(rc));
|
449
|
+
goto txn_abort;
|
450
|
+
}
|
451
|
+
batch++;
|
452
|
+
if (batch == 100) {
|
453
|
+
rc = mdb_txn_commit(txn);
|
454
|
+
if (rc) {
|
455
|
+
fprintf(stderr, "%s: line %"Yu": txn_commit: %s\n",
|
456
|
+
prog, lineno, mdb_strerror(rc));
|
457
|
+
goto env_close;
|
458
|
+
}
|
459
|
+
rc = mdb_txn_begin(env, NULL, 0, &txn);
|
460
|
+
if (rc) {
|
461
|
+
fprintf(stderr, "mdb_txn_begin failed, error %d %s\n", rc, mdb_strerror(rc));
|
462
|
+
goto env_close;
|
463
|
+
}
|
464
|
+
rc = mdb_cursor_open(txn, dbi, &mc);
|
465
|
+
if (rc) {
|
466
|
+
fprintf(stderr, "mdb_cursor_open failed, error %d %s\n", rc, mdb_strerror(rc));
|
467
|
+
goto txn_abort;
|
468
|
+
}
|
469
|
+
if (appflag & MDB_APPENDDUP) {
|
470
|
+
MDB_val k, d;
|
471
|
+
mdb_cursor_get(mc, &k, &d, MDB_LAST);
|
472
|
+
}
|
473
|
+
batch = 0;
|
474
|
+
}
|
475
|
+
}
|
476
|
+
rc = mdb_txn_commit(txn);
|
477
|
+
txn = NULL;
|
478
|
+
if (rc) {
|
479
|
+
fprintf(stderr, "%s: line %"Yu": txn_commit: %s\n",
|
480
|
+
prog, lineno, mdb_strerror(rc));
|
481
|
+
goto env_close;
|
482
|
+
}
|
483
|
+
mdb_dbi_close(env, dbi);
|
484
|
+
}
|
485
|
+
|
486
|
+
txn_abort:
|
487
|
+
mdb_txn_abort(txn);
|
488
|
+
env_close:
|
489
|
+
mdb_env_close(env);
|
490
|
+
|
491
|
+
return rc ? EXIT_FAILURE : EXIT_SUCCESS;
|
492
|
+
}
|
@@ -0,0 +1,70 @@
|
|
1
|
+
.TH MDB_STAT 1 "2017/07/31" "LMDB 0.9.70"
|
2
|
+
.\" Copyright 2012-2021 Howard Chu, Symas Corp. All Rights Reserved.
|
3
|
+
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
|
4
|
+
.SH NAME
|
5
|
+
mdb_stat \- LMDB environment status tool
|
6
|
+
.SH SYNOPSIS
|
7
|
+
.B mdb_stat
|
8
|
+
[\c
|
9
|
+
.BR \-V ]
|
10
|
+
[\c
|
11
|
+
.BR \-e ]
|
12
|
+
[\c
|
13
|
+
.BR \-f [ f [ f ]]]
|
14
|
+
[\c
|
15
|
+
.BR \-n ]
|
16
|
+
[\c
|
17
|
+
.BR \-v ]
|
18
|
+
[\c
|
19
|
+
.BR \-r [ r ]]
|
20
|
+
[\c
|
21
|
+
.BR \-a \ |
|
22
|
+
.BI \-s \ subdb\fR]
|
23
|
+
.BR \ envpath
|
24
|
+
.SH DESCRIPTION
|
25
|
+
The
|
26
|
+
.B mdb_stat
|
27
|
+
utility displays the status of an LMDB environment.
|
28
|
+
.SH OPTIONS
|
29
|
+
.TP
|
30
|
+
.BR \-V
|
31
|
+
Write the library version number to the standard output, and exit.
|
32
|
+
.TP
|
33
|
+
.BR \-e
|
34
|
+
Display information about the database environment.
|
35
|
+
.TP
|
36
|
+
.BR \-f
|
37
|
+
Display information about the environment freelist.
|
38
|
+
If \fB\-ff\fP is given, summarize each freelist entry.
|
39
|
+
If \fB\-fff\fP is given, display the full list of page IDs in the freelist.
|
40
|
+
.TP
|
41
|
+
.BR \-n
|
42
|
+
Display the status of an LMDB database which does not use subdirectories.
|
43
|
+
.TP
|
44
|
+
.BR \-v
|
45
|
+
Use the previous environment state instead of the latest state.
|
46
|
+
This may be useful if the latest state has been corrupted.
|
47
|
+
.TP
|
48
|
+
.BR \-r
|
49
|
+
Display information about the environment reader table.
|
50
|
+
Shows the process ID, thread ID, and transaction ID for each active
|
51
|
+
reader slot. The process ID and transaction ID are in decimal, the
|
52
|
+
thread ID is in hexadecimal. The transaction ID is displayed as "-"
|
53
|
+
if the reader does not currently have a read transaction open.
|
54
|
+
If \fB\-rr\fP is given, check for stale entries in the reader
|
55
|
+
table and clear them. The reader table will be printed again
|
56
|
+
after the check is performed.
|
57
|
+
.TP
|
58
|
+
.BR \-a
|
59
|
+
Display the status of all of the subdatabases in the environment.
|
60
|
+
.TP
|
61
|
+
.BR \-s \ subdb
|
62
|
+
Display the status of a specific subdatabase.
|
63
|
+
.SH DIAGNOSTICS
|
64
|
+
Exit status is zero if no errors occur.
|
65
|
+
Errors result in a non-zero exit status and
|
66
|
+
a diagnostic message being written to standard error.
|
67
|
+
.SH "SEE ALSO"
|
68
|
+
.BR mdb_copy (1)
|
69
|
+
.SH AUTHOR
|
70
|
+
Howard Chu of Symas Corporation <http://www.symas.com>
|