put(MDB_MULTIPLE): Skip existing item cleanly.

Don't set dkey.mv_size if mdb won't clear it before next iteration.
vmware
Hallvard Furuseth 11 years ago
parent fcb0d09598
commit c0858e6d93
  1. 11
      libraries/liblmdb/mdb.c

@ -5824,9 +5824,8 @@ more:
if (flags == MDB_CURRENT) if (flags == MDB_CURRENT)
goto current; goto current;
dkey = olddata;
#if UINT_MAX < SIZE_MAX #if UINT_MAX < SIZE_MAX
if (mc->mc_dbx->md_dcmp == mdb_cmp_int && dkey.mv_size == sizeof(size_t)) if (mc->mc_dbx->md_dcmp == mdb_cmp_int && olddata.mv_size == sizeof(size_t))
#ifdef MISALIGNED_OK #ifdef MISALIGNED_OK
mc->mc_dbx->md_dcmp = mdb_cmp_long; mc->mc_dbx->md_dcmp = mdb_cmp_long;
#else #else
@ -5834,7 +5833,7 @@ more:
#endif #endif
#endif #endif
/* if data matches, skip it */ /* if data matches, skip it */
if (!mc->mc_dbx->md_dcmp(data, &dkey)) { if (!mc->mc_dbx->md_dcmp(data, &olddata)) {
if (flags & MDB_NODUPDATA) if (flags & MDB_NODUPDATA)
rc = MDB_KEYEXIST; rc = MDB_KEYEXIST;
else if (flags & MDB_MULTIPLE) else if (flags & MDB_MULTIPLE)
@ -5844,9 +5843,11 @@ more:
return rc; return rc;
} }
/* Back up original data item */
dkey.mv_size = olddata.mv_size;
dkey.mv_data = memcpy(dbuf, olddata.mv_data, olddata.mv_size);
/* create a fake page for the dup items */ /* create a fake page for the dup items */
memcpy(dbuf, dkey.mv_data, dkey.mv_size);
dkey.mv_data = dbuf;
fp->mp_flags = P_LEAF|P_DIRTY|P_SUBP; fp->mp_flags = P_LEAF|P_DIRTY|P_SUBP;
fp->mp_lower = PAGEHDRSZ; fp->mp_lower = PAGEHDRSZ;
xdata.mv_size = PAGEHDRSZ + dkey.mv_size + data->mv_size; xdata.mv_size = PAGEHDRSZ + dkey.mv_size + data->mv_size;

Loading…
Cancel
Save