Fix cursor_set for dups

Also make sure dups are counted in md_entries
vmware
Howard Chu 13 years ago
parent edf9d8e51b
commit 8f77043372
  1. 43
      libraries/libmdb/mdb.c

@ -478,20 +478,26 @@ mdb_strerror(int err)
int int
mdb_cmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b) mdb_cmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b)
{ {
return txn->mt_dbxs[dbi].md_cmp(a, b); if (txn->mt_dbxs[dbi].md_cmp)
} return txn->mt_dbxs[dbi].md_cmp(a, b);
static int
_mdb_cmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *key1, const MDB_val *key2)
{
if (txn->mt_dbs[dbi].md_flags & (MDB_REVERSEKEY if (txn->mt_dbs[dbi].md_flags & (MDB_REVERSEKEY
#if __BYTE_ORDER == __LITTLE_ENDIAN #if __BYTE_ORDER == __LITTLE_ENDIAN
|MDB_INTEGERKEY |MDB_INTEGERKEY
#endif #endif
)) ))
return memnrcmp(key1->mv_data, key1->mv_size, key2->mv_data, key2->mv_size); return memnrcmp(a->mv_data, a->mv_size, b->mv_data, b->mv_size);
else else
return memncmp((char *)key1->mv_data, key1->mv_size, key2->mv_data, key2->mv_size); return memncmp((char *)a->mv_data, a->mv_size, b->mv_data, b->mv_size);
}
int
mdb_dcmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b)
{
if (txn->mt_dbxs[dbi].md_dcmp)
return txn->mt_dbxs[dbi].md_dcmp(a, b);
return memncmp((char *)a->mv_data, a->mv_size, b->mv_data, b->mv_size);
} }
/* Allocate new page(s) for writing */ /* Allocate new page(s) for writing */
@ -1496,10 +1502,7 @@ mdb_search_node(MDB_txn *txn, MDB_dbi dbi, MDB_page *mp, MDB_val *key,
nodekey.mv_size = node->mn_ksize; nodekey.mv_size = node->mn_ksize;
nodekey.mv_data = NODEKEY(node); nodekey.mv_data = NODEKEY(node);
if (txn->mt_dbxs[dbi].md_cmp) rc = mdb_cmp(txn, dbi, key, &nodekey);
rc = txn->mt_dbxs[dbi].md_cmp(key, &nodekey);
else
rc = _mdb_cmp(txn, dbi, key, &nodekey);
if (IS_LEAF(mp)) if (IS_LEAF(mp))
DPRINTF("found leaf index %u [%.*s], rc = %i", DPRINTF("found leaf index %u [%.*s], rc = %i",
@ -2027,6 +2030,16 @@ mdb_cursor_set(MDB_cursor *cursor, MDB_val *key, MDB_val *data,
if (rc != MDB_SUCCESS) if (rc != MDB_SUCCESS)
return rc; return rc;
} }
} else if (op == MDB_GET_BOTH || op == MDB_GET_BOTH_RANGE) {
MDB_val d2;
if ((rc = mdb_read_data(cursor->mc_txn, leaf, &d2)) != MDB_SUCCESS)
return rc;
rc = mdb_dcmp(cursor->mc_txn, cursor->mc_dbi, data, &d2);
if (rc) {
if (op == MDB_GET_BOTH || rc > 0)
return MDB_NOTFOUND;
}
} else { } else {
if ((rc = mdb_read_data(cursor->mc_txn, leaf, data)) != MDB_SUCCESS) if ((rc = mdb_read_data(cursor->mc_txn, leaf, data)) != MDB_SUCCESS)
return rc; return rc;
@ -2128,7 +2141,7 @@ mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data,
switch (op) { switch (op) {
case MDB_GET_BOTH: case MDB_GET_BOTH:
case MDB_GET_BOTH_RANGE: case MDB_GET_BOTH_RANGE:
if (data == NULL) { if (data == NULL || cursor->mc_xcursor == NULL) {
rc = EINVAL; rc = EINVAL;
break; break;
} }
@ -2137,7 +2150,7 @@ mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data,
case MDB_SET_RANGE: case MDB_SET_RANGE:
if (key == NULL || key->mv_size == 0 || key->mv_size > MAXKEYSIZE) { if (key == NULL || key->mv_size == 0 || key->mv_size > MAXKEYSIZE) {
rc = EINVAL; rc = EINVAL;
} else if (op != MDB_SET_RANGE) } else if (op == MDB_SET_RANGE)
rc = mdb_cursor_set(cursor, key, data, op, NULL); rc = mdb_cursor_set(cursor, key, data, op, NULL);
else else
rc = mdb_cursor_set(cursor, key, data, op, &exact); rc = mdb_cursor_set(cursor, key, data, op, &exact);
@ -2834,6 +2847,7 @@ mdb_del(MDB_txn *txn, MDB_dbi dbi,
if (mx.mx_txn.mt_dbs[mx.mx_cursor.mc_dbi].md_root != P_INVALID) { if (mx.mx_txn.mt_dbs[mx.mx_cursor.mc_dbi].md_root != P_INVALID) {
memcpy(NODEDATA(leaf), &mx.mx_txn.mt_dbs[mx.mx_cursor.mc_dbi], memcpy(NODEDATA(leaf), &mx.mx_txn.mt_dbs[mx.mx_cursor.mc_dbi],
sizeof(MDB_db)); sizeof(MDB_db));
txn->mt_dbs[dbi].md_entries--;
return rc; return rc;
} }
/* otherwise fall thru and delete the sub-DB */ /* otherwise fall thru and delete the sub-DB */
@ -3125,8 +3139,6 @@ new_sub:
if (rc != MDB_SUCCESS) if (rc != MDB_SUCCESS)
txn->mt_flags |= MDB_TXN_ERROR; txn->mt_flags |= MDB_TXN_ERROR;
else { else {
txn->mt_dbs[dbi].md_entries++;
/* Remember if we just added a subdatabase */ /* Remember if we just added a subdatabase */
if (flags & F_SUBDATA) { if (flags & F_SUBDATA) {
leaf = NODEPTR(mpp.mp_page, ki); leaf = NODEPTR(mpp.mp_page, ki);
@ -3161,6 +3173,7 @@ put_sub:
memcpy(NODEDATA(leaf), &mx.mx_txn.mt_dbs[mx.mx_cursor.mc_dbi], memcpy(NODEDATA(leaf), &mx.mx_txn.mt_dbs[mx.mx_cursor.mc_dbi],
sizeof(MDB_db)); sizeof(MDB_db));
} }
txn->mt_dbs[dbi].md_entries++;
} }
done: done:

Loading…
Cancel
Save