Tweaks for MDB_MULTIPLE

Terminate loop on intermediate failures, return count of written items,
document usage.
vmware
Howard Chu 12 years ago
parent fb674c1cf5
commit 589370d880
  1. 12
      libraries/liblmdb/lmdb.h
  2. 30
      libraries/liblmdb/mdb.c

@ -309,7 +309,7 @@ typedef void (MDB_rel_func)(MDB_val *item, void *oldptr, void *newptr, void *rel
#define MDB_APPEND 0x20000 #define MDB_APPEND 0x20000
/** Duplicate data is being appended, don't split full pages. */ /** Duplicate data is being appended, don't split full pages. */
#define MDB_APPENDDUP 0x40000 #define MDB_APPENDDUP 0x40000
/** Store multiple data items in one call. */ /** Store multiple data items in one call. Only for #MDB_DUPFIXED. */
#define MDB_MULTIPLE 0x80000 #define MDB_MULTIPLE 0x80000
/* @} */ /* @} */
@ -1210,6 +1210,16 @@ int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data,
* correct order. Loading unsorted keys with this flag will cause * correct order. Loading unsorted keys with this flag will cause
* data corruption. * data corruption.
* <li>#MDB_APPENDDUP - as above, but for sorted dup data. * <li>#MDB_APPENDDUP - as above, but for sorted dup data.
* <li>#MDB_MULTIPLE - store multiple contiguous data elements in a
* single request. This flag may only be specified if the database
* was opened with #MDB_DUPFIXED. The \b data argument must be an
* array of two MDB_vals. The mv_size of the first MDB_val must be
* the size of a single data element. The mv_data of the first MDB_val
* must point to the beginning of the array of contiguous data elements.
* The mv_size of the second MDB_val must be the count of the number
* of data elements to store. On return this field will be set to
* the count of the number of elements actually written. The mv_data
* of the second MDB_val is unused.
* </ul> * </ul>
* @return A non-zero error value on failure and 0 on success. Some possible * @return A non-zero error value on failure and 0 on success. Some possible
* errors are: * errors are:

@ -4969,7 +4969,7 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
MDB_page *fp; MDB_page *fp;
MDB_db dummy; MDB_db dummy;
int do_sub = 0, insert = 0; int do_sub = 0, insert = 0;
unsigned int mcount = 0; unsigned int mcount = 0, dcount;
size_t nsize; size_t nsize;
int rc, rc2; int rc, rc2;
MDB_pagebuf pbuf; MDB_pagebuf pbuf;
@ -4977,6 +4977,16 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
unsigned int nflags; unsigned int nflags;
DKBUF; DKBUF;
/* Check this first so counter will always be zero on any
* early failures.
*/
if (flags & MDB_MULTIPLE) {
dcount = data[1].mv_size;
data[1].mv_size = 0;
if (!F_ISSET(mc->mc_db->md_flags, MDB_DUPFIXED))
return EINVAL;
}
if (F_ISSET(mc->mc_txn->mt_flags, MDB_TXN_RDONLY)) if (F_ISSET(mc->mc_txn->mt_flags, MDB_TXN_RDONLY))
return EACCES; return EACCES;
@ -5340,8 +5350,8 @@ put_sub:
} }
} }
} }
/* we've done our job */ /* we've done our job */
dkey.mv_size = 0; dkey.mv_size = 0;
} }
if (flags & MDB_APPENDDUP) if (flags & MDB_APPENDDUP)
xflags |= MDB_APPEND; xflags |= MDB_APPEND;
@ -5357,12 +5367,16 @@ put_sub:
if (!rc && !(flags & MDB_CURRENT)) if (!rc && !(flags & MDB_CURRENT))
mc->mc_db->md_entries++; mc->mc_db->md_entries++;
if (flags & MDB_MULTIPLE) { if (flags & MDB_MULTIPLE) {
mcount++; if (!rc) {
if (mcount < data[1].mv_size) { mcount++;
data[0].mv_data = (char *)data[0].mv_data + data[0].mv_size; if (mcount < dcount) {
leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); data[0].mv_data = (char *)data[0].mv_data + data[0].mv_size;
goto more; leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
goto more;
}
} }
/* let caller know how many succeeded, if any */
data[1].mv_size = mcount;
} }
} }
done: done:

Loading…
Cancel
Save