mdbx-tools: rework/fix mdbx_load for custom comparators.

Change-Id: I9bc15fb878d1586839768f97567806208bfcc5b8
This commit is contained in:
Leonid Yuriev 2020-01-20 22:15:33 +03:00
parent 2c1d3a3fda
commit 2d334185cb

View File

@ -55,7 +55,7 @@ static int version;
static int dbi_flags; static int dbi_flags;
static char *prog; static char *prog;
static int Eof; static bool Eof;
static MDBX_envinfo envinfo; static MDBX_envinfo envinfo;
static MDBX_val kbuf, dbuf; static MDBX_val kbuf, dbuf;
@ -85,20 +85,32 @@ static void readhdr(void) {
dbi_flags = 0; dbi_flags = 0;
while (fgets(dbuf.iov_base, (int)dbuf.iov_len, stdin) != NULL) { while (fgets(dbuf.iov_base, (int)dbuf.iov_len, stdin) != NULL) {
lineno++; lineno++;
if (!strncmp(dbuf.iov_base, "db_pagesize=", STRLENOF("db_pagesize=")) ||
!strncmp(dbuf.iov_base, "duplicates=", STRLENOF("duplicates="))) { if (!strncmp(dbuf.iov_base, "db_pagesize=", STRLENOF("db_pagesize="))) {
/* LY: silently ignore information fields. */ envinfo.mi_dxb_pagesize =
atoi((char *)dbuf.iov_base + STRLENOF("db_pagesize="));
continue; continue;
} else if (!strncmp(dbuf.iov_base, "VERSION=", STRLENOF("VERSION="))) { }
if (!strncmp(dbuf.iov_base, "duplicates=", STRLENOF("duplicates="))) {
dbi_flags |= MDBX_DUPSORT;
continue;
}
if (!strncmp(dbuf.iov_base, "VERSION=", STRLENOF("VERSION="))) {
version = atoi((char *)dbuf.iov_base + STRLENOF("VERSION=")); version = atoi((char *)dbuf.iov_base + STRLENOF("VERSION="));
if (version > 3) { if (version > 3) {
fprintf(stderr, "%s: line %" PRIiSIZE ": unsupported VERSION %d\n", fprintf(stderr, "%s: line %" PRIiSIZE ": unsupported VERSION %d\n",
prog, lineno, version); prog, lineno, version);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} else if (!strncmp(dbuf.iov_base, "HEADER=END", STRLENOF("HEADER=END"))) { continue;
break; }
} else if (!strncmp(dbuf.iov_base, "format=", STRLENOF("format="))) {
if (!strncmp(dbuf.iov_base, "HEADER=END", STRLENOF("HEADER=END")))
return;
if (!strncmp(dbuf.iov_base, "format=", STRLENOF("format="))) {
if (!strncmp((char *)dbuf.iov_base + STRLENOF("FORMAT="), "print", if (!strncmp((char *)dbuf.iov_base + STRLENOF("FORMAT="), "print",
STRLENOF("print"))) STRLENOF("print")))
mode |= PRINT; mode |= PRINT;
@ -108,21 +120,30 @@ static void readhdr(void) {
lineno, (char *)dbuf.iov_base + STRLENOF("FORMAT=")); lineno, (char *)dbuf.iov_base + STRLENOF("FORMAT="));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} else if (!strncmp(dbuf.iov_base, "database=", STRLENOF("database="))) { continue;
}
if (!strncmp(dbuf.iov_base, "database=", STRLENOF("database="))) {
ptr = memchr(dbuf.iov_base, '\n', dbuf.iov_len); ptr = memchr(dbuf.iov_base, '\n', dbuf.iov_len);
if (ptr) if (ptr)
*ptr = '\0'; *ptr = '\0';
if (subname) if (subname)
mdbx_free(subname); mdbx_free(subname);
subname = mdbx_strdup((char *)dbuf.iov_base + STRLENOF("database=")); subname = mdbx_strdup((char *)dbuf.iov_base + STRLENOF("database="));
} else if (!strncmp(dbuf.iov_base, "type=", STRLENOF("type="))) { continue;
}
if (!strncmp(dbuf.iov_base, "type=", STRLENOF("type="))) {
if (strncmp((char *)dbuf.iov_base + STRLENOF("type="), "btree", if (strncmp((char *)dbuf.iov_base + STRLENOF("type="), "btree",
STRLENOF("btree"))) { STRLENOF("btree"))) {
fprintf(stderr, "%s: line %" PRIiSIZE ": unsupported type %s\n", prog, fprintf(stderr, "%s: line %" PRIiSIZE ": unsupported type %s\n", prog,
lineno, (char *)dbuf.iov_base + STRLENOF("type=")); lineno, (char *)dbuf.iov_base + STRLENOF("type="));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} else if (!strncmp(dbuf.iov_base, "mapaddr=", STRLENOF("mapaddr="))) { continue;
}
if (!strncmp(dbuf.iov_base, "mapaddr=", STRLENOF("mapaddr="))) {
int i; int i;
ptr = memchr(dbuf.iov_base, '\n', dbuf.iov_len); ptr = memchr(dbuf.iov_base, '\n', dbuf.iov_len);
if (ptr) if (ptr)
@ -134,7 +155,10 @@ static void readhdr(void) {
lineno, (char *)dbuf.iov_base + STRLENOF("mapaddr=")); lineno, (char *)dbuf.iov_base + STRLENOF("mapaddr="));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} else if (!strncmp(dbuf.iov_base, "mapsize=", STRLENOF("mapsize="))) { continue;
}
if (!strncmp(dbuf.iov_base, "mapsize=", STRLENOF("mapsize="))) {
int i; int i;
ptr = memchr(dbuf.iov_base, '\n', dbuf.iov_len); ptr = memchr(dbuf.iov_base, '\n', dbuf.iov_len);
if (ptr) if (ptr)
@ -146,8 +170,10 @@ static void readhdr(void) {
lineno, (char *)dbuf.iov_base + STRLENOF("mapsize=")); lineno, (char *)dbuf.iov_base + STRLENOF("mapsize="));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} else if (!strncmp(dbuf.iov_base, continue;
"maxreaders=", STRLENOF("maxreaders="))) { }
if (!strncmp(dbuf.iov_base, "maxreaders=", STRLENOF("maxreaders="))) {
int i; int i;
ptr = memchr(dbuf.iov_base, '\n', dbuf.iov_len); ptr = memchr(dbuf.iov_base, '\n', dbuf.iov_len);
if (ptr) if (ptr)
@ -159,31 +185,33 @@ static void readhdr(void) {
lineno, (char *)dbuf.iov_base + STRLENOF("maxreaders=")); lineno, (char *)dbuf.iov_base + STRLENOF("maxreaders="));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} else { continue;
int i; }
for (i = 0; dbflags[i].bit; i++) {
if (!strncmp(dbuf.iov_base, dbflags[i].name, dbflags[i].len) && int i;
((char *)dbuf.iov_base)[dbflags[i].len] == '=') { for (i = 0; dbflags[i].bit; i++) {
if (((char *)dbuf.iov_base)[dbflags[i].len + 1] == '1') if (!strncmp(dbuf.iov_base, dbflags[i].name, dbflags[i].len) &&
dbi_flags |= dbflags[i].bit; ((char *)dbuf.iov_base)[dbflags[i].len] == '=') {
break; if (((char *)dbuf.iov_base)[dbflags[i].len + 1] == '1')
} dbi_flags |= dbflags[i].bit;
break;
} }
if (!dbflags[i].bit) { }
ptr = memchr(dbuf.iov_base, '=', dbuf.iov_len); if (!dbflags[i].bit) {
if (!ptr) { ptr = memchr(dbuf.iov_base, '=', dbuf.iov_len);
fprintf(stderr, "%s: line %" PRIiSIZE ": unexpected format\n", prog, if (!ptr) {
lineno); fprintf(stderr, "%s: line %" PRIiSIZE ": unexpected format\n", prog,
exit(EXIT_FAILURE); lineno);
} else { exit(EXIT_FAILURE);
*ptr = '\0'; } else {
fprintf(stderr, *ptr = '\0';
"%s: line %" PRIiSIZE ": unrecognized keyword ignored: %s\n", fprintf(stderr,
prog, lineno, (char *)dbuf.iov_base); "%s: line %" PRIiSIZE ": unrecognized keyword ignored: %s\n",
} prog, lineno, (char *)dbuf.iov_base);
} }
} }
} }
Eof = true;
} }
static void badend(void) { static void badend(void) {
@ -212,14 +240,14 @@ static int readline(MDBX_val *out, MDBX_val *buf) {
if (!(mode & NOHDR)) { if (!(mode & NOHDR)) {
c = fgetc(stdin); c = fgetc(stdin);
if (c == EOF) { if (c == EOF) {
Eof = 1; Eof = true;
return EOF; return EOF;
} }
if (c != ' ') { if (c != ' ') {
lineno++; lineno++;
if (fgets(buf->iov_base, (int)buf->iov_len, stdin) == NULL) { if (fgets(buf->iov_base, (int)buf->iov_len, stdin) == NULL) {
badend: badend:
Eof = 1; Eof = true;
badend(); badend();
return EOF; return EOF;
} }
@ -229,7 +257,7 @@ static int readline(MDBX_val *out, MDBX_val *buf) {
} }
} }
if (fgets(buf->iov_base, (int)buf->iov_len, stdin) == NULL) { if (fgets(buf->iov_base, (int)buf->iov_len, stdin) == NULL) {
Eof = 1; Eof = true;
return EOF; return EOF;
} }
lineno++; lineno++;
@ -242,7 +270,7 @@ static int readline(MDBX_val *out, MDBX_val *buf) {
while (c1[len - 1] != '\n') { while (c1[len - 1] != '\n') {
buf->iov_base = mdbx_realloc(buf->iov_base, buf->iov_len * 2); buf->iov_base = mdbx_realloc(buf->iov_base, buf->iov_len * 2);
if (!buf->iov_base) { if (!buf->iov_base) {
Eof = 1; Eof = true;
fprintf(stderr, "%s: line %" PRIiSIZE ": out of memory, line too long\n", fprintf(stderr, "%s: line %" PRIiSIZE ": out of memory, line too long\n",
prog, lineno); prog, lineno);
return EOF; return EOF;
@ -250,7 +278,7 @@ static int readline(MDBX_val *out, MDBX_val *buf) {
c1 = buf->iov_base; c1 = buf->iov_base;
c1 += l2; c1 += l2;
if (fgets((char *)c1, (int)buf->iov_len + 1, stdin) == NULL) { if (fgets((char *)c1, (int)buf->iov_len + 1, stdin) == NULL) {
Eof = 1; Eof = true;
badend(); badend();
return EOF; return EOF;
} }
@ -270,7 +298,7 @@ static int readline(MDBX_val *out, MDBX_val *buf) {
*c1++ = '\\'; *c1++ = '\\';
} else { } else {
if (c2 + 3 > end || !isxdigit(c2[1]) || !isxdigit(c2[2])) { if (c2 + 3 > end || !isxdigit(c2[1]) || !isxdigit(c2[2])) {
Eof = 1; Eof = true;
badend(); badend();
return EOF; return EOF;
} }
@ -285,13 +313,13 @@ static int readline(MDBX_val *out, MDBX_val *buf) {
} else { } else {
/* odd length not allowed */ /* odd length not allowed */
if (len & 1) { if (len & 1) {
Eof = 1; Eof = true;
badend(); badend();
return EOF; return EOF;
} }
while (c2 < end) { while (c2 < end) {
if (!isxdigit(*c2) || !isxdigit(c2[1])) { if (!isxdigit(*c2) || !isxdigit(c2[1])) {
Eof = 1; Eof = true;
badend(); badend();
return EOF; return EOF;
} }
@ -366,7 +394,7 @@ int main(int argc, char *argv[]) {
break; break;
case 'f': case 'f':
if (freopen(optarg, "r", stdin) == NULL) { if (freopen(optarg, "r", stdin) == NULL) {
fprintf(stderr, "%s: %s: reopen: %s\n", prog, optarg, fprintf(stderr, "%s: %s: open: %s\n", prog, optarg,
mdbx_strerror(errno)); mdbx_strerror(errno));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -433,16 +461,20 @@ int main(int argc, char *argv[]) {
mdbx_env_set_maxdbs(env, 2); mdbx_env_set_maxdbs(env, 2);
if (envinfo.mi_maxreaders) #ifdef MDBX_FIXEDMAP
mdbx_env_set_maxreaders(env, envinfo.mi_maxreaders); if (info.mi_mapaddr)
envflags |= MDBX_FIXEDMAP;
#endif
if (envinfo.mi_mapsize) { if (envinfo.mi_mapsize) {
if (envinfo.mi_mapsize > SIZE_MAX) { if (envinfo.mi_mapsize > INTPTR_MAX) {
fprintf(stderr, "mdbx_env_set_mapsize failed, error %d %s\n", rc, fprintf(stderr,
mdbx_strerror(MDBX_TOO_LARGE)); "Database size is too large for current system (mapsize=%" PRIu64
return EXIT_FAILURE; " is great than system-limit %zi)\n",
envinfo.mi_mapsize, INTPTR_MAX);
goto env_close;
} }
rc = mdbx_env_set_geometry(env, 0, -1, (size_t)envinfo.mi_mapsize, -1, -1, rc = mdbx_env_set_geometry(env, 0, 0, (intptr_t)envinfo.mi_mapsize, -1, -1,
-1); -1);
if (rc) { if (rc) {
fprintf(stderr, "mdbx_env_set_geometry failed, error %d %s\n", rc, fprintf(stderr, "mdbx_env_set_geometry failed, error %d %s\n", rc,
@ -451,11 +483,6 @@ int main(int argc, char *argv[]) {
} }
} }
#ifdef MDBX_FIXEDMAP
if (info.mi_mapaddr)
envflags |= MDBX_FIXEDMAP;
#endif
rc = mdbx_env_open(env, envname, envflags, 0664); rc = mdbx_env_open(env, envname, envflags, 0664);
if (rc) { if (rc) {
fprintf(stderr, "mdbx_env_open failed, error %d %s\n", rc, fprintf(stderr, "mdbx_env_open failed, error %d %s\n", rc,
@ -464,7 +491,7 @@ int main(int argc, char *argv[]) {
} }
kbuf.iov_len = mdbx_env_get_maxvalsize_ex(env, MDBX_DUPSORT); kbuf.iov_len = mdbx_env_get_maxvalsize_ex(env, MDBX_DUPSORT);
if (kbuf.iov_len >= SIZE_MAX / 4) { if (kbuf.iov_len >= INTPTR_MAX / 4) {
fprintf(stderr, "mdbx_env_get_maxkeysize failed, returns %zu\n", fprintf(stderr, "mdbx_env_get_maxkeysize failed, returns %zu\n",
kbuf.iov_len); kbuf.iov_len);
goto env_close; goto env_close;
@ -574,6 +601,7 @@ int main(int argc, char *argv[]) {
goto env_close; goto env_close;
} }
mdbx_dbi_close(env, dbi); mdbx_dbi_close(env, dbi);
subname = NULL;
/* try read next header */ /* try read next header */
if (!(mode & NOHDR)) if (!(mode & NOHDR))