*/
int
mdb_dup_compare(
- DB *db,
- const DBT *usrkey,
- const DBT *curkey
+ const MDB_val *usrkey,
+ const MDB_val *curkey
)
{
diskNode *un, *cn;
- int rc;
+ int rc, nrlen;
- un = (diskNode *)usrkey->data;
- cn = (diskNode *)curkey->data;
+ un = (diskNode *)usrkey->mv_data;
+ cn = (diskNode *)curkey->mv_data;
/* data is not aligned, cannot compare directly */
rc = un->nrdnlen[0] - cn->nrdnlen[0];
rc = un->nrdnlen[1] - cn->nrdnlen[1];
if ( rc ) return rc;
- return strcmp( un->nrdn, cn->nrdn );
+ nrlen = (un->nrdnlen[0] << 8) | un->nrdnlen[1];
+ return strncmp( un->nrdn, cn->nrdn, nrlen );
}
+#if 0
/* This function constructs a full DN for a given entry.
*/
int mdb_fix_dn(
return 0;
}
+#endif
/* We add two elements to the DN2ID database - a data item under the parent's
* entryID containing the child's RDN and entryID, and an item under the
int
mdb_dn2id_add(
Operation *op,
- DB_TXN *txn,
- EntryInfo *eip,
+ MDB_txn *txn,
+ ID pid,
Entry *e )
{
struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
- DB *db = mdb->bi_dn2id->bdi_db;
- DBT key, data;
+ MDB_dbi dbi = mdb->mi_dn2id;
+ MDB_val key, data;
ID nid;
int rc, rlen, nrlen;
diskNode *d;
*ptr++ = '\0';
ptr = lutil_strncopy( ptr, e->e_name.bv_val, rlen );
*ptr++ = '\0';
- MDB_ID2DISK( e->e_id, ptr );
+ memcpy( ptr, &e->e_id, sizeof( ID ));
- DBTzero(&key);
- DBTzero(&data);
- key.size = sizeof(ID);
- key.flags = DB_DBT_USERMEM;
- MDB_ID2DISK( eip->bei_id, &nid );
+ key.mv_size = sizeof(ID);
+ key.mv_data = &nid;
- key.data = &nid;
+ nid = pid;
/* Need to make dummy root node once. Subsequent attempts
* will fail harmlessly.
*/
- if ( eip->bei_id == 0 ) {
+ if ( pid == 0 ) {
diskNode dummy = {{0, 0}, "", "", ""};
- data.data = &dummy;
- data.size = sizeof(diskNode);
- data.flags = DB_DBT_USERMEM;
+ data.mv_data = &dummy;
+ data.mv_size = sizeof(diskNode);
- db->put( db, txn, &key, &data, DB_NODUPDATA );
+ mdb_put( txn, dbi, &key, &data, MDB_NODUPDATA );
}
- data.data = d;
- data.size = sizeof(diskNode) + rlen + nrlen;
- data.flags = DB_DBT_USERMEM;
+ data.mv_data = d;
+ data.mv_size = sizeof(diskNode) + rlen + nrlen;
- rc = db->put( db, txn, &key, &data, DB_NODUPDATA );
+ rc = mdb_put( txn, dbi, &key, &data, MDB_NODUPDATA );
if (rc == 0) {
- MDB_ID2DISK( e->e_id, &nid );
- MDB_ID2DISK( eip->bei_id, ptr );
+ nid = e->e_id;
+ memcpy( ptr, &pid, sizeof( ID ));
d->nrdnlen[0] ^= 0x80;
- rc = db->put( db, txn, &key, &data, DB_NODUPDATA );
- }
-
- /* Update all parents' IDL cache entries */
- if ( rc == 0 && mdb->bi_idl_cache_size ) {
- ID tmp[2];
- char *ptr = ((char *)&tmp[1])-1;
- key.data = ptr;
- key.size = sizeof(ID)+1;
- tmp[1] = eip->bei_id;
- *ptr = DN_ONE_PREFIX;
- mdb_idl_cache_add_id( mdb, db, &key, e->e_id );
- if ( eip->bei_parent ) {
- *ptr = DN_SUBTREE_PREFIX;
- for (; eip && eip->bei_parent->bei_id; eip = eip->bei_parent) {
- tmp[1] = eip->bei_id;
- mdb_idl_cache_add_id( mdb, db, &key, e->e_id );
- }
- /* Handle DB with empty suffix */
- if ( !op->o_bd->be_suffix[0].bv_len && eip ) {
- tmp[1] = eip->bei_id;
- mdb_idl_cache_add_id( mdb, db, &key, e->e_id );
- }
- }
+ rc = mdb_put( txn, dbi, &key, &data, MDB_NODUPDATA );
}
op->o_tmpfree( d, op->o_tmpmemctx );
int
mdb_dn2id_delete(
Operation *op,
- DB_TXN *txn,
- EntryInfo *eip,
+ MDB_txn *txn,
+ ID pid,
Entry *e )
{
struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
- DB *db = mdb->bi_dn2id->bdi_db;
- DBT key, data;
- DBC *cursor;
+ MDB_dbi dbi = mdb->mi_dn2id;
+ MDB_val key, data;
diskNode *d;
- int rc;
+ int rc, nrlen;
ID nid;
- unsigned char dlen[2];
Debug( LDAP_DEBUG_TRACE, "=> mdb_dn2id_delete 0x%lx: \"%s\"\n",
e->e_id, e->e_ndn, 0 );
- DBTzero(&key);
- key.size = sizeof(ID);
- key.ulen = key.size;
- key.flags = DB_DBT_USERMEM;
- MDB_ID2DISK( eip->bei_id, &nid );
+ key.mv_size = sizeof(ID);
+ key.mv_data = &nid;
+ nid = pid;
- DBTzero(&data);
- data.size = sizeof(diskNode) + BEI(e)->bei_nrdn.bv_len - sizeof(ID) - 1;
- data.ulen = data.size;
- data.dlen = data.size;
- data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
-
- key.data = &nid;
-
- d = op->o_tmpalloc( data.size, op->o_tmpmemctx );
- d->nrdnlen[1] = BEI(e)->bei_nrdn.bv_len & 0xff;
- d->nrdnlen[0] = (BEI(e)->bei_nrdn.bv_len >> 8) | 0x80;
- dlen[0] = d->nrdnlen[0];
- dlen[1] = d->nrdnlen[1];
- memcpy( d->nrdn, BEI(e)->bei_nrdn.bv_val, BEI(e)->bei_nrdn.bv_len+1 );
- data.data = d;
+ nrlen = dn_rdnlen( op->o_bd, &e->e_nname );
+ data.mv_size = sizeof(diskNode) + nrlen - sizeof(ID) - 1;
- rc = db->cursor( db, txn, &cursor, mdb->bi_db_opflags );
- if ( rc ) goto func_leave;
+ d = op->o_tmpalloc( data.mv_size, op->o_tmpmemctx );
+ d->nrdnlen[1] = nrlen & 0xff;
+ d->nrdnlen[0] = (nrlen >> 8) | 0x80;
+ memcpy( d->nrdn, e->e_nname.bv_val, nrlen );
+ data.mv_data = d;
/* Delete our ID from the parent's list */
- rc = cursor->c_get( cursor, &key, &data, DB_GET_BOTH_RANGE );
- if ( rc == 0 ) {
- if ( dlen[1] == d->nrdnlen[1] && dlen[0] == d->nrdnlen[0] &&
- !strcmp( d->nrdn, BEI(e)->bei_nrdn.bv_val ))
- rc = cursor->c_del( cursor, 0 );
- else
- rc = DB_NOTFOUND;
- }
+ rc = mdb_del( txn, dbi, &key, &data, MDB_DEL_DUP );
/* Delete our ID from the tree. With sorted duplicates, this
* will leave any child nodes still hanging around. This is OK
* for modrdn, which will add our info back in later.
*/
if ( rc == 0 ) {
- MDB_ID2DISK( e->e_id, &nid );
- rc = cursor->c_get( cursor, &key, &data, DB_SET );
- if ( rc == 0 )
- rc = cursor->c_del( cursor, 0 );
+ nid = e->e_id;
+ d->nrdnlen[0] ^= 0x80;
+ rc = mdb_del( txn, dbi, &key, &data, MDB_DEL_DUP );
}
- cursor->c_close( cursor );
-func_leave:
op->o_tmpfree( d, op->o_tmpmemctx );
- /* Delete IDL cache entries */
- if ( rc == 0 && mdb->bi_idl_cache_size ) {
- ID tmp[2];
- char *ptr = ((char *)&tmp[1])-1;
- key.data = ptr;
- key.size = sizeof(ID)+1;
- tmp[1] = eip->bei_id;
- *ptr = DN_ONE_PREFIX;
- mdb_idl_cache_del_id( mdb, db, &key, e->e_id );
- if ( eip ->bei_parent ) {
- *ptr = DN_SUBTREE_PREFIX;
- for (; eip && eip->bei_parent->bei_id; eip = eip->bei_parent) {
- tmp[1] = eip->bei_id;
- mdb_idl_cache_del_id( mdb, db, &key, e->e_id );
- }
- /* Handle DB with empty suffix */
- if ( !op->o_bd->be_suffix[0].bv_len && eip ) {
- tmp[1] = eip->bei_id;
- mdb_idl_cache_del_id( mdb, db, &key, e->e_id );
- }
- }
- }
Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2id_delete 0x%lx: %d\n", e->e_id, rc, 0 );
return rc;
}
-
+/* return last found ID in *id if no match */
int
mdb_dn2id(
Operation *op,
+ MDB_txn *txn,
struct berval *in,
- EntryInfo *ei,
- DB_TXN *txn,
- DBC **cursor )
+ ID *id,
+ struct berval *matched )
{
struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
- DB *db = mdb->bi_dn2id->bdi_db;
- DBT key, data;
+ MDB_cursor *cursor;
+ MDB_dbi dbi = mdb->mi_dn2id;
+ MDB_val key, data;
int rc = 0, nrlen;
diskNode *d;
char *ptr;
- unsigned char dlen[2];
- ID idp, parentID;
+ char dn[SLAP_LDAPDN_MAXLEN];
+ ID pid, nid;
+ struct berval tmp;
Debug( LDAP_DEBUG_TRACE, "=> mdb_dn2id(\"%s\")\n", in->bv_val, 0, 0 );
- nrlen = dn_rdnlen( op->o_bd, in );
- if (!nrlen) nrlen = in->bv_len;
+ if ( !in->bv_len ) {
+ *id = 0;
+ nid = 0;
+ goto done;
+ }
- DBTzero(&key);
- key.size = sizeof(ID);
- key.data = &idp;
- key.ulen = sizeof(ID);
- key.flags = DB_DBT_USERMEM;
- parentID = ( ei->bei_parent != NULL ) ? ei->bei_parent->bei_id : 0;
- MDB_ID2DISK( parentID, &idp );
+ tmp = *in;
- DBTzero(&data);
- data.size = sizeof(diskNode) + nrlen - sizeof(ID) - 1;
- data.ulen = data.size * 3;
- data.dlen = data.ulen;
- data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
+ if ( matched ) {
+ matched->bv_val = dn + sizeof(dn) - 1;
+ matched->bv_len = 0;
+ *matched->bv_val-- = '\0';
+ }
- rc = db->cursor( db, txn, cursor, mdb->bi_db_opflags );
- if ( rc ) return rc;
+ nrlen = tmp.bv_len - op->o_bd->be_nsuffix[0].bv_len;
+ tmp.bv_val += nrlen;
+ tmp.bv_len = op->o_bd->be_nsuffix[0].bv_len;
+ nid = 0;
+ key.mv_size = sizeof(ID);
- d = op->o_tmpalloc( data.size * 3, op->o_tmpmemctx );
- d->nrdnlen[1] = nrlen & 0xff;
- d->nrdnlen[0] = (nrlen >> 8) | 0x80;
- dlen[0] = d->nrdnlen[0];
- dlen[1] = d->nrdnlen[1];
- ptr = lutil_strncopy( d->nrdn, in->bv_val, nrlen );
- *ptr = '\0';
- data.data = d;
+ rc = mdb_cursor_open( txn, dbi, &cursor );
+ if ( rc ) return rc;
- rc = (*cursor)->c_get( *cursor, &key, &data, DB_GET_BOTH_RANGE );
- if ( rc == 0 && (dlen[1] != d->nrdnlen[1] || dlen[0] != d->nrdnlen[0] ||
- strncmp( d->nrdn, in->bv_val, nrlen ))) {
- rc = DB_NOTFOUND;
- }
- if ( rc == 0 ) {
- ptr = (char *) data.data + data.size - sizeof(ID);
- MDB_DISK2ID( ptr, &ei->bei_id );
- ei->bei_rdn.bv_len = data.size - sizeof(diskNode) - nrlen;
- ptr = d->nrdn + nrlen + 1;
- ber_str2bv( ptr, ei->bei_rdn.bv_len, 1, &ei->bei_rdn );
- if ( ei->bei_parent != NULL && !ei->bei_parent->bei_dkids ) {
- db_recno_t dkids;
- /* How many children does the parent have? */
- /* FIXME: do we need to lock the parent
- * entryinfo? Seems safe...
- */
- (*cursor)->c_count( *cursor, &dkids, 0 );
- ei->bei_parent->bei_dkids = dkids;
+ for (;;) {
+ key.mv_data = &pid;
+ pid = nid;
+
+ data.mv_size = sizeof(diskNode) + tmp.bv_len;
+ d = op->o_tmpalloc( data.mv_size, op->o_tmpmemctx );
+ d->nrdnlen[1] = tmp.bv_len & 0xff;
+ d->nrdnlen[0] = (tmp.bv_len >> 8) | 0x80;
+ ptr = lutil_strncopy( d->nrdn, tmp.bv_val, tmp.bv_len );
+ *ptr = '\0';
+ data.mv_data = d;
+ rc = mdb_cursor_get( cursor, &key, &data, MDB_GET_BOTH );
+ op->o_tmpfree( d, op->o_tmpmemctx );
+ if ( rc )
+ break;
+ ptr = (char *) data.mv_data + data.mv_size - sizeof(ID);
+ memcpy( &nid, ptr, sizeof(ID));
+
+ /* grab the non-normalized RDN */
+ if ( matched ) {
+ int rlen;
+ d = data.mv_data;
+ rlen = data.mv_size - sizeof(diskNode) - tmp.bv_len;
+ matched->bv_len += rlen;
+ matched->bv_val -= rlen + 1;
+ ptr = lutil_strcopy( matched->bv_val, d->rdn + tmp.bv_len );
+ if ( pid ) {
+ *ptr = ',';
+ matched->bv_len++;
+ }
+ }
+ if ( tmp.bv_val > in->bv_val ) {
+ for (ptr = tmp.bv_val - 2; ptr > in->bv_val &&
+ !DN_SEPARATOR(*ptr); ptr--) /* empty */;
+ if ( ptr >= in->bv_val ) {
+ if (DN_SEPARATOR(*ptr)) ptr++;
+ tmp.bv_len = tmp.bv_val - ptr - 1;
+ tmp.bv_val = ptr;
+ }
+ } else {
+ break;
}
}
+ *id = nid;
+ mdb_cursor_close( cursor );
+ if ( matched && matched->bv_len ) {
+ ptr = op->o_tmpalloc( matched->bv_len+1, op->o_tmpmemctx );
+ strcpy( ptr, matched->bv_val );
+ matched->bv_val = ptr;
+ }
- op->o_tmpfree( d, op->o_tmpmemctx );
+done:
if( rc != 0 ) {
Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2id: get failed: %s (%d)\n",
- db_strerror( rc ), rc, 0 );
+ mdb_strerror( rc ), rc, 0 );
} else {
Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2id: got id=0x%lx\n",
- ei->bei_id, 0, 0 );
+ nid, 0, 0 );
}
return rc;
}
+/* return IDs from root to parent of DN */
+int
+mdb_dn2sups(
+ Operation *op,
+ MDB_txn *txn,
+ struct berval *in,
+ ID *ids )
+{
+ struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
+ MDB_cursor *cursor;
+ MDB_dbi dbi = mdb->mi_dn2id;
+ MDB_val key, data;
+ int rc = 0, nrlen;
+ diskNode *d;
+ char *ptr;
+ ID pid, nid;
+ struct berval tmp;
+
+ Debug( LDAP_DEBUG_TRACE, "=> mdb_dn2sups(\"%s\")\n", in->bv_val, 0, 0 );
+
+ if ( !in->bv_len ) {
+ goto done;
+ }
+
+ tmp = *in;
+
+ nrlen = tmp.bv_len - op->o_bd->be_nsuffix[0].bv_len;
+ tmp.bv_val += nrlen;
+ tmp.bv_len = op->o_bd->be_nsuffix[0].bv_len;
+ nid = 0;
+ key.mv_size = sizeof(ID);
+
+ rc = mdb_cursor_open( txn, dbi, &cursor );
+ if ( rc ) return rc;
+
+ for (;;) {
+ key.mv_data = &pid;
+ pid = nid;
+
+ data.mv_size = sizeof(diskNode) + tmp.bv_len;
+ d = op->o_tmpalloc( data.mv_size, op->o_tmpmemctx );
+ d->nrdnlen[1] = tmp.bv_len & 0xff;
+ d->nrdnlen[0] = (tmp.bv_len >> 8) | 0x80;
+ ptr = lutil_strncopy( d->nrdn, tmp.bv_val, tmp.bv_len );
+ *ptr = '\0';
+ data.mv_data = d;
+ rc = mdb_cursor_get( cursor, &key, &data, MDB_GET_BOTH );
+ op->o_tmpfree( d, op->o_tmpmemctx );
+ if ( rc ) {
+ mdb_cursor_close( cursor );
+ break;
+ }
+ ptr = (char *) data.mv_data + data.mv_size - sizeof(ID);
+ memcpy( &nid, ptr, sizeof(ID));
+
+ if ( pid )
+ mdb_idl_insert( ids, pid );
+
+ if ( tmp.bv_val > in->bv_val ) {
+ for (ptr = tmp.bv_val - 2; ptr > in->bv_val &&
+ !DN_SEPARATOR(*ptr); ptr--) /* empty */;
+ if ( ptr >= in->bv_val ) {
+ if (DN_SEPARATOR(*ptr)) ptr++;
+ tmp.bv_len = tmp.bv_val - ptr - 1;
+ tmp.bv_val = ptr;
+ }
+ } else {
+ break;
+ }
+ }
+
+done:
+ if( rc != 0 ) {
+ Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2sups: get failed: %s (%d)\n",
+ mdb_strerror( rc ), rc, 0 );
+ }
+
+ return rc;
+}
+
+#if 0
int
mdb_dn2id_parent(
Operation *op,
op->o_tmpfree( d, op->o_tmpmemctx );
return rc;
}
+#endif
int
mdb_dn2id_children(
Operation *op,
- DB_TXN *txn,
+ MDB_txn *txn,
Entry *e )
{
struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
- DB *db = mdb->bi_dn2id->bdi_db;
- DBT key, data;
- DBC *cursor;
+ MDB_dbi dbi = mdb->mi_dn2id;
+ MDB_val key, data;
+ MDB_cursor *cursor;
int rc;
ID id;
- diskNode d;
- DBTzero(&key);
- key.size = sizeof(ID);
- key.data = &e->e_id;
- key.flags = DB_DBT_USERMEM;
- MDB_ID2DISK( e->e_id, &id );
+ key.mv_size = sizeof(ID);
+ key.mv_data = &id;
+ id = e->e_id;
+
+ rc = mdb_cursor_open( txn, dbi, &cursor );
+ if ( rc ) return rc;
- /* IDL cache is in host byte order */
- if ( mdb->bi_idl_cache_size ) {
- rc = mdb_idl_cache_get( mdb, db, &key, NULL );
- if ( rc != LDAP_NO_SUCH_OBJECT ) {
- return rc;
+ rc = mdb_cursor_get( cursor, &key, &data, MDB_SET );
+ if ( rc == 0 ) {
+ unsigned long dkids;
+ rc = mdb_cursor_count( cursor, &dkids );
+ if ( rc == 0 ) {
+ if ( dkids < 2 ) rc = MDB_NOTFOUND;
}
}
+ mdb_cursor_close( cursor );
+ return rc;
+}
- key.data = &id;
- DBTzero(&data);
- data.data = &d;
- data.ulen = sizeof(d);
- data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
- data.dlen = sizeof(d);
+int
+mdb_id2name(
+ Operation *op,
+ MDB_txn *txn,
+ MDB_cursor **cursp,
+ ID id,
+ struct berval *name,
+ struct berval *nname )
+{
+ struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
+ MDB_dbi dbi = mdb->mi_dn2id;
+ MDB_val key, data;
+ MDB_cursor *cursor;
+ int rc, len, nlen;
+ char dn[SLAP_LDAPDN_MAXLEN], ndn[SLAP_LDAPDN_MAXLEN], *ptr;
+ char *dptr, *nptr;
+ diskNode *d;
- rc = db->cursor( db, txn, &cursor, mdb->bi_db_opflags );
- if ( rc ) return rc;
+ key.mv_size = sizeof(ID);
- rc = cursor->c_get( cursor, &key, &data, DB_SET );
+ if ( !*cursp ) {
+ rc = mdb_cursor_open( txn, dbi, cursp );
+ if ( rc ) return rc;
+ }
+ cursor = *cursp;
+
+ len = 0;
+ nlen = 0;
+ dptr = dn;
+ nptr = ndn;
+ while (id) {
+ int nrlen, rlen;
+ key.mv_data = &id;
+ data.mv_size = 0;
+ data.mv_data = "";
+ rc = mdb_cursor_get( cursor, &key, &data, MDB_SET );
+ if ( rc ) break;
+ ptr = data.mv_data;
+ ptr += data.mv_size - sizeof(ID);
+ memcpy( &id, ptr, sizeof(ID) );
+ d = data.mv_data;
+ nrlen = (d->nrdnlen[0] << 8) | d->nrdnlen[1];
+ if (nptr > ndn) {
+ *nptr++ = ',';
+ *dptr++ = ',';
+ }
+ /* copy name and trailing NUL */
+ memcpy( nptr, d->nrdn, nrlen+1 );
+ rlen = data.mv_size - sizeof(diskNode) - nrlen;
+ memcpy( dptr, d->nrdn+nrlen+1, rlen+1 );
+ nptr += nrlen;
+ dptr += rlen;
+ }
if ( rc == 0 ) {
- db_recno_t dkids;
- rc = cursor->c_count( cursor, &dkids, 0 );
- if ( rc == 0 ) {
- BEI(e)->bei_dkids = dkids;
- if ( dkids < 2 ) rc = DB_NOTFOUND;
+ name->bv_len = dptr - dn;
+ nname->bv_len = nptr - ndn;
+ name->bv_val = op->o_tmpalloc( name->bv_len + 1, op->o_tmpmemctx );
+ nname->bv_val = op->o_tmpalloc( nname->bv_len + 1, op->o_tmpmemctx );
+ memcpy( name->bv_val, dn, name->bv_len );
+ name->bv_val[name->bv_len] = '\0';
+ memcpy( nname->bv_val, ndn, nname->bv_len );
+ nname->bv_val[nname->bv_len] = '\0';
+ }
+ return rc;
+}
+
+/* Find each id in ids that is a child of base and move it to res.
+ */
+int
+mdb_idscope(
+ Operation *op,
+ MDB_txn *txn,
+ ID base,
+ ID *ids,
+ ID *res )
+{
+ struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
+ MDB_dbi dbi = mdb->mi_dn2id;
+ MDB_val key, data;
+ MDB_cursor *cursor;
+ ID ida, id, cid, ci0, idc = 0;
+ char *ptr;
+ int rc;
+
+ key.mv_size = sizeof(ID);
+
+ MDB_IDL_ZERO( res );
+
+ rc = mdb_cursor_open( txn, dbi, &cursor );
+ if ( rc ) return rc;
+
+ ida = mdb_idl_first( ids, &cid );
+
+ /* Don't bother moving out of ids if it's a range */
+ if (!MDB_IDL_IS_RANGE(ids)) {
+ idc = ids[0];
+ ci0 = cid;
+ }
+
+ while (ida != NOID) {
+ id = ida;
+ while (id) {
+ key.mv_data = &id;
+ rc = mdb_cursor_get( cursor, &key, &data, MDB_SET );
+ if ( rc ) {
+ /* not found, move on to next */
+ if (idc) {
+ if (ci0 != cid)
+ ids[ci0] = ids[cid];
+ ci0++;
+ }
+ break;
+ }
+ ptr = data.mv_data;
+ ptr += data.mv_size - sizeof(ID);
+ memcpy( &id, ptr, sizeof(ID) );
+ if ( id == base ) {
+ res[0]++;
+ res[res[0]] = ida;
+ if (idc)
+ idc--;
+ break;
+ } else {
+ if (idc) {
+ if (ci0 != cid)
+ ids[ci0] = ids[cid];
+ ci0++;
+ }
+ }
+ if ( op->ors_scope == LDAP_SCOPE_ONELEVEL )
+ break;
}
+ ida = mdb_idl_next( ids, &cid );
}
- cursor->c_close( cursor );
+ if (!MDB_IDL_IS_RANGE( ids ))
+ ids[0] = idc;
+
+ mdb_cursor_close( cursor );
return rc;
}
+/* See if base is a child of any of the scopes
+ */
+int
+mdb_idscopes(
+ Operation *op,
+ MDB_txn *txn,
+ MDB_cursor **cursp,
+ ID base,
+ ID *scopes )
+{
+ struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
+ MDB_dbi dbi = mdb->mi_dn2id;
+ MDB_val key, data;
+ MDB_cursor *cursor;
+ ID id;
+ char *ptr;
+ int rc;
+ unsigned int x;
+
+ key.mv_size = sizeof(ID);
+
+ if ( !*cursp ) {
+ rc = mdb_cursor_open( txn, dbi, cursp );
+ if ( rc ) return rc;
+ }
+ cursor = *cursp;
+
+ id = base;
+ while (id) {
+ key.mv_data = &id;
+ rc = mdb_cursor_get( cursor, &key, &data, MDB_SET );
+ if ( rc )
+ break;
+ ptr = data.mv_data;
+ ptr += data.mv_size - sizeof(ID);
+ memcpy( &id, ptr, sizeof(ID) );
+ x = mdb_idl_search( scopes, id );
+ if ( scopes[x] == id )
+ return MDB_SUCCESS;
+ if ( op->ors_scope == LDAP_SCOPE_ONELEVEL )
+ break;
+ }
+ return MDB_NOTFOUND;
+}
+
+#if 0
/* mdb_dn2idl:
* We can't just use mdb_idl_fetch_key because
* 1 - our data items are longer than just an entry ID
return cx.rc;
}
+#endif