Sorted dups basically completed, needs testing

vmware
Howard Chu 13 years ago
parent f586e57742
commit 314ac28938
  1. 70
      libraries/libmdb/mdb.c
  2. 10
      libraries/libmdb/mdb.h
  3. 2
      libraries/libmdb/mtest.c

@ -2067,33 +2067,6 @@ mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data,
return rc; return rc;
} }
/* Delete the item the cursor points to
* flags is currently unused.
*/
int
mdb_cursor_del(MDB_cursor *cursor, uint32_t flags)
{
int rc;
flags = 0;
return rc;
}
int mdb_cursor_put(MDB_cursor *cursor, MDB_val *key, MDB_val *data,
MDB_cursor_op op)
{
int rc;
assert(cursor);
switch (op) {
case MDB_CURRENT:
case MDB_NODUPDATA:
case MDB_SET:
}
return rc;
}
/* Allocate a page and initialize it /* Allocate a page and initialize it
*/ */
static MDB_dpage * static MDB_dpage *
@ -2679,7 +2652,8 @@ mdb_del0(MDB_txn *txn, MDB_dbi dbi, unsigned int ki, MDB_pageparent *mpp, MDB_no
int int
mdb_del(MDB_txn *txn, MDB_dbi dbi, mdb_del(MDB_txn *txn, MDB_dbi dbi,
MDB_val *key, MDB_val *data) MDB_val *key, MDB_val *data,
unsigned int flags)
{ {
int rc, exact; int rc, exact;
unsigned int ki; unsigned int ki;
@ -2715,26 +2689,34 @@ mdb_del(MDB_txn *txn, MDB_dbi dbi,
return rc; return rc;
if (F_ISSET(txn->mt_dbs[dbi].md_flags, MDB_DUPSORT)) { if (F_ISSET(txn->mt_dbs[dbi].md_flags, MDB_DUPSORT)) {
/* add all the child DB's pages to the free list */
MDB_cursor mc;
MDB_xcursor mx; MDB_xcursor mx;
MDB_pageparent mp2; MDB_pageparent mp2;
mdb_xcursor_init0(txn, dbi, &mx); mdb_xcursor_init0(txn, dbi, &mx);
mdb_xcursor_init1(txn, dbi, &mx, NODEDATA(leaf)); mdb_xcursor_init1(txn, dbi, &mx, NODEDATA(leaf));
SLIST_INIT(&mc.mc_stack); if (flags == MDB_DEL_DUP) {
mc.mc_dbi = mx.mx_txn.mt_numdbs-1; rc = mdb_del(&mx.mx_txn, mx.mx_cursor.mc_dbi, data, NULL, 0);
mc.mc_txn = &mx.mx_txn; if (rc != MDB_SUCCESS)
rc = mdb_search_page(&mx.mx_txn, mx.mx_txn.mt_numdbs - 1, NULL, &mc, 0, &mp2); return rc;
mdb_xcursor_fini(txn, dbi, &mx);
/* If sub-DB still has entries, we're done */
if (mx.mx_txn.mt_dbs[mx.mx_cursor.mc_dbi].md_root != P_INVALID)
return rc;
/* otherwise fall thru and delete the sub-db */
} else {
/* add all the child DB's pages to the free list */
rc = mdb_search_page(&mx.mx_txn, mx.mx_cursor.mc_dbi,
NULL, &mx.mx_cursor, 0, &mp2);
if (rc == MDB_SUCCESS) { if (rc == MDB_SUCCESS) {
MDB_ppage *top, *parent; MDB_ppage *top, *parent;
MDB_node *ni; MDB_node *ni;
unsigned int i; unsigned int i;
cursor_pop_page(&mc); cursor_pop_page(&mx.mx_cursor);
top = CURSOR_TOP(&mc); top = CURSOR_TOP(&mx.mx_cursor);
if (top != NULL) {
parent = SLIST_NEXT(top, mp_entry); parent = SLIST_NEXT(top, mp_entry);
do { while (parent != NULL) {
for (i=0; i<NUMKEYS(top->mp_page); i++) { for (i=0; i<NUMKEYS(top->mp_page); i++) {
ni = NODEPTR(top->mp_page, i); ni = NODEPTR(top->mp_page, i);
mdb_idl_insert(txn->mt_free_pgs, ni->mn_pgno); mdb_idl_insert(txn->mt_free_pgs, ni->mn_pgno);
@ -2742,16 +2724,18 @@ mdb_del(MDB_txn *txn, MDB_dbi dbi,
if (parent) { if (parent) {
parent->mp_ki++; parent->mp_ki++;
if (parent->mp_ki >= NUMKEYS(parent->mp_page)) { if (parent->mp_ki >= NUMKEYS(parent->mp_page)) {
cursor_pop_page(&mc); cursor_pop_page(&mx.mx_cursor);
top = CURSOR_TOP(&mc); top = CURSOR_TOP(&mx.mx_cursor);
parent = SLIST_NEXT(top, mp_entry); parent = SLIST_NEXT(top, mp_entry);
} else { } else {
ni = NODEPTR(parent->mp_page, parent->mp_ki); ni = NODEPTR(parent->mp_page, parent->mp_ki);
top->mp_page = mdb_get_page(mc.mc_txn, ni->mn_pgno); top->mp_page = mdb_get_page(&mx.mx_txn, ni->mn_pgno);
}
} }
} }
} }
mdb_idl_insert(txn->mt_free_pgs, mx.mx_txn.mt_dbs[mc.mc_dbi].md_root); mdb_idl_insert(txn->mt_free_pgs, mx.mx_txn.mt_dbs[mx.mx_cursor.mc_dbi].md_root);
}
} }
} }
@ -2936,10 +2920,6 @@ mdb_put(MDB_txn *txn, MDB_dbi dbi,
return EINVAL; return EINVAL;
} }
if (txn->mt_env->me_txn != txn) {
return EINVAL;
}
if (key->mv_size == 0 || key->mv_size > MAXKEYSIZE) { if (key->mv_size == 0 || key->mv_size > MAXKEYSIZE) {
return EINVAL; return EINVAL;
} }

@ -50,8 +50,11 @@ typedef struct MDB_val {
typedef int (MDB_cmp_func)(const MDB_val *a, const MDB_val *b); typedef int (MDB_cmp_func)(const MDB_val *a, const MDB_val *b);
typedef void (MDB_rel_func)(void *ptr, void *oldptr); typedef void (MDB_rel_func)(void *ptr, void *oldptr);
#define MDB_NOOVERWRITE 1
#define MDB_NODUPDATA 2
#define MDB_DEL_DUP 3
typedef enum MDB_cursor_op { /* cursor operations */ typedef enum MDB_cursor_op { /* cursor operations */
MDB_CURRENT,
MDB_FIRST, MDB_FIRST,
MDB_GET_BOTH, /* position at key/data */ MDB_GET_BOTH, /* position at key/data */
MDB_GET_BOTH_RANGE, /* position at key, nearest data */ MDB_GET_BOTH_RANGE, /* position at key, nearest data */
@ -59,8 +62,6 @@ typedef enum MDB_cursor_op { /* cursor operations */
MDB_NEXT, MDB_NEXT,
MDB_NEXT_DUP, MDB_NEXT_DUP,
MDB_NEXT_NODUP, MDB_NEXT_NODUP,
MDB_NODUPDATA,
MDB_NOOVERWRITE,
MDB_PREV, MDB_PREV,
MDB_PREV_DUP, MDB_PREV_DUP,
MDB_PREV_NODUP, MDB_PREV_NODUP,
@ -123,7 +124,8 @@ int mdb_set_relfunc(MDB_txn *txn, MDB_dbi dbi, MDB_rel_func *rel);
int mdb_get(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data); int mdb_get(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data);
int mdb_put(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data, int mdb_put(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data,
unsigned int flags); unsigned int flags);
int mdb_del(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data); int mdb_del(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data,
unsigned int flags);
int mdb_cursor_open(MDB_txn *txn, MDB_dbi dbi, MDB_cursor **cursor); int mdb_cursor_open(MDB_txn *txn, MDB_dbi dbi, MDB_cursor **cursor);
void mdb_cursor_close(MDB_cursor *cursor); void mdb_cursor_close(MDB_cursor *cursor);

@ -77,7 +77,7 @@ int main(int argc,char * argv[])
txn=NULL; txn=NULL;
rc = mdb_txn_begin(env, 0, &txn); rc = mdb_txn_begin(env, 0, &txn);
sprintf(sval, "%03x ", values[i]); sprintf(sval, "%03x ", values[i]);
rc = mdb_del(txn, dbi, &key, NULL); rc = mdb_del(txn, dbi, &key, NULL, 0);
if (rc) { if (rc) {
j--; j--;
mdb_txn_abort(txn); mdb_txn_abort(txn);

Loading…
Cancel
Save