Merge pull request #2495

2540d162 Add -a append option to mdb_load (Howard Chu)
This commit is contained in:
Riccardo Spagni 2017-10-02 23:18:48 +04:00
commit 4a450042f7
No known key found for this signature in database
GPG Key ID: 55432DF31CCD4FCD
2 changed files with 47 additions and 6 deletions

View File

@ -37,6 +37,13 @@ option below.
.BR \-V .BR \-V
Write the library version number to the standard output, and exit. Write the library version number to the standard output, and exit.
.TP .TP
.BR \-a
Append all records in the order they appear in the input. The input is assumed to already be
in correctly sorted order and no sorting or checking for redundant values will be performed.
This option must be used to reload data that was produced by running
.B mdb_dump
on a database that uses custom compare functions.
.TP
.BR \-f \ file .BR \-f \ file
Read from the specified file instead of from the standard input. Read from the specified file instead of from the standard input.
.TP .TP

View File

@ -37,6 +37,7 @@ static int Eof;
static MDB_envinfo info; static MDB_envinfo info;
static MDB_val kbuf, dbuf; static MDB_val kbuf, dbuf;
static MDB_val k0buf;
#ifdef _WIN32 #ifdef _WIN32
#define Z "I" #define Z "I"
@ -285,10 +286,15 @@ badend:
static void usage(void) static void usage(void)
{ {
fprintf(stderr, "usage: %s [-V] [-f input] [-n] [-s name] [-N] [-T] dbpath\n", prog); fprintf(stderr, "usage: %s [-V] [-a] [-f input] [-n] [-s name] [-N] [-T] dbpath\n", prog);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
static int greater(const MDB_val *a, const MDB_val *b)
{
return 1;
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int i, rc; int i, rc;
@ -298,7 +304,8 @@ int main(int argc, char *argv[])
MDB_dbi dbi; MDB_dbi dbi;
char *envname; char *envname;
int envflags = 0, putflags = 0; int envflags = 0, putflags = 0;
int dohdr = 0; int dohdr = 0, append = 0;
MDB_val prevk;
prog = argv[0]; prog = argv[0];
@ -306,19 +313,23 @@ int main(int argc, char *argv[])
usage(); usage();
} }
/* -f: load file instead of stdin /* -a: append records in input order
* -f: load file instead of stdin
* -n: use NOSUBDIR flag on env_open * -n: use NOSUBDIR flag on env_open
* -s: load into named subDB * -s: load into named subDB
* -N: use NOOVERWRITE on puts * -N: use NOOVERWRITE on puts
* -T: read plaintext * -T: read plaintext
* -V: print version and exit * -V: print version and exit
*/ */
while ((i = getopt(argc, argv, "f:ns:NTV")) != EOF) { while ((i = getopt(argc, argv, "af:ns:NTV")) != EOF) {
switch(i) { switch(i) {
case 'V': case 'V':
printf("%s\n", MDB_VERSION_STRING); printf("%s\n", MDB_VERSION_STRING);
exit(0); exit(0);
break; break;
case 'a':
append = 1;
break;
case 'f': case 'f':
if (freopen(optarg, "r", stdin) == NULL) { if (freopen(optarg, "r", stdin) == NULL) {
fprintf(stderr, "%s: %s: reopen: %s\n", fprintf(stderr, "%s: %s: reopen: %s\n",
@ -377,12 +388,17 @@ int main(int argc, char *argv[])
} }
kbuf.mv_size = mdb_env_get_maxkeysize(env) * 2 + 2; kbuf.mv_size = mdb_env_get_maxkeysize(env) * 2 + 2;
kbuf.mv_data = malloc(kbuf.mv_size); kbuf.mv_data = malloc(kbuf.mv_size * 2);
k0buf.mv_size = kbuf.mv_size;
k0buf.mv_data = (char *)kbuf.mv_data + kbuf.mv_size;
prevk.mv_size = 0;
prevk.mv_data = k0buf.mv_data;
while(!Eof) { while(!Eof) {
MDB_val key, data; MDB_val key, data;
int batch = 0; int batch = 0;
flags = 0; flags = 0;
int appflag;
if (!dohdr) { if (!dohdr) {
dohdr = 1; dohdr = 1;
@ -400,6 +416,11 @@ int main(int argc, char *argv[])
fprintf(stderr, "mdb_open failed, error %d %s\n", rc, mdb_strerror(rc)); fprintf(stderr, "mdb_open failed, error %d %s\n", rc, mdb_strerror(rc));
goto txn_abort; goto txn_abort;
} }
if (append) {
mdb_set_compare(txn, dbi, greater);
if (flags & MDB_DUPSORT)
mdb_set_dupsort(txn, dbi, greater);
}
rc = mdb_cursor_open(txn, dbi, &mc); rc = mdb_cursor_open(txn, dbi, &mc);
if (rc) { if (rc) {
@ -418,7 +439,20 @@ int main(int argc, char *argv[])
goto txn_abort; goto txn_abort;
} }
rc = mdb_cursor_put(mc, &key, &data, putflags); if (append) {
appflag = MDB_APPEND;
if (flags & MDB_DUPSORT) {
if (prevk.mv_size == key.mv_size && !memcmp(prevk.mv_data, key.mv_data, key.mv_size))
appflag = MDB_APPENDDUP;
else {
memcpy(prevk.mv_data, key.mv_data, key.mv_size);
prevk.mv_size = key.mv_size;
}
}
} else {
appflag = 0;
}
rc = mdb_cursor_put(mc, &key, &data, putflags|appflag);
if (rc == MDB_KEYEXIST && putflags) if (rc == MDB_KEYEXIST && putflags)
continue; continue;
if (rc) { if (rc) {