|
|
@ -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) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
if (txn->mt_dbxs[dbi].md_cmp) |
|
|
|
return txn->mt_dbxs[dbi].md_cmp(a, b); |
|
|
|
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: |
|
|
|