mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-20 22:59:34 -05:00
More subdb stuff, add cursor_last()
This commit is contained in:
parent
9b4c689601
commit
1f3fdc811e
1 changed files with 64 additions and 14 deletions
|
|
@ -223,13 +223,12 @@ typedef struct MDB_db {
|
||||||
} MDB_db;
|
} MDB_db;
|
||||||
|
|
||||||
typedef struct MDB_dbx {
|
typedef struct MDB_dbx {
|
||||||
char *md_name;
|
MDB_val md_name;
|
||||||
MDB_cmp_func *md_cmp; /* user compare function */
|
MDB_cmp_func *md_cmp; /* user compare function */
|
||||||
MDB_cmp_func *md_dcmp; /* user dupsort function */
|
MDB_cmp_func *md_dcmp; /* user dupsort function */
|
||||||
MDB_rel_func *md_rel; /* user relocate function */
|
MDB_rel_func *md_rel; /* user relocate function */
|
||||||
MDB_db *md_db;
|
MDB_db *md_db;
|
||||||
MDB_page *md_page;
|
MDB_page *md_page;
|
||||||
unsigned int md_ki; /* cursor index on parent page */
|
|
||||||
} MDB_dbx;
|
} MDB_dbx;
|
||||||
|
|
||||||
struct MDB_txn {
|
struct MDB_txn {
|
||||||
|
|
@ -331,6 +330,8 @@ static int mdb_cursor_set(MDB_cursor *cursor,
|
||||||
MDB_val *key, MDB_val *data, int *exactp);
|
MDB_val *key, MDB_val *data, int *exactp);
|
||||||
static int mdb_cursor_first(MDB_cursor *cursor,
|
static int mdb_cursor_first(MDB_cursor *cursor,
|
||||||
MDB_val *key, MDB_val *data);
|
MDB_val *key, MDB_val *data);
|
||||||
|
static int mdb_cursor_last(MDB_cursor *cursor,
|
||||||
|
MDB_val *key, MDB_val *data);
|
||||||
|
|
||||||
static size_t mdb_leaf_size(MDB_env *env, MDB_val *key,
|
static size_t mdb_leaf_size(MDB_env *env, MDB_val *key,
|
||||||
MDB_val *data);
|
MDB_val *data);
|
||||||
|
|
@ -1372,7 +1373,10 @@ mdb_search_page_root(MDB_txn *txn, MDB_dbi dbi, MDB_val *key,
|
||||||
|
|
||||||
if (key == NULL) /* Initialize cursor to first page. */
|
if (key == NULL) /* Initialize cursor to first page. */
|
||||||
i = 0;
|
i = 0;
|
||||||
else {
|
else if (key->mv_size > MAXKEYSIZE && key->mv_data == NULL) {
|
||||||
|
/* cursor to last page */
|
||||||
|
i = NUMKEYS(mp)-1;
|
||||||
|
} else {
|
||||||
int exact;
|
int exact;
|
||||||
node = mdb_search_node(txn, dbi, mp, key, &exact, &i);
|
node = mdb_search_node(txn, dbi, mp, key, &exact, &i);
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
|
|
@ -1458,12 +1462,22 @@ mdb_search_page(MDB_txn *txn, MDB_dbi dbi, MDB_val *key,
|
||||||
|
|
||||||
DPRINTF("root page has flags 0x%X", mpp->mp_page->mp_flags);
|
DPRINTF("root page has flags 0x%X", mpp->mp_page->mp_flags);
|
||||||
|
|
||||||
if (modify && !F_ISSET(mpp->mp_page->mp_flags, P_DIRTY)) {
|
if (modify) {
|
||||||
mpp->mp_parent = NULL;
|
/* For sub-databases, update main root first */
|
||||||
mpp->mp_pi = 0;
|
if (dbi && !F_ISSET(txn->mt_dbxs[dbi].md_page->mp_flags, P_DIRTY)) {
|
||||||
if ((rc = mdb_touch(txn, mpp)))
|
MDB_pageparent mp2;
|
||||||
return rc;
|
rc = mdb_search_page(txn, 0, &txn->mt_dbxs[dbi].md_name,
|
||||||
txn->mt_dbxs[dbi].md_db->md_root = mpp->mp_page->mp_pgno;
|
NULL, 1, &mp2);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
if (!F_ISSET(mpp->mp_page->mp_flags, P_DIRTY)) {
|
||||||
|
mpp->mp_parent = NULL;
|
||||||
|
mpp->mp_pi = 0;
|
||||||
|
if ((rc = mdb_touch(txn, mpp)))
|
||||||
|
return rc;
|
||||||
|
txn->mt_dbxs[dbi].md_db->md_root = mpp->mp_page->mp_pgno;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mdb_search_page_root(txn, dbi, key, cursor, modify, mpp);
|
return mdb_search_page_root(txn, dbi, key, cursor, modify, mpp);
|
||||||
|
|
@ -1698,6 +1712,32 @@ mdb_cursor_first(MDB_cursor *cursor, MDB_val *key, MDB_val *data)
|
||||||
return mdb_set_key(leaf, key);
|
return mdb_set_key(leaf, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mdb_cursor_last(MDB_cursor *cursor, MDB_val *key, MDB_val *data)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
MDB_pageparent mpp;
|
||||||
|
MDB_node *leaf;
|
||||||
|
MDB_val lkey;
|
||||||
|
|
||||||
|
lkey.mv_size = MAXKEYSIZE+1;
|
||||||
|
lkey.mv_data = NULL;
|
||||||
|
|
||||||
|
rc = mdb_search_page(cursor->mc_txn, cursor->mc_dbi, &lkey, cursor, 0, &mpp);
|
||||||
|
if (rc != MDB_SUCCESS)
|
||||||
|
return rc;
|
||||||
|
assert(IS_LEAF(mpp.mp_page));
|
||||||
|
|
||||||
|
leaf = NODEPTR(mpp.mp_page, NUMKEYS(mpp.mp_page)-1);
|
||||||
|
cursor->mc_initialized = 1;
|
||||||
|
cursor->mc_eof = 1;
|
||||||
|
|
||||||
|
if (data && (rc = mdb_read_data(cursor->mc_txn->mt_env, leaf, data)) != MDB_SUCCESS)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
return mdb_set_key(leaf, key);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data,
|
mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data,
|
||||||
MDB_cursor_op op)
|
MDB_cursor_op op)
|
||||||
|
|
@ -1730,6 +1770,11 @@ mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data,
|
||||||
cursor_pop_page(cursor);
|
cursor_pop_page(cursor);
|
||||||
rc = mdb_cursor_first(cursor, key, data);
|
rc = mdb_cursor_first(cursor, key, data);
|
||||||
break;
|
break;
|
||||||
|
case MDB_LAST:
|
||||||
|
while (CURSOR_TOP(cursor) != NULL)
|
||||||
|
cursor_pop_page(cursor);
|
||||||
|
rc = mdb_cursor_last(cursor, key, data);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
DPRINTF("unhandled/unimplemented cursor operation %u", op);
|
DPRINTF("unhandled/unimplemented cursor operation %u", op);
|
||||||
rc = EINVAL;
|
rc = EINVAL;
|
||||||
|
|
@ -2561,6 +2606,7 @@ int mdb_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *dbi)
|
||||||
MDB_val key, data;
|
MDB_val key, data;
|
||||||
MDB_dbi i;
|
MDB_dbi i;
|
||||||
int rc;
|
int rc;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
/* main DB? */
|
/* main DB? */
|
||||||
if (!name) {
|
if (!name) {
|
||||||
|
|
@ -2569,15 +2615,17 @@ int mdb_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *dbi)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is the DB already open? */
|
/* Is the DB already open? */
|
||||||
|
len = strlen(name);
|
||||||
for (i=0; i<txn->mt_numdbs; i++) {
|
for (i=0; i<txn->mt_numdbs; i++) {
|
||||||
if (!strcmp(name, txn->mt_dbxs[i].md_name)) {
|
if (len == txn->mt_dbxs[i].md_name.mv_size &&
|
||||||
|
!strcmp(name, txn->mt_dbxs[i].md_name.mv_data)) {
|
||||||
*dbi = i;
|
*dbi = i;
|
||||||
return MDB_SUCCESS;
|
return MDB_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the DB info */
|
/* Find the DB info */
|
||||||
key.mv_size = strlen(name);
|
key.mv_size = len;
|
||||||
key.mv_data = (void *)name;
|
key.mv_data = (void *)name;
|
||||||
rc = mdb_get(txn, 0, &key, &data);
|
rc = mdb_get(txn, 0, &key, &data);
|
||||||
|
|
||||||
|
|
@ -2606,7 +2654,8 @@ int mdb_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *dbi)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
txn->mt_dbxs = p1;
|
txn->mt_dbxs = p1;
|
||||||
}
|
}
|
||||||
txn->mt_dbxs[txn->mt_numdbs].md_name = strdup(name);
|
txn->mt_dbxs[txn->mt_numdbs].md_name.mv_data = strdup(name);
|
||||||
|
txn->mt_dbxs[txn->mt_numdbs].md_name.mv_size = len;
|
||||||
txn->mt_dbxs[txn->mt_numdbs].md_cmp = NULL;
|
txn->mt_dbxs[txn->mt_numdbs].md_cmp = NULL;
|
||||||
txn->mt_dbxs[txn->mt_numdbs].md_dcmp = NULL;
|
txn->mt_dbxs[txn->mt_numdbs].md_dcmp = NULL;
|
||||||
txn->mt_dbxs[txn->mt_numdbs].md_rel = NULL;
|
txn->mt_dbxs[txn->mt_numdbs].md_rel = NULL;
|
||||||
|
|
@ -2637,6 +2686,7 @@ void mdb_close(MDB_txn *txn, MDB_dbi dbi)
|
||||||
{
|
{
|
||||||
if (dbi >= txn->mt_numdbs)
|
if (dbi >= txn->mt_numdbs)
|
||||||
return;
|
return;
|
||||||
free(txn->mt_dbxs[dbi].md_name);
|
free(txn->mt_dbxs[dbi].md_name.mv_data);
|
||||||
txn->mt_dbxs[dbi].md_name = NULL;
|
txn->mt_dbxs[dbi].md_name.mv_data = NULL;
|
||||||
|
txn->mt_dbxs[dbi].md_name.mv_size = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue