aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRiccardo Spagni <ric@spagni.net>2017-10-02 23:18:48 +0400
committerRiccardo Spagni <ric@spagni.net>2017-10-02 23:18:48 +0400
commit4a450042f79b2bd67070113294e6158b96b38582 (patch)
tree8cbf77a117e3f1fb4be0c932bbce7ebe46eae606
parentMerge pull request #2491 (diff)
parentAdd -a append option to mdb_load (diff)
downloadmonero-4a450042f79b2bd67070113294e6158b96b38582.tar.xz
Merge pull request #2495
2540d162 Add -a append option to mdb_load (Howard Chu)
-rw-r--r--external/db_drivers/liblmdb/mdb_load.17
-rw-r--r--external/db_drivers/liblmdb/mdb_load.c46
2 files changed, 47 insertions, 6 deletions
diff --git a/external/db_drivers/liblmdb/mdb_load.1 b/external/db_drivers/liblmdb/mdb_load.1
index 712ed0540..ede3702d9 100644
--- a/external/db_drivers/liblmdb/mdb_load.1
+++ b/external/db_drivers/liblmdb/mdb_load.1
@@ -37,6 +37,13 @@ option below.
.BR \-V
Write the library version number to the standard output, and exit.
.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
Read from the specified file instead of from the standard input.
.TP
diff --git a/external/db_drivers/liblmdb/mdb_load.c b/external/db_drivers/liblmdb/mdb_load.c
index d1fda4bf5..797c2f979 100644
--- a/external/db_drivers/liblmdb/mdb_load.c
+++ b/external/db_drivers/liblmdb/mdb_load.c
@@ -37,6 +37,7 @@ static int Eof;
static MDB_envinfo info;
static MDB_val kbuf, dbuf;
+static MDB_val k0buf;
#ifdef _WIN32
#define Z "I"
@@ -285,10 +286,15 @@ badend:
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);
}
+static int greater(const MDB_val *a, const MDB_val *b)
+{
+ return 1;
+}
+
int main(int argc, char *argv[])
{
int i, rc;
@@ -298,7 +304,8 @@ int main(int argc, char *argv[])
MDB_dbi dbi;
char *envname;
int envflags = 0, putflags = 0;
- int dohdr = 0;
+ int dohdr = 0, append = 0;
+ MDB_val prevk;
prog = argv[0];
@@ -306,19 +313,23 @@ int main(int argc, char *argv[])
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
* -s: load into named subDB
* -N: use NOOVERWRITE on puts
* -T: read plaintext
* -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) {
case 'V':
printf("%s\n", MDB_VERSION_STRING);
exit(0);
break;
+ case 'a':
+ append = 1;
+ break;
case 'f':
if (freopen(optarg, "r", stdin) == NULL) {
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_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) {
MDB_val key, data;
int batch = 0;
flags = 0;
+ int appflag;
if (!dohdr) {
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));
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);
if (rc) {
@@ -418,7 +439,20 @@ int main(int argc, char *argv[])
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)
continue;
if (rc) {