mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-06 10:46:21 +08:00
Add cursor_prev
This commit is contained in:
parent
cc56ba04fb
commit
edf7869466
@ -362,6 +362,8 @@ static int mdb_set_key(MDB_node *node, MDB_val *key);
|
||||
static int mdb_sibling(MDB_cursor *cursor, int move_right);
|
||||
static int mdb_cursor_next(MDB_cursor *cursor,
|
||||
MDB_val *key, MDB_val *data);
|
||||
static int mdb_cursor_prev(MDB_cursor *cursor,
|
||||
MDB_val *key, MDB_val *data);
|
||||
static int mdb_cursor_set(MDB_cursor *cursor,
|
||||
MDB_val *key, MDB_val *data, int *exactp);
|
||||
static int mdb_cursor_first(MDB_cursor *cursor,
|
||||
@ -1753,6 +1755,46 @@ mdb_cursor_next(MDB_cursor *cursor, MDB_val *key, MDB_val *data)
|
||||
return mdb_set_key(leaf, key);
|
||||
}
|
||||
|
||||
static int
|
||||
mdb_cursor_prev(MDB_cursor *cursor, MDB_val *key, MDB_val *data)
|
||||
{
|
||||
MDB_ppage *top;
|
||||
MDB_page *mp;
|
||||
MDB_node *leaf;
|
||||
|
||||
assert(cursor->mc_initialized);
|
||||
|
||||
top = CURSOR_TOP(cursor);
|
||||
mp = top->mp_page;
|
||||
|
||||
DPRINTF("cursor_prev: top page is %lu in cursor %p", mp->mp_pgno, (void *) cursor);
|
||||
|
||||
if (top->mp_ki == 0) {
|
||||
DPRINTF("=====> move to prev sibling page");
|
||||
if (mdb_sibling(cursor, 0) != MDB_SUCCESS) {
|
||||
return ENOENT;
|
||||
}
|
||||
top = CURSOR_TOP(cursor);
|
||||
mp = top->mp_page;
|
||||
top->mp_ki = NUMKEYS(mp) - 1;
|
||||
DPRINTF("prev page is %lu, key index %u", mp->mp_pgno, top->mp_ki);
|
||||
} else
|
||||
top->mp_ki--;
|
||||
|
||||
cursor->mc_eof = 0;
|
||||
|
||||
DPRINTF("==> cursor points to page %lu with %u keys, key index %u",
|
||||
mp->mp_pgno, NUMKEYS(mp), top->mp_ki);
|
||||
|
||||
assert(IS_LEAF(mp));
|
||||
leaf = NODEPTR(mp, top->mp_ki);
|
||||
|
||||
if (data && mdb_read_data(cursor->mc_txn->mt_env, leaf, data) != MDB_SUCCESS)
|
||||
return MDB_FAIL;
|
||||
|
||||
return mdb_set_key(leaf, key);
|
||||
}
|
||||
|
||||
static int
|
||||
mdb_cursor_set(MDB_cursor *cursor, MDB_val *key, MDB_val *data,
|
||||
int *exactp)
|
||||
@ -1831,6 +1873,7 @@ static int
|
||||
mdb_cursor_last(MDB_cursor *cursor, MDB_val *key, MDB_val *data)
|
||||
{
|
||||
int rc;
|
||||
MDB_ppage *top;
|
||||
MDB_pageparent mpp;
|
||||
MDB_node *leaf;
|
||||
MDB_val lkey;
|
||||
@ -1845,7 +1888,10 @@ mdb_cursor_last(MDB_cursor *cursor, MDB_val *key, MDB_val *data)
|
||||
|
||||
leaf = NODEPTR(mpp.mp_page, NUMKEYS(mpp.mp_page)-1);
|
||||
cursor->mc_initialized = 1;
|
||||
cursor->mc_eof = 1;
|
||||
cursor->mc_eof = 0;
|
||||
|
||||
top = CURSOR_TOP(cursor);
|
||||
top->mp_ki = NUMKEYS(top->mp_page) - 1;
|
||||
|
||||
if (data && (rc = mdb_read_data(cursor->mc_txn->mt_env, leaf, data)) != MDB_SUCCESS)
|
||||
return rc;
|
||||
@ -1880,6 +1926,14 @@ mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data,
|
||||
else
|
||||
rc = mdb_cursor_next(cursor, key, data);
|
||||
break;
|
||||
case MDB_PREV:
|
||||
if (!cursor->mc_initialized || cursor->mc_eof) {
|
||||
while (CURSOR_TOP(cursor) != NULL)
|
||||
cursor_pop_page(cursor);
|
||||
rc = mdb_cursor_last(cursor, key, data);
|
||||
} else
|
||||
rc = mdb_cursor_prev(cursor, key, data);
|
||||
break;
|
||||
case MDB_FIRST:
|
||||
while (CURSOR_TOP(cursor) != NULL)
|
||||
cursor_pop_page(cursor);
|
||||
|
@ -58,7 +58,7 @@ typedef enum MDB_cursor_op { /* cursor operations */
|
||||
MDB_FIRST,
|
||||
MDB_NEXT,
|
||||
MDB_LAST,
|
||||
MDB_PREV, /* not implemented */
|
||||
MDB_PREV,
|
||||
MDB_GET_BOTH, /* position at key/data */
|
||||
MDB_GET_BOTH_RANGE /* position at key, nearest data */
|
||||
} MDB_cursor_op;
|
||||
|
@ -91,11 +91,18 @@ int main(int argc,char * argv[])
|
||||
rc = mdbenv_stat(env, &mst);
|
||||
rc = mdb_txn_begin(env, 1, &txn);
|
||||
rc = mdb_cursor_open(txn, dbi, &cursor);
|
||||
printf("Cursor next\n");
|
||||
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
||||
printf("key: %.*s, data: %.*s\n",
|
||||
(int) key.mv_size, (char *) key.mv_data,
|
||||
(int) data.mv_size, (char *) data.mv_data);
|
||||
}
|
||||
printf("Cursor prev\n");
|
||||
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_PREV)) == 0) {
|
||||
printf("key: %.*s, data: %.*s\n",
|
||||
(int) key.mv_size, (char *) key.mv_data,
|
||||
(int) data.mv_size, (char *) data.mv_data);
|
||||
}
|
||||
#if 0
|
||||
/* write ops aren't coordinated with cursors,
|
||||
* this stuff all breaks
|
||||
|
Loading…
Reference in New Issue
Block a user