From db44f4ed712b558166072348ac96fb26a6ccfbfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sun, 16 Mar 2025 20:02:26 +0300 Subject: [PATCH] =?UTF-8?q?mdbx-tools:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D0=BF=D1=86=D0=B8=D0=B8?= =?UTF-8?q?=20`-c`=20(concise)=20=D0=B2=20`mdbx=5Fdump`.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/man1/mdbx_dump.1 | 5 ++++ src/tools/dump.c | 69 ++++++++++++++++++++------------------------ src/tools/load.c | 13 +++++++-- 3 files changed, 48 insertions(+), 39 deletions(-) diff --git a/src/man1/mdbx_dump.1 b/src/man1/mdbx_dump.1 index 6b04c0af..39e917ce 100644 --- a/src/man1/mdbx_dump.1 +++ b/src/man1/mdbx_dump.1 @@ -12,6 +12,8 @@ mdbx_dump \- MDBX environment export tool [\c .BR \-q ] [\c +.BR \-c ] +[\c .BI \-f \ file\fR] [\c .BR \-l ] @@ -41,6 +43,9 @@ Write the library version number to the standard output, and exit. .BR \-q Be quiet. .TP +.BR \-c +Concise mode without repeating keys in a dump, but incompatible with Berkeley DB and LMDB. +.TP .BR \-f \ file Write to the specified file instead of to the standard output. .TP diff --git a/src/tools/dump.c b/src/tools/dump.c index c09b2b17..95d9c72b 100644 --- a/src/tools/dump.c +++ b/src/tools/dump.c @@ -20,6 +20,7 @@ #define PRINT 1 #define GLOBAL 2 +#define CONCISE 4 static int mode = GLOBAL; typedef struct flagbit { @@ -55,42 +56,23 @@ static void signal_handler(int sig) { #endif /* !WINDOWS */ -static const char hexc[] = "0123456789abcdef"; - -static void dumpbyte(unsigned char c) { - putchar(hexc[c >> 4]); - putchar(hexc[c & 15]); -} - -static void text(MDBX_val *v) { - unsigned char *c, *end; - +static void dumpval(const MDBX_val *v) { + static const char digits[] = "0123456789abcdef"; putchar(' '); - c = v->iov_base; - end = c + v->iov_len; - while (c < end) { - if (isprint(*c) && *c != '\\') { - putchar(*c); - } else { - putchar('\\'); - dumpbyte(*c); + for (const unsigned char *c = v->iov_base, *end = c + v->iov_len; c < end; ++c) { + if (mode & PRINT) { + if (isprint(*c) && *c != '\\') { + putchar(*c); + continue; + } else + putchar('\\'); } - c++; + putchar(digits[*c >> 4]); + putchar(digits[*c & 15]); } putchar('\n'); } -static void dumpval(MDBX_val *v) { - unsigned char *c, *end; - - putchar(' '); - c = v->iov_base; - end = c + v->iov_len; - while (c < end) - dumpbyte(*c++); - putchar('\n'); -} - bool quiet = false, rescue = false; const char *prog; static void error(const char *func, int rc) { @@ -185,12 +167,19 @@ static int dump_tbl(MDBX_txn *txn, MDBX_dbi dbi, char *name) { rc = MDBX_EINTR; break; } - if (mode & PRINT) { - text(&key); - text(&data); - } else { - dumpval(&key); - dumpval(&data); + dumpval(&key); + dumpval(&data); + if ((flags & MDBX_DUPSORT) && (mode & CONCISE)) { + while ((rc = mdbx_cursor_get(cursor, &key, &data, MDBX_NEXT_DUP)) == MDBX_SUCCESS) { + if (user_break) { + rc = MDBX_EINTR; + break; + } + putchar(' '); + dumpval(&data); + } + if (rc != MDBX_NOTFOUND) + break; } } printf("DATA=END\n"); @@ -206,10 +195,12 @@ static int dump_tbl(MDBX_txn *txn, MDBX_dbi dbi, char *name) { static void usage(void) { fprintf(stderr, "usage: %s " - "[-V] [-q] [-f file] [-l] [-p] [-r] [-a|-s table] [-u|U] " + "[-V] [-q] [-c] [-f file] [-l] [-p] [-r] [-a|-s table] [-u|U] " "dbpath\n" " -V\t\tprint version and exit\n" " -q\t\tbe quiet\n" + " -c\t\tconcise mode without repeating keys,\n" + " \t\tbut incompatible with Berkeley DB and LMDB\n" " -f\t\twrite to file instead of stdout\n" " -l\t\tlist tables and exit\n" " -p\t\tuse printable characters\n" @@ -268,6 +259,7 @@ int main(int argc, char *argv[]) { "s:" "V" "r" + "c" "q")) != EOF) { switch (i) { case 'V': @@ -298,6 +290,9 @@ int main(int argc, char *argv[]) { break; case 'n': break; + case 'c': + mode |= CONCISE; + break; case 'p': mode |= PRINT; break; diff --git a/src/tools/load.c b/src/tools/load.c index 0220ce22..6cb35c60 100644 --- a/src/tools/load.c +++ b/src/tools/load.c @@ -380,7 +380,16 @@ __hot static int readline(MDBX_val *out, MDBX_val *buf) { return badend(); } } - if (fgets(buf->iov_base, (int)buf->iov_len, stdin) == nullptr) + + /* modern concise mode, where space in second position mean the same (previously) value */ + c = fgetc(stdin); + if (c == EOF) + return errno ? errno : EOF; + if (c == ' ') + return (ungetc(c, stdin) == c) ? MDBX_SUCCESS : (errno ? errno : EOF); + + *(char *)buf->iov_base = c; + if (fgets((char *)buf->iov_base + 1, (int)buf->iov_len - 1, stdin) == nullptr) return errno ? errno : EOF; lineno++; @@ -721,8 +730,8 @@ int main(int argc, char *argv[]) { } int batch = 0; + MDBX_val key = {.iov_base = nullptr, .iov_len = 0}, data = {.iov_base = nullptr, .iov_len = 0}; while (err == MDBX_SUCCESS) { - MDBX_val key, data; err = readline(&key, &kbuf); if (err == EOF) break;