Back to index

openldap  2.4.31
Defines | Typedefs | Functions | Variables
proto-mdb.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define MDB_UCTYPE   "MDB"
#define mdb_index_entry_add(op, t, e)   mdb_index_entry((op),(t),SLAP_INDEX_ADD_OP,(e))
#define mdb_index_entry_del(op, t, e)   mdb_index_entry((op),(t),SLAP_INDEX_DELETE_OP,(e))

Typedefs

typedef intmdb_idl_keyfunc )(MDB_cursor *mc, struct berval *key, ID id)

Functions

AttrInfomdb_attr_mask (struct mdb_info *mdb, AttributeDescription *desc)
void mdb_attr_flush (struct mdb_info *mdb)
int mdb_attr_slot (struct mdb_info *mdb, AttributeDescription *desc, int *insert)
int mdb_attr_dbs_open (BackendDB *be, MDB_txn *txn, struct config_reply_s *cr)
void mdb_attr_dbs_close (struct mdb_info *mdb)
int mdb_attr_index_config LDAP_P ((struct mdb_info *mdb, const char *fname, int lineno, int argc, char **argv, struct config_reply_s *cr))
void mdb_attr_index_unparse LDAP_P ((struct mdb_info *mdb, BerVarray *bva))
void mdb_attr_index_destroy LDAP_P ((struct mdb_info *mdb))
void mdb_attr_index_free LDAP_P ((struct mdb_info *mdb, AttributeDescription *ad))
void mdb_attr_info_free (AttrInfo *ai)
int mdb_ad_read (struct mdb_info *mdb, MDB_txn *txn)
int mdb_ad_get (struct mdb_info *mdb, MDB_txn *txn, AttributeDescription *ad)
int mdb_back_init_cf (BackendInfo *bi)
int mdb_dn2entry LDAP_P ((Operation *op, MDB_txn *tid, MDB_cursor *mc, struct berval *dn, Entry **e, int matched))
int mdb_dn2id (Operation *op, MDB_txn *txn, MDB_cursor *mc, struct berval *ndn, ID *id, struct berval *matched, struct berval *nmatched)
int mdb_dn2id_add (Operation *op, MDB_cursor *mcp, MDB_cursor *mcd, ID pid, Entry *e)
int mdb_dn2id_delete (Operation *op, MDB_cursor *mc, ID id)
int mdb_dn2id_children (Operation *op, MDB_txn *tid, Entry *e)
int mdb_dn2sups (Operation *op, MDB_txn *tid, struct berval *dn, ID *sups)
int mdb_dn2idl (Operation *op, MDB_txn *txn, struct berval *ndn, ID eid, ID *ids, ID *stack)
int mdb_dn2id_parent (Operation *op, MDB_txn *txn, ID eid, ID *idp)
int mdb_id2name (Operation *op, MDB_txn *txn, MDB_cursor **cursp, ID eid, struct berval *name, struct berval *nname)
int mdb_idscope (Operation *op, MDB_txn *txn, ID base, ID *ids, ID *res)
int mdb_idscopes (Operation *op, struct IdScopes *isc)
int mdb_filter_candidates (Operation *op, MDB_txn *txn, Filter *f, ID *ids, ID *tmp, ID *stack)
int mdb_id2entry_add (Operation *op, MDB_txn *tid, MDB_cursor *mc, Entry *e)
int mdb_id2entry_update (Operation *op, MDB_txn *tid, MDB_cursor *mc, Entry *e)
int mdb_id2entry_delete (BackendDB *be, MDB_txn *tid, Entry *e)
int mdb_id2entry (Operation *op, MDB_cursor *mc, ID id, Entry **e)
int mdb_entry_return (Operation *op, Entry *e)
int mdb_entry_decode (Operation *op, MDB_val *data, Entry **e)
void mdb_reader_flush (MDB_env *env)
int mdb_opinfo_get (Operation *op, struct mdb_info *mdb, int rdonly, mdb_op_info **moi)
unsigned mdb_idl_search (ID *ids, ID id)
int mdb_idl_fetch_key (BackendDB *be, MDB_txn *txn, MDB_dbi dbi, MDB_val *key, ID *ids, MDB_cursor **saved_cursor, int get_flag)
int mdb_idl_insert (ID *ids, ID id)
int mdb_idl_intersection (ID *a, ID *b)
int mdb_idl_union (ID *a, ID *b)
ID mdb_idl_first (ID *ids, ID *cursor)
ID mdb_idl_next (ID *ids, ID *cursor)
void mdb_idl_sort (ID *ids, ID *tmp)
int mdb_idl_append (ID *a, ID *b)
int mdb_idl_append_one (ID *ids, ID id)
AttrInfo *mdb_index_mask LDAP_P ((Backend *be, AttributeDescription *desc, struct berval *name))
int mdb_index_param LDAP_P ((Backend *be, AttributeDescription *desc, int ftype, MDB_dbi *dbi, slap_mask_t *mask, struct berval *prefix))
int mdb_index_values LDAP_P ((Operation *op, MDB_txn *txn, AttributeDescription *desc, BerVarray vals, ID id, int opid))
int mdb_index_recset LDAP_P ((struct mdb_info *mdb, Attribute *a, AttributeType *type, struct berval *tags, IndexRec *ir))
int mdb_index_recrun LDAP_P ((Operation *op, MDB_txn *txn, struct mdb_info *mdb, IndexRec *ir, ID id, int base))
int mdb_index_entry LDAP_P ((Operation *op, MDB_txn *t, int r, Entry *e))
int mdb_key_read (Backend *be, MDB_txn *txn, MDB_dbi dbi, struct berval *k, ID *ids, MDB_cursor **saved_cursor, int get_flags)
int mdb_next_id (BackendDB *be, MDB_cursor *mc, ID *id)
int mdb_modify_internal (Operation *op, MDB_txn *tid, Modifications *modlist, Entry *e, const char **text, char *textbuf, size_t textlen)
int mdb_monitor_db_init (BackendDB *be)
int mdb_monitor_db_open (BackendDB *be)
int mdb_monitor_db_close (BackendDB *be)
int mdb_monitor_db_destroy (BackendDB *be)
int mdb_tool_idl_add (MDB_cursor *mc, struct berval *keys, ID id)

Variables

MDB_cmp_func mdb_dup_compare
BI_entry_release_rw mdb_entry_release
BI_entry_get_rw mdb_entry_get
mdb_idl_keyfunc mdb_idl_insert_keys
mdb_idl_keyfunc mdb_idl_delete_keys
BI_init mdb_back_initialize
BI_db_config mdb_db_config
BI_op_add mdb_add
BI_op_bind mdb_bind
BI_op_compare mdb_compare
BI_op_delete mdb_delete
BI_op_modify mdb_modify
BI_op_modrdn mdb_modrdn
BI_op_search mdb_search
BI_op_extended mdb_extended
BI_chk_referrals mdb_referrals
BI_operational mdb_operational
BI_has_subordinates mdb_hasSubordinates
BI_tool_entry_open mdb_tool_entry_open
BI_tool_entry_close mdb_tool_entry_close
BI_tool_entry_first_x mdb_tool_entry_first_x
BI_tool_entry_next mdb_tool_entry_next
BI_tool_entry_get mdb_tool_entry_get
BI_tool_entry_put mdb_tool_entry_put
BI_tool_entry_reindex mdb_tool_entry_reindex
BI_tool_dn2id_get mdb_tool_dn2id_get
BI_tool_entry_modify mdb_tool_entry_modify

Define Documentation

#define mdb_index_entry_add (   op,
  t,
  e 
)    mdb_index_entry((op),(t),SLAP_INDEX_ADD_OP,(e))

Definition at line 277 of file proto-mdb.h.

#define mdb_index_entry_del (   op,
  t,
  e 
)    mdb_index_entry((op),(t),SLAP_INDEX_DELETE_OP,(e))

Definition at line 279 of file proto-mdb.h.

#define MDB_UCTYPE   "MDB"

Definition at line 21 of file proto-mdb.h.


Typedef Documentation

typedef int( mdb_idl_keyfunc)(MDB_cursor *mc, struct berval *key, ID id)

Definition at line 204 of file proto-mdb.h.


Function Documentation

int mdb_attr_index_config LDAP_P ( (struct mdb_info *mdb, const char *fname, int lineno, int argc, char **argv, struct config_reply_s *cr )
int mdb_ad_get ( struct mdb_info mdb,
MDB_txn txn,
AttributeDescription ad 
)

Definition at line 582 of file attr.c.

{
       int i, rc;
       MDB_val key, val;

       rc = mdb_ad_read( mdb, txn );
       if (rc)
              return rc;

       if ( mdb->mi_adxs[ad->ad_index] )
              return 0;

       i = mdb->mi_numads+1;
       key.mv_size = sizeof(int);
       key.mv_data = &i;
       val.mv_size = ad->ad_cname.bv_len;
       val.mv_data = ad->ad_cname.bv_val;

       rc = mdb_put( txn, mdb->mi_ad2id, &key, &val, 0 );
       if ( rc == MDB_SUCCESS ) {
              mdb->mi_adxs[ad->ad_index] = i;
              mdb->mi_ads[i] = ad;
              mdb->mi_numads++;
       } else {
              Debug( LDAP_DEBUG_ANY,
                     "mdb_ad_get: mdb_put failed %s(%d)\n",
                     mdb_strerror(rc), rc, 0);
       }

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_ad_read ( struct mdb_info mdb,
MDB_txn txn 
)

Definition at line 527 of file attr.c.

{
       int i, rc;
       MDB_cursor *mc;
       MDB_val key, data;
       struct berval bdata;
       const char *text;
       AttributeDescription *ad;

       rc = mdb_cursor_open( txn, mdb->mi_ad2id, &mc );
       if ( rc ) {
              Debug( LDAP_DEBUG_ANY,
                     "mdb_ad_read: cursor_open failed %s(%d)\n",
                     mdb_strerror(rc), rc, 0);
              return rc;
       }

       /* our array is 1-based, an index of 0 means no data */
       i = mdb->mi_numads+1;
       key.mv_size = sizeof(int);
       key.mv_data = &i;

       rc = mdb_cursor_get( mc, &key, &data, MDB_SET );

       while ( rc == MDB_SUCCESS ) {
              bdata.bv_len = data.mv_size;
              bdata.bv_val = data.mv_data;
              ad = NULL;
              rc = slap_bv2ad( &bdata, &ad, &text );
              if ( rc ) {
                     rc = slap_bv2undef_ad( &bdata, &mdb->mi_ads[i], &text, 0 );
              } else {
                     if ( ad->ad_index >= MDB_MAXADS ) {
                            Debug( LDAP_DEBUG_ANY,
                                   "mdb_adb_read: too many AttributeDescriptions in use\n",
                                   0, 0, 0 );
                            return LDAP_OTHER;
                     }
                     mdb->mi_adxs[ad->ad_index] = i;
                     mdb->mi_ads[i] = ad;
              }
              i++;
              rc = mdb_cursor_get( mc, &key, &data, MDB_NEXT );
       }
       mdb->mi_numads = i-1;

done:
       if ( rc == MDB_NOTFOUND )
              rc = 0;

       mdb_cursor_close( mc );

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void mdb_attr_dbs_close ( struct mdb_info mdb)

Definition at line 159 of file attr.c.

{
       int i;
       for ( i=0; i<mdb->mi_nattrs; i++ )
              if ( mdb->mi_attrs[i]->ai_dbi )
                     mdb_close( mdb->mi_dbenv, mdb->mi_attrs[i]->ai_dbi );
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_attr_dbs_open ( BackendDB be,
MDB_txn txn,
struct config_reply_s cr 
)
void mdb_attr_flush ( struct mdb_info mdb)

Definition at line 511 of file attr.c.

{
       int i;

       for ( i=0; i<mdb->mi_nattrs; i++ ) {
              if ( mdb->mi_attrs[i]->ai_indexmask & MDB_INDEX_DELETING ) {
                     int j;
                     mdb_attr_info_free( mdb->mi_attrs[i] );
                     mdb->mi_nattrs--;
                     for (j=i; j<mdb->mi_nattrs; j++)
                            mdb->mi_attrs[j] = mdb->mi_attrs[j+1];
                     i--;
              }
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 479 of file attr.c.

{
#ifdef LDAP_COMP_MATCH
       free( ai->ai_cr );
#endif
       free( ai );
}

Here is the caller graph for this function:

AttrInfo* mdb_attr_mask ( struct mdb_info mdb,
AttributeDescription desc 
)

Definition at line 82 of file attr.c.

{
       int i = mdb_attr_slot( mdb, desc, NULL );
       return i < 0 ? NULL : mdb->mi_attrs[i];
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_attr_slot ( struct mdb_info mdb,
AttributeDescription desc,
int insert 
)

Definition at line 33 of file attr.c.

{
       unsigned base = 0, cursor = 0;
       unsigned n = mdb->mi_nattrs;
       int val = 0;
       
       while ( 0 < n ) {
              unsigned pivot = n >> 1;
              cursor = base + pivot;

              val = SLAP_PTRCMP( ad, mdb->mi_attrs[cursor]->ai_desc );
              if ( val < 0 ) {
                     n = pivot;
              } else if ( val > 0 ) {
                     base = cursor + 1;
                     n -= pivot + 1;
              } else {
                     return cursor;
              }
       }
       if ( ins ) {
              if ( val > 0 )
                     ++cursor;
              *ins = cursor;
       }
       return -1;
}

Here is the caller graph for this function:

Definition at line 580 of file config.c.

{
       int rc;
       bi->bi_cf_ocs = mdbocs;

       rc = config_register_schema( mdbcfg, mdbocs );
       if ( rc ) return rc;
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_dn2id ( Operation op,
MDB_txn txn,
MDB_cursor mc,
struct berval ndn,
ID id,
struct berval matched,
struct berval nmatched 
)

Definition at line 247 of file dn2id.c.

{
       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;
       char dn[SLAP_LDAPDN_MAXLEN];
       ID pid, nid;
       struct berval tmp;

       Debug( LDAP_DEBUG_TRACE, "=> mdb_dn2id(\"%s\")\n", in->bv_val ? in->bv_val : "", 0, 0 );

       if ( matched ) {
              matched->bv_val = dn + sizeof(dn) - 1;
              matched->bv_len = 0;
              *matched->bv_val-- = '\0';
       }
       if ( nmatched ) {
              nmatched->bv_len = 0;
              nmatched->bv_val = 0;
       }

       if ( !in->bv_len ) {
              *id = 0;
              nid = 0;
              goto done;
       }

       tmp = *in;

       if ( op->o_bd->be_nsuffix[0].bv_len ) {
              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;
       } else {
              for ( ptr = tmp.bv_val + tmp.bv_len - 1; ptr >= tmp.bv_val; ptr-- )
                     if (DN_SEPARATOR(*ptr))
                            break;
              ptr++;
              tmp.bv_len -= ptr - tmp.bv_val;
              tmp.bv_val = ptr;
       }
       nid = 0;
       key.mv_size = sizeof(ID);

       if ( mc ) {
              cursor = mc;
       } else {
              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 )
                     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 ( nmatched ) {
                     nmatched->bv_val = tmp.bv_val;
              }

              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; 
       if ( !mc )
              mdb_cursor_close( cursor );
done:
       if ( matched ) {
              if ( matched->bv_len ) {
                     ptr = op->o_tmpalloc( matched->bv_len+1, op->o_tmpmemctx );
                     strcpy( ptr, matched->bv_val );
                     matched->bv_val = ptr;
              } else {
                     if ( BER_BVISEMPTY( &op->o_bd->be_nsuffix[0] ) && !nid ) {
                            ber_dupbv( matched, (struct berval *)&slap_empty_bv );
                     } else {
                            matched->bv_val = NULL;
                     }
              }
       }
       if ( nmatched ) {
              if ( nmatched->bv_val ) {
                     nmatched->bv_len = in->bv_len - (nmatched->bv_val - in->bv_val);
              } else {
                     *nmatched = slap_empty_bv;
              }
       }

       if( rc != 0 ) {
              Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2id: get failed: %s (%d)\n",
                     mdb_strerror( rc ), rc, 0 );
       } else {
              Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2id: got id=0x%lx\n",
                     nid, 0, 0 );
       }

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_dn2id_add ( Operation op,
MDB_cursor mcp,
MDB_cursor mcd,
ID  pid,
Entry e 
)

Definition at line 137 of file dn2id.c.

{
       struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
       MDB_val              key, data;
       ID            nid;
       int           rc, rlen, nrlen;
       diskNode *d;
       char *ptr;

       Debug( LDAP_DEBUG_TRACE, "=> mdb_dn2id_add 0x%lx: \"%s\"\n",
              e->e_id, e->e_ndn ? e->e_ndn : "", 0 );

       nrlen = dn_rdnlen( op->o_bd, &e->e_nname );
       if (nrlen) {
              rlen = dn_rdnlen( op->o_bd, &e->e_name );
       } else {
              nrlen = e->e_nname.bv_len;
              rlen = e->e_name.bv_len;
       }

       d = op->o_tmpalloc(sizeof(diskNode) + rlen + nrlen, op->o_tmpmemctx);
       d->nrdnlen[1] = nrlen & 0xff;
       d->nrdnlen[0] = (nrlen >> 8) | 0x80;
       ptr = lutil_strncopy( d->nrdn, e->e_nname.bv_val, nrlen );
       *ptr++ = '\0';
       ptr = lutil_strncopy( ptr, e->e_name.bv_val, rlen );
       *ptr++ = '\0';
       memcpy( ptr, &e->e_id, sizeof( ID ));

       key.mv_size = sizeof(ID);
       key.mv_data = &nid;

       nid = pid;

       /* Need to make dummy root node once. Subsequent attempts
        * will fail harmlessly.
        */
       if ( pid == 0 ) {
              diskNode dummy = {{0, 0}, "", "", ""};
              data.mv_data = &dummy;
              data.mv_size = sizeof(diskNode);

              mdb_cursor_put( mcp, &key, &data, MDB_NODUPDATA );
       }

       data.mv_data = d;
       data.mv_size = sizeof(diskNode) + rlen + nrlen;

       rc = mdb_cursor_put( mcp, &key, &data, MDB_NODUPDATA );

       if (rc == 0) {
              int flag = MDB_NODUPDATA;
              nid = e->e_id;
              memcpy( ptr, &pid, sizeof( ID ));
              d->nrdnlen[0] ^= 0x80;

              if (slapMode & SLAP_TOOL_MODE)
                     flag |= MDB_APPEND;
              rc = mdb_cursor_put( mcd, &key, &data, flag );
       }

fail:
       op->o_tmpfree( d, op->o_tmpmemctx );
       Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2id_add 0x%lx: %d\n", e->e_id, rc, 0 );

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_dn2id_children ( Operation op,
MDB_txn tid,
Entry e 
)

Definition at line 532 of file dn2id.c.

{
       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;
       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;

       rc = mdb_cursor_get( cursor, &key, &data, MDB_SET );
       if ( rc == 0 ) {
              size_t dkids;
              rc = mdb_cursor_count( cursor, &dkids );
              if ( rc == 0 ) {
                     if ( dkids < 2 ) rc = MDB_NOTFOUND;
              }
       }
       mdb_cursor_close( cursor );
       return rc;
}

Here is the call graph for this function:

int mdb_dn2id_delete ( Operation op,
MDB_cursor mc,
ID  id 
)

Definition at line 212 of file dn2id.c.

{
       int rc;

       Debug( LDAP_DEBUG_TRACE, "=> mdb_dn2id_delete 0x%lx\n",
              id, 0, 0 );

       /* Delete our ID from the parent's list */
       rc = mdb_cursor_del( mc, 0 );

       /* 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_val       key;
              key.mv_size = sizeof(ID);
              key.mv_data = &id;
              rc = mdb_cursor_get( mc, &key, NULL, MDB_SET );
              if ( rc == 0 )
                     rc = mdb_cursor_del( mc, 0 );
       }

       Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2id_delete 0x%lx: %d\n", id, rc, 0 );
       return rc;
}

Here is the call graph for this function:

int mdb_dn2id_parent ( Operation op,
MDB_txn txn,
ID  eid,
ID idp 
)
int mdb_dn2idl ( Operation op,
MDB_txn txn,
struct berval ndn,
ID  eid,
ID ids,
ID stack 
)

Here is the caller graph for this function:

int mdb_dn2sups ( Operation op,
MDB_txn tid,
struct berval dn,
ID sups 
)

Definition at line 394 of file dn2id.c.

{
       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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_entry_decode ( Operation op,
MDB_val data,
Entry **  e 
)

Definition at line 617 of file id2entry.c.

{
       struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
       int i, j, nattrs, nvals;
       int rc;
       Attribute *a;
       Entry *x;
       const char *text;
       AttributeDescription *ad;
       unsigned int *lp = (unsigned int *)data->mv_data;
       unsigned char *ptr;
       BerVarray bptr;

       Debug( LDAP_DEBUG_TRACE,
              "=> mdb_entry_decode:\n",
              0, 0, 0 );

       nattrs = *lp++;
       nvals = *lp++;
       x = mdb_entry_alloc(op, nattrs, nvals);
       x->e_ocflags = *lp++;
       if (!nvals) {
              goto done;
       }
       a = x->e_attrs;
       bptr = a->a_vals;
       i = *lp++;
       ptr = (unsigned char *)(lp + i);

       for (;nattrs>0; nattrs--) {
              int have_nval = 0;
              a->a_desc = mdb->mi_ads[*lp++];
              a->a_flags = SLAP_ATTR_DONT_FREE_DATA | SLAP_ATTR_DONT_FREE_VALS;
              a->a_numvals = *lp++;
              if (a->a_numvals & HIGH_BIT) {
                     a->a_numvals ^= HIGH_BIT;
                     have_nval = 1;
              }
              a->a_vals = bptr;
              for (i=0; i<a->a_numvals; i++) {
                     bptr->bv_len = *lp++;;
                     bptr->bv_val = (char *)ptr;
                     ptr += bptr->bv_len+1;
                     bptr++;
              }
              bptr->bv_val = NULL;
              bptr->bv_len = 0;
              bptr++;

              if (have_nval) {
                     a->a_nvals = bptr;
                     for (i=0; i<a->a_numvals; i++) {
                            bptr->bv_len = *lp++;
                            bptr->bv_val = (char *)ptr;
                            ptr += bptr->bv_len+1;
                            bptr++;
                     }
                     bptr->bv_val = NULL;
                     bptr->bv_len = 0;
                     bptr++;
              } else {
                     a->a_nvals = a->a_vals;
              }
              /* FIXME: This is redundant once a sorted entry is saved into the DB */
              if ( a->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL ) {
                     rc = slap_sort_vals( (Modifications *)a, &text, &j, NULL );
                     if ( rc == LDAP_SUCCESS ) {
                            a->a_flags |= SLAP_ATTR_SORTED_VALS;
                     } else if ( rc == LDAP_TYPE_OR_VALUE_EXISTS ) {
                            /* should never happen */
                            Debug( LDAP_DEBUG_ANY,
                                   "mdb_entry_decode: attributeType %s value #%d provided more than once\n",
                                   a->a_desc->ad_cname.bv_val, j, 0 );
                            return rc;
                     }
              }
              a->a_next = a+1;
              a = a->a_next;
       }
       a[-1].a_next = NULL;
done:

       Debug(LDAP_DEBUG_TRACE, "<= mdb_entry_decode\n",
              0, 0, 0 );
       *e = x;
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_entry_return ( Operation op,
Entry e 
)

Definition at line 214 of file id2entry.c.

{
       if ( e->e_private ) {
              if ( op->o_hdr ) {
                     op->o_tmpfree( e->e_nname.bv_val, op->o_tmpmemctx );
                     op->o_tmpfree( e->e_name.bv_val, op->o_tmpmemctx );
                     op->o_tmpfree( e, op->o_tmpmemctx );
              } else {
                     ch_free( e->e_nname.bv_val );
                     ch_free( e->e_name.bv_val );
                     ch_free( e );
              }
       } else {
              entry_free( e );
       }
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_filter_candidates ( Operation op,
MDB_txn txn,
Filter f,
ID ids,
ID tmp,
ID stack 
)

Definition at line 101 of file filterindex.c.

{
       int rc = 0;
#ifdef LDAP_COMP_MATCH
       AttributeAliasing *aa;
#endif
       Debug( LDAP_DEBUG_FILTER, "=> mdb_filter_candidates\n", 0, 0, 0 );

       if ( f->f_choice & SLAPD_FILTER_UNDEFINED ) {
              MDB_IDL_ZERO( ids );
              goto out;
       }

       switch ( f->f_choice ) {
       case SLAPD_FILTER_COMPUTED:
              switch( f->f_result ) {
              case SLAPD_COMPARE_UNDEFINED:
              /* This technically is not the same as FALSE, but it
               * certainly will produce no matches.
               */
              /* FALL THRU */
              case LDAP_COMPARE_FALSE:
                     MDB_IDL_ZERO( ids );
                     break;
              case LDAP_COMPARE_TRUE:
                     MDB_IDL_ALL( ids );
                     break;
              case LDAP_SUCCESS:
                     /* this is a pre-computed scope, leave it alone */
                     break;
              }
              break;
       case LDAP_FILTER_PRESENT:
              Debug( LDAP_DEBUG_FILTER, "\tPRESENT\n", 0, 0, 0 );
              rc = presence_candidates( op, rtxn, f->f_desc, ids );
              break;

       case LDAP_FILTER_EQUALITY:
              Debug( LDAP_DEBUG_FILTER, "\tEQUALITY\n", 0, 0, 0 );
#ifdef LDAP_COMP_MATCH
              if ( is_aliased_attribute && ( aa = is_aliased_attribute ( f->f_ava->aa_desc ) ) ) {
                     rc = ava_comp_candidates ( op, rtxn, f->f_ava, aa, ids, tmp, stack );
              }
              else
#endif
              {
                     rc = equality_candidates( op, rtxn, f->f_ava, ids, tmp );
              }
              break;

       case LDAP_FILTER_APPROX:
              Debug( LDAP_DEBUG_FILTER, "\tAPPROX\n", 0, 0, 0 );
              rc = approx_candidates( op, rtxn, f->f_ava, ids, tmp );
              break;

       case LDAP_FILTER_SUBSTRINGS:
              Debug( LDAP_DEBUG_FILTER, "\tSUBSTRINGS\n", 0, 0, 0 );
              rc = substring_candidates( op, rtxn, f->f_sub, ids, tmp );
              break;

       case LDAP_FILTER_GE:
              /* if no GE index, use pres */
              Debug( LDAP_DEBUG_FILTER, "\tGE\n", 0, 0, 0 );
              if( f->f_ava->aa_desc->ad_type->sat_ordering &&
                     ( f->f_ava->aa_desc->ad_type->sat_ordering->smr_usage & SLAP_MR_ORDERED_INDEX ) )
                     rc = inequality_candidates( op, rtxn, f->f_ava, ids, tmp, LDAP_FILTER_GE );
              else
                     rc = presence_candidates( op, rtxn, f->f_ava->aa_desc, ids );
              break;

       case LDAP_FILTER_LE:
              /* if no LE index, use pres */
              Debug( LDAP_DEBUG_FILTER, "\tLE\n", 0, 0, 0 );
              if( f->f_ava->aa_desc->ad_type->sat_ordering &&
                     ( f->f_ava->aa_desc->ad_type->sat_ordering->smr_usage & SLAP_MR_ORDERED_INDEX ) )
                     rc = inequality_candidates( op, rtxn, f->f_ava, ids, tmp, LDAP_FILTER_LE );
              else
                     rc = presence_candidates( op, rtxn, f->f_ava->aa_desc, ids );
              break;

       case LDAP_FILTER_NOT:
              /* no indexing to support NOT filters */
              Debug( LDAP_DEBUG_FILTER, "\tNOT\n", 0, 0, 0 );
              MDB_IDL_ALL( ids );
              break;

       case LDAP_FILTER_AND:
              Debug( LDAP_DEBUG_FILTER, "\tAND\n", 0, 0, 0 );
              rc = list_candidates( op, rtxn, 
                     f->f_and, LDAP_FILTER_AND, ids, tmp, stack );
              break;

       case LDAP_FILTER_OR:
              Debug( LDAP_DEBUG_FILTER, "\tOR\n", 0, 0, 0 );
              rc = list_candidates( op, rtxn,
                     f->f_or, LDAP_FILTER_OR, ids, tmp, stack );
              break;
       case LDAP_FILTER_EXT:
                Debug( LDAP_DEBUG_FILTER, "\tEXT\n", 0, 0, 0 );
                rc = ext_candidates( op, rtxn, f->f_mra, ids, tmp, stack );
                break;
       default:
              Debug( LDAP_DEBUG_FILTER, "\tUNKNOWN %lu\n",
                     (unsigned long) f->f_choice, 0, 0 );
              /* Must not return NULL, otherwise extended filters break */
              MDB_IDL_ALL( ids );
       }

out:
       Debug( LDAP_DEBUG_FILTER,
              "<= mdb_filter_candidates: id=%ld first=%ld last=%ld\n",
              (long) ids[0],
              (long) MDB_IDL_FIRST( ids ),
              (long) MDB_IDL_LAST( ids ) );

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_id2entry ( Operation op,
MDB_cursor mc,
ID  id,
Entry **  e 
)

Definition at line 114 of file id2entry.c.

{
       struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
       MDB_val key, data;
       int rc = 0;

       *e = NULL;

       key.mv_data = &id;
       key.mv_size = sizeof(ID);

       /* fetch it */
       rc = mdb_cursor_get( mc, &key, &data, MDB_SET );
       if ( rc == MDB_NOTFOUND ) {
              /* Looking for root entry on an empty-dn suffix? */
              if ( !id && BER_BVISEMPTY( &op->o_bd->be_nsuffix[0] )) {
                     struct berval gluebv = BER_BVC("glue");
                     Entry *r = mdb_entry_alloc(op, 2, 4);
                     Attribute *a = r->e_attrs;
                     struct berval *bptr;

                     r->e_id = 0;
                     r->e_ocflags = SLAP_OC_GLUE|SLAP_OC__END;
                     bptr = a->a_vals;
                     a->a_flags = SLAP_ATTR_DONT_FREE_DATA | SLAP_ATTR_DONT_FREE_VALS;
                     a->a_desc = slap_schema.si_ad_objectClass;
                     a->a_nvals = a->a_vals;
                     a->a_numvals = 1;
                     *bptr++ = gluebv;
                     BER_BVZERO(bptr);
                     bptr++;
                     a->a_next = a+1;
                     a = a->a_next;
                     a->a_flags = SLAP_ATTR_DONT_FREE_DATA | SLAP_ATTR_DONT_FREE_VALS;
                     a->a_desc = slap_schema.si_ad_structuralObjectClass;
                     a->a_vals = bptr;
                     a->a_nvals = a->a_vals;
                     a->a_numvals = 1;
                     *bptr++ = gluebv;
                     BER_BVZERO(bptr);
                     a->a_next = NULL;
                     *e = r;
                     return MDB_SUCCESS;
              }
       }
       if ( rc ) return rc;

       rc = mdb_entry_decode( op, &data, e );
       if ( rc ) return rc;

       (*e)->e_id = id;
       (*e)->e_name.bv_val = NULL;
       (*e)->e_nname.bv_val = NULL;

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_id2entry_add ( Operation op,
MDB_txn tid,
MDB_cursor mc,
Entry e 
)

Definition at line 96 of file id2entry.c.

{
       return mdb_id2entry_put(op, txn, mc, e, ADD_FLAGS);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_id2entry_delete ( BackendDB be,
MDB_txn tid,
Entry e 
)

Definition at line 175 of file id2entry.c.

{
       struct mdb_info *mdb = (struct mdb_info *) be->be_private;
       MDB_dbi dbi = mdb->mi_id2entry;
       MDB_val key;
       int rc;

       key.mv_data = &e->e_id;
       key.mv_size = sizeof(ID);

       /* delete from database */
       rc = mdb_del( tid, dbi, &key, NULL );

       return rc;
}

Here is the call graph for this function:

int mdb_id2entry_update ( Operation op,
MDB_txn tid,
MDB_cursor mc,
Entry e 
)

Definition at line 105 of file id2entry.c.

{
       return mdb_id2entry_put(op, txn, mc, e, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_id2name ( Operation op,
MDB_txn txn,
MDB_cursor **  cursp,
ID  eid,
struct berval name,
struct berval nname 
)

Definition at line 564 of file dn2id.c.

{
       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;

       key.mv_size = sizeof(ID);

       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) {
              unsigned 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];
              rlen = data.mv_size - sizeof(diskNode) - nrlen;
              assert( nrlen < 1024 && rlen < 1024 );    /* FIXME: Sanity check */
              if (nptr > ndn) {
                     *nptr++ = ',';
                     *dptr++ = ',';
              }
              /* copy name and trailing NUL */
              memcpy( nptr, d->nrdn, nrlen+1 );
              memcpy( dptr, d->nrdn+nrlen+1, rlen+1 );
              nptr += nrlen;
              dptr += rlen;
       }
       if ( rc == 0 ) {
              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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_idl_append ( ID a,
ID b 
)

Definition at line 960 of file idl.c.

{
       ID ida, idb, tmp, swap = 0;

       if ( MDB_IDL_IS_ZERO( b ) ) {
              return 0;
       }

       if ( MDB_IDL_IS_ZERO( a ) ) {
              MDB_IDL_CPY( a, b );
              return 0;
       }

       ida = MDB_IDL_LAST( a );
       idb = MDB_IDL_LAST( b );
       if ( MDB_IDL_IS_RANGE( a ) || MDB_IDL_IS_RANGE(b) ||
              a[0] + b[0] >= MDB_IDL_UM_MAX ) {
              a[2] = IDL_MAX( ida, idb );
              a[1] = IDL_MIN( a[1], b[1] );
              a[0] = NOID;
              return 0;
       }

       if ( b[0] > 1 && ida > idb ) {
              swap = idb;
              a[a[0]] = idb;
              b[b[0]] = ida;
       }

       if ( b[1] < a[1] ) {
              tmp = a[1];
              a[1] = b[1];
       } else {
              tmp = b[1];
       }
       a[0]++;
       a[a[0]] = tmp;

       if ( b[0] > 1 ) {
              int i = b[0] - 1;
              AC_MEMCPY(a+a[0]+1, b+2, i * sizeof(ID));
              a[0] += i;
       }
       if ( swap ) {
              b[b[0]] = swap;
       }
       return 0;
}
int mdb_idl_append_one ( ID ids,
ID  id 
)

Definition at line 921 of file idl.c.

{
       if (MDB_IDL_IS_RANGE( ids )) {
              /* if already in range, treat as a dup */
              if (id >= MDB_IDL_RANGE_FIRST(ids) && id <= MDB_IDL_RANGE_LAST(ids))
                     return -1;
              if (id < MDB_IDL_RANGE_FIRST(ids))
                     ids[1] = id;
              else if (id > MDB_IDL_RANGE_LAST(ids))
                     ids[2] = id;
              return 0;
       }
       if ( ids[0] ) {
              ID tmp;

              if (id < ids[1]) {
                     tmp = ids[1];
                     ids[1] = id;
                     id = tmp;
              }
              if ( ids[0] > 1 && id < ids[ids[0]] ) {
                     tmp = ids[ids[0]];
                     ids[ids[0]] = id;
                     id = tmp;
              }
       }
       ids[0]++;
       if ( ids[0] >= MDB_IDL_UM_MAX ) {
              ids[0] = NOID;
              ids[2] = id;
       } else {
              ids[ids[0]] = id;
       }
       return 0;
}
int mdb_idl_fetch_key ( BackendDB be,
MDB_txn txn,
MDB_dbi  dbi,
MDB_val key,
ID ids,
MDB_cursor **  saved_cursor,
int  get_flag 
)

Definition at line 262 of file idl.c.

{
       MDB_val data, key2, *kptr;
       MDB_cursor *cursor;
       ID *i;
       size_t len;
       int rc;
       MDB_cursor_op opflag;

       char keybuf[16];

       Debug( LDAP_DEBUG_ARGS,
              "mdb_idl_fetch_key: %s\n", 
              mdb_show_key( keybuf, key->mv_data, key->mv_size ), 0, 0 );

       assert( ids != NULL );

       if ( saved_cursor && *saved_cursor ) {
              opflag = MDB_NEXT;
       } else if ( get_flag == LDAP_FILTER_GE ) {
              opflag = MDB_SET_RANGE;
       } else if ( get_flag == LDAP_FILTER_LE ) {
              opflag = MDB_FIRST;
       } else {
              opflag = MDB_SET;
       }

       /* If we're not reusing an existing cursor, get a new one */
       if( opflag != MDB_NEXT ) {
              rc = mdb_cursor_open( txn, dbi, &cursor );
              if( rc != 0 ) {
                     Debug( LDAP_DEBUG_ANY, "=> mdb_idl_fetch_key: "
                            "cursor failed: %s (%d)\n", mdb_strerror(rc), rc, 0 );
                     return rc;
              }
       } else {
              cursor = *saved_cursor;
       }
       
       /* If this is a LE lookup, save original key so we can determine
        * when to stop. If this is a GE lookup, save the key since it
        * will be overwritten.
        */
       if ( get_flag == LDAP_FILTER_LE || get_flag == LDAP_FILTER_GE ) {
              key2.mv_data = keybuf;
              key2.mv_size = key->mv_size;
              AC_MEMCPY( keybuf, key->mv_data, key->mv_size );
              kptr = &key2;
       } else {
              kptr = key;
       }
       len = key->mv_size;
       rc = mdb_cursor_get( cursor, kptr, &data, opflag );

       /* skip presence key on range inequality lookups */
       while (rc == 0 && kptr->mv_size != len) {
              rc = mdb_cursor_get( cursor, kptr, &data, MDB_NEXT_NODUP );
       }
       /* If we're doing a LE compare and the new key is greater than
        * our search key, we're done
        */
       if (rc == 0 && get_flag == LDAP_FILTER_LE && memcmp( kptr->mv_data,
              key->mv_data, key->mv_size ) > 0 ) {
              rc = MDB_NOTFOUND;
       }
       if (rc == 0) {
              i = ids+1;
              rc = mdb_cursor_get( cursor, key, &data, MDB_GET_MULTIPLE );
              while (rc == 0) {
                     memcpy( i, data.mv_data, data.mv_size );
                     i += data.mv_size / sizeof(ID);
                     rc = mdb_cursor_get( cursor, key, &data, MDB_NEXT_MULTIPLE );
              }
              if ( rc == MDB_NOTFOUND ) rc = 0;
              ids[0] = i - &ids[1];
              /* On disk, a range is denoted by 0 in the first element */
              if (ids[1] == 0) {
                     if (ids[0] != MDB_IDL_RANGE_SIZE) {
                            Debug( LDAP_DEBUG_ANY, "=> mdb_idl_fetch_key: "
                                   "range size mismatch: expected %d, got %ld\n",
                                   MDB_IDL_RANGE_SIZE, ids[0], 0 );
                            mdb_cursor_close( cursor );
                            return -1;
                     }
                     MDB_IDL_RANGE( ids, ids[2], ids[3] );
              }
              data.mv_size = MDB_IDL_SIZEOF(ids);
       }

       if ( saved_cursor && rc == 0 ) {
              if ( !*saved_cursor )
                     *saved_cursor = cursor;
       }
       else
              mdb_cursor_close( cursor );

       if( rc == MDB_NOTFOUND ) {
              return rc;

       } else if( rc != 0 ) {
              Debug( LDAP_DEBUG_ANY, "=> mdb_idl_fetch_key: "
                     "get failed: %s (%d)\n",
                     mdb_strerror(rc), rc, 0 );
              return rc;

       } else if ( data.mv_size == 0 || data.mv_size % sizeof( ID ) ) {
              /* size not multiple of ID size */
              Debug( LDAP_DEBUG_ANY, "=> mdb_idl_fetch_key: "
                     "odd size: expected %ld multiple, got %ld\n",
                     (long) sizeof( ID ), (long) data.mv_size, 0 );
              return -1;

       } else if ( data.mv_size != MDB_IDL_SIZEOF(ids) ) {
              /* size mismatch */
              Debug( LDAP_DEBUG_ANY, "=> mdb_idl_fetch_key: "
                     "get size mismatch: expected %ld, got %ld\n",
                     (long) ((1 + ids[0]) * sizeof( ID )), (long) data.mv_size, 0 );
              return -1;
       }

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ID mdb_idl_first ( ID ids,
ID cursor 
)

Definition at line 872 of file idl.c.

{
       ID pos;

       if ( ids[0] == 0 ) {
              *cursor = NOID;
              return NOID;
       }

       if ( MDB_IDL_IS_RANGE( ids ) ) {
              if( *cursor < ids[1] ) {
                     *cursor = ids[1];
              }
              return *cursor;
       }

       if ( *cursor == 0 )
              pos = 1;
       else
              pos = mdb_idl_search( ids, *cursor );

       if( pos > ids[0] ) {
              return NOID;
       }

       *cursor = pos;
       return ids[pos];
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_idl_insert ( ID ids,
ID  id 
)

Definition at line 128 of file idl.c.

{
       unsigned x;

#if IDL_DEBUG > 1
       Debug( LDAP_DEBUG_ANY, "insert: %04lx at %d\n", (long) id, x, 0 );
       idl_dump( ids );
#elif IDL_DEBUG > 0
       idl_check( ids );
#endif

       if (MDB_IDL_IS_RANGE( ids )) {
              /* if already in range, treat as a dup */
              if (id >= MDB_IDL_RANGE_FIRST(ids) && id <= MDB_IDL_RANGE_LAST(ids))
                     return -1;
              if (id < MDB_IDL_RANGE_FIRST(ids))
                     ids[1] = id;
              else if (id > MDB_IDL_RANGE_LAST(ids))
                     ids[2] = id;
              return 0;
       }

       x = mdb_idl_search( ids, id );
       assert( x > 0 );

       if( x < 1 ) {
              /* internal error */
              return -2;
       }

       if ( x <= ids[0] && ids[x] == id ) {
              /* duplicate */
              return -1;
       }

       if ( ++ids[0] >= MDB_IDL_DB_MAX ) {
              if( id < ids[1] ) {
                     ids[1] = id;
                     ids[2] = ids[ids[0]-1];
              } else if ( ids[ids[0]-1] < id ) {
                     ids[2] = id;
              } else {
                     ids[2] = ids[ids[0]-1];
              }
              ids[0] = NOID;
       
       } else {
              /* insert id */
              AC_MEMCPY( &ids[x+1], &ids[x], (ids[0]-x) * sizeof(ID) );
              ids[x] = id;
       }

#if IDL_DEBUG > 1
       idl_dump( ids );
#elif IDL_DEBUG > 0
       idl_check( ids );
#endif

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_idl_intersection ( ID a,
ID b 
)

Definition at line 662 of file idl.c.

{
       ID ida, idb;
       ID idmax, idmin;
       ID cursora = 0, cursorb = 0, cursorc;
       int swap = 0;

       if ( MDB_IDL_IS_ZERO( a ) || MDB_IDL_IS_ZERO( b ) ) {
              a[0] = 0;
              return 0;
       }

       idmin = IDL_MAX( MDB_IDL_FIRST(a), MDB_IDL_FIRST(b) );
       idmax = IDL_MIN( MDB_IDL_LAST(a), MDB_IDL_LAST(b) );
       if ( idmin > idmax ) {
              a[0] = 0;
              return 0;
       } else if ( idmin == idmax ) {
              a[0] = 1;
              a[1] = idmin;
              return 0;
       }

       if ( MDB_IDL_IS_RANGE( a ) ) {
              if ( MDB_IDL_IS_RANGE(b) ) {
              /* If both are ranges, just shrink the boundaries */
                     a[1] = idmin;
                     a[2] = idmax;
                     return 0;
              } else {
              /* Else swap so that b is the range, a is a list */
                     ID *tmp = a;
                     a = b;
                     b = tmp;
                     swap = 1;
              }
       }

       /* If a range completely covers the list, the result is
        * just the list. If idmin to idmax is contiguous, just
        * turn it into a range.
        */
       if ( MDB_IDL_IS_RANGE( b )
              && MDB_IDL_RANGE_FIRST( b ) <= MDB_IDL_RANGE_FIRST( a )
              && MDB_IDL_RANGE_LAST( b ) >= MDB_IDL_RANGE_LAST( a ) ) {
              if (idmax - idmin + 1 == a[0])
              {
                     a[0] = NOID;
                     a[1] = idmin;
                     a[2] = idmax;
              }
              goto done;
       }

       /* Fine, do the intersection one element at a time.
        * First advance to idmin in both IDLs.
        */
       cursora = cursorb = idmin;
       ida = mdb_idl_first( a, &cursora );
       idb = mdb_idl_first( b, &cursorb );
       cursorc = 0;

       while( ida <= idmax || idb <= idmax ) {
              if( ida == idb ) {
                     a[++cursorc] = ida;
                     ida = mdb_idl_next( a, &cursora );
                     idb = mdb_idl_next( b, &cursorb );
              } else if ( ida < idb ) {
                     ida = mdb_idl_next( a, &cursora );
              } else {
                     idb = mdb_idl_next( b, &cursorb );
              }
       }
       a[0] = cursorc;
done:
       if (swap)
              MDB_IDL_CPY( b, a );

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ID mdb_idl_next ( ID ids,
ID cursor 
)

Definition at line 901 of file idl.c.

{
       if ( MDB_IDL_IS_RANGE( ids ) ) {
              if( ids[2] < ++(*cursor) ) {
                     return NOID;
              }
              return *cursor;
       }

       if ( ++(*cursor) <= ids[0] ) {
              return ids[*cursor];
       }

       return NOID;
}

Here is the caller graph for this function:

unsigned mdb_idl_search ( ID ids,
ID  id 
)

Definition at line 70 of file idl.c.

{
#define IDL_BINARY_SEARCH 1
#ifdef IDL_BINARY_SEARCH
       /*
        * binary search of id in ids
        * if found, returns position of id
        * if not found, returns first postion greater than id
        */
       unsigned base = 0;
       unsigned cursor = 1;
       int val = 0;
       unsigned n = ids[0];

#if IDL_DEBUG > 0
       idl_check( ids );
#endif

       while( 0 < n ) {
              unsigned pivot = n >> 1;
              cursor = base + pivot + 1;
              val = IDL_CMP( id, ids[cursor] );

              if( val < 0 ) {
                     n = pivot;

              } else if ( val > 0 ) {
                     base = cursor;
                     n -= pivot + 1;

              } else {
                     return cursor;
              }
       }
       
       if( val > 0 ) {
              ++cursor;
       }
       return cursor;

#else
       /* (reverse) linear search */
       int i;

#if IDL_DEBUG > 0
       idl_check( ids );
#endif

       for( i=ids[0]; i; i-- ) {
              if( id > ids[i] ) {
                     break;
              }
       }

       return i+1;
#endif
}

Here is the caller graph for this function:

void mdb_idl_sort ( ID ids,
ID tmp 
)

Definition at line 1017 of file idl.c.

{
       int *istack = (int *)tmp; /* Private stack, not used by caller */
       int i,j,k,l,ir,jstack;
       ID a, itmp;

       if ( MDB_IDL_IS_RANGE( ids ))
              return;

       ir = ids[0];
       l = 1;
       jstack = 0;
       for(;;) {
              if (ir - l < SMALL) {       /* Insertion sort */
                     for (j=l+1;j<=ir;j++) {
                            a = ids[j];
                            for (i=j-1;i>=1;i--) {
                                   if (ids[i] <= a) break;
                                   ids[i+1] = ids[i];
                            }
                            ids[i+1] = a;
                     }
                     if (jstack == 0) break;
                     ir = istack[jstack--];
                     l = istack[jstack--];
              } else {
                     k = (l + ir) >> 1;   /* Choose median of left, center, right */
                     SWAP(ids[k], ids[l+1]);
                     if (ids[l] > ids[ir]) {
                            SWAP(ids[l], ids[ir]);
                     }
                     if (ids[l+1] > ids[ir]) {
                            SWAP(ids[l+1], ids[ir]);
                     }
                     if (ids[l] > ids[l+1]) {
                            SWAP(ids[l], ids[l+1]);
                     }
                     i = l+1;
                     j = ir;
                     a = ids[l+1];
                     for(;;) {
                            do i++; while(ids[i] < a);
                            do j--; while(ids[j] > a);
                            if (j < i) break;
                            SWAP(ids[i],ids[j]);
                     }
                     ids[l+1] = ids[j];
                     ids[j] = a;
                     jstack += 2;
                     if (ir-i+1 >= j-1) {
                            istack[jstack] = ir;
                            istack[jstack-1] = i;
                            ir = j-1;
                     } else {
                            istack[jstack] = j-1;
                            istack[jstack-1] = l;
                            l = i;
                     }
              }
       }
}
int mdb_idl_union ( ID a,
ID b 
)

Definition at line 750 of file idl.c.

{
       ID ida, idb;
       ID cursora = 0, cursorb = 0, cursorc;

       if ( MDB_IDL_IS_ZERO( b ) ) {
              return 0;
       }

       if ( MDB_IDL_IS_ZERO( a ) ) {
              MDB_IDL_CPY( a, b );
              return 0;
       }

       if ( MDB_IDL_IS_RANGE( a ) || MDB_IDL_IS_RANGE(b) ) {
over:         ida = IDL_MIN( MDB_IDL_FIRST(a), MDB_IDL_FIRST(b) );
              idb = IDL_MAX( MDB_IDL_LAST(a), MDB_IDL_LAST(b) );
              a[0] = NOID;
              a[1] = ida;
              a[2] = idb;
              return 0;
       }

       ida = mdb_idl_first( a, &cursora );
       idb = mdb_idl_first( b, &cursorb );

       cursorc = b[0];

       /* The distinct elements of a are cat'd to b */
       while( ida != NOID || idb != NOID ) {
              if ( ida < idb ) {
                     if( ++cursorc > MDB_IDL_UM_MAX ) {
                            goto over;
                     }
                     b[cursorc] = ida;
                     ida = mdb_idl_next( a, &cursora );

              } else {
                     if ( ida == idb )
                            ida = mdb_idl_next( a, &cursora );
                     idb = mdb_idl_next( b, &cursorb );
              }
       }

       /* b is copied back to a in sorted order */
       a[0] = cursorc;
       cursora = 1;
       cursorb = 1;
       cursorc = b[0]+1;
       while (cursorb <= b[0] || cursorc <= a[0]) {
              if (cursorc > a[0])
                     idb = NOID;
              else
                     idb = b[cursorc];
              if (cursorb <= b[0] && b[cursorb] < idb)
                     a[cursora++] = b[cursorb++];
              else {
                     a[cursora++] = idb;
                     cursorc++;
              }
       }

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_idscope ( Operation op,
MDB_txn txn,
ID  base,
ID ids,
ID res 
)

Definition at line 633 of file dn2id.c.

{
       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 );
       }
       if (!MDB_IDL_IS_RANGE( ids ))
              ids[0] = idc;

       mdb_cursor_close( cursor );
       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_idscopes ( Operation op,
struct IdScopes isc 
)

Definition at line 708 of file dn2id.c.

{
       struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
       MDB_dbi dbi = mdb->mi_dn2id;
       MDB_val              key, data;
       ID id;
       ID2 id2;
       char   *ptr;
       int           rc = 0;
       unsigned int x;
       unsigned int nrlen, rlen;
       diskNode *d;

       key.mv_size = sizeof(ID);

       if ( !isc->mc ) {
              rc = mdb_cursor_open( isc->mt, dbi, &isc->mc );
              if ( rc ) return rc;
       }

       id = isc->id;
       while (id) {
              if ( !rc ) {
                     key.mv_data = &id;
                     rc = mdb_cursor_get( isc->mc, &key, &data, MDB_SET );
                     if ( rc )
                            break;

                     /* save RDN info */
              }
              d = data.mv_data;
              nrlen = (d->nrdnlen[0] << 8) | d->nrdnlen[1];
              rlen = data.mv_size - sizeof(diskNode) - nrlen;
              isc->nrdns[isc->numrdns].bv_len = nrlen;
              isc->nrdns[isc->numrdns].bv_val = d->nrdn;
              isc->rdns[isc->numrdns].bv_len = rlen;
              isc->rdns[isc->numrdns].bv_val = d->nrdn+nrlen+1;
              isc->numrdns++;

              if (!rc && id != isc->id) {
                     id2.mid = id;
                     id2.mval = data;
                     mdb_id2l_insert( isc->scopes, &id2 );
              }
              ptr = data.mv_data;
              ptr += data.mv_size - sizeof(ID);
              memcpy( &id, ptr, sizeof(ID) );
              x = mdb_id2l_search( isc->scopes, id );
              if ( x <= isc->scopes[0].mid && isc->scopes[x].mid == id ) {
                     if ( !isc->scopes[x].mval.mv_data ) {
                            isc->nscope = x;
                            return MDB_SUCCESS;
                     }
                     data = isc->scopes[x].mval;
                     rc = 1;
              }
              if ( op->ors_scope == LDAP_SCOPE_ONELEVEL )
                     break;
       }
       return MDB_NOTFOUND;
}

Here is the call graph for this function:

int mdb_key_read ( Backend be,
MDB_txn txn,
MDB_dbi  dbi,
struct berval k,
ID ids,
MDB_cursor **  saved_cursor,
int  get_flags 
)

Definition at line 30 of file key.c.

{
       int rc;
       MDB_val key;
#ifndef MISALIGNED_OK
       int kbuf[2];
#endif

       Debug( LDAP_DEBUG_TRACE, "=> key_read\n", 0, 0, 0 );

#ifndef MISALIGNED_OK
       if (k->bv_len & ALIGNER) {
              key.mv_size = sizeof(kbuf);
              key.mv_data = kbuf;
              kbuf[1] = 0;
              memcpy(kbuf, k->bv_val, k->bv_len);
       } else
#endif
       {
              key.mv_size = k->bv_len;
              key.mv_data = k->bv_val;
       }

       rc = mdb_idl_fetch_key( be, txn, dbi, &key, ids, saved_cursor, get_flag );

       if( rc != LDAP_SUCCESS ) {
              Debug( LDAP_DEBUG_TRACE, "<= mdb_index_read: failed (%d)\n",
                     rc, 0, 0 );
       } else {
              Debug( LDAP_DEBUG_TRACE, "<= mdb_index_read %ld candidates\n",
                     (long) MDB_IDL_N(ids), 0, 0 );
       }

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_modify_internal ( Operation op,
MDB_txn tid,
Modifications modlist,
Entry e,
const char **  text,
char *  textbuf,
size_t  textlen 
)

Definition at line 68 of file modify.c.

{
       int rc, err;
       Modification  *mod;
       Modifications *ml;
       Attribute     *save_attrs;
       Attribute     *ap;
       int                  glue_attr_delete = 0;
       int                  got_delete;

       Debug( LDAP_DEBUG_TRACE, "mdb_modify_internal: 0x%08lx: %s\n",
              e->e_id, e->e_dn, 0);

       if ( !acl_check_modlist( op, e, modlist )) {
              return LDAP_INSUFFICIENT_ACCESS;
       }

       /* save_attrs will be disposed of by caller */
       save_attrs = e->e_attrs;
       e->e_attrs = attrs_dup( e->e_attrs );

       for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
              int match;
              mod = &ml->sml_mod;
              switch( mod->sm_op ) {
              case LDAP_MOD_ADD:
              case LDAP_MOD_REPLACE:
                     if ( mod->sm_desc == slap_schema.si_ad_structuralObjectClass ) {
                            value_match( &match, slap_schema.si_ad_structuralObjectClass,
                                   slap_schema.si_ad_structuralObjectClass->
                                          ad_type->sat_equality,
                                   SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
                                   &mod->sm_values[0], &scbva[0], text );
                            if ( !match ) glue_attr_delete = 1;
                     }
              }
              if ( glue_attr_delete )
                     break;
       }

       if ( glue_attr_delete ) {
              Attribute     **app = &e->e_attrs;
              while ( *app != NULL ) {
                     if ( !is_at_operational( (*app)->a_desc->ad_type )) {
                            Attribute *save = *app;
                            *app = (*app)->a_next;
                            attr_free( save );
                            continue;
                     }
                     app = &(*app)->a_next;
              }
       }

       for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
              mod = &ml->sml_mod;
              got_delete = 0;

              switch ( mod->sm_op ) {
              case LDAP_MOD_ADD:
                     Debug(LDAP_DEBUG_ARGS,
                            "mdb_modify_internal: add %s\n",
                            mod->sm_desc->ad_cname.bv_val, 0, 0);
                     err = modify_add_values( e, mod, get_permissiveModify(op),
                            text, textbuf, textlen );
                     if( err != LDAP_SUCCESS ) {
                            Debug(LDAP_DEBUG_ARGS, "mdb_modify_internal: %d %s\n",
                                   err, *text, 0);
                     }
                     break;

              case LDAP_MOD_DELETE:
                     if ( glue_attr_delete ) {
                            err = LDAP_SUCCESS;
                            break;
                     }

                     Debug(LDAP_DEBUG_ARGS,
                            "mdb_modify_internal: delete %s\n",
                            mod->sm_desc->ad_cname.bv_val, 0, 0);
                     err = modify_delete_values( e, mod, get_permissiveModify(op),
                            text, textbuf, textlen );
                     if( err != LDAP_SUCCESS ) {
                            Debug(LDAP_DEBUG_ARGS, "mdb_modify_internal: %d %s\n",
                                   err, *text, 0);
                     } else {
                            got_delete = 1;
                     }
                     break;

              case LDAP_MOD_REPLACE:
                     Debug(LDAP_DEBUG_ARGS,
                            "mdb_modify_internal: replace %s\n",
                            mod->sm_desc->ad_cname.bv_val, 0, 0);
                     err = modify_replace_values( e, mod, get_permissiveModify(op),
                            text, textbuf, textlen );
                     if( err != LDAP_SUCCESS ) {
                            Debug(LDAP_DEBUG_ARGS, "mdb_modify_internal: %d %s\n",
                                   err, *text, 0);
                     } else {
                            got_delete = 1;
                     }
                     break;

              case LDAP_MOD_INCREMENT:
                     Debug(LDAP_DEBUG_ARGS,
                            "mdb_modify_internal: increment %s\n",
                            mod->sm_desc->ad_cname.bv_val, 0, 0);
                     err = modify_increment_values( e, mod, get_permissiveModify(op),
                            text, textbuf, textlen );
                     if( err != LDAP_SUCCESS ) {
                            Debug(LDAP_DEBUG_ARGS,
                                   "mdb_modify_internal: %d %s\n",
                                   err, *text, 0);
                     } else {
                            got_delete = 1;
                     }
                     break;

              case SLAP_MOD_SOFTADD:
                     Debug(LDAP_DEBUG_ARGS,
                            "mdb_modify_internal: softadd %s\n",
                            mod->sm_desc->ad_cname.bv_val, 0, 0);
                     /* Avoid problems in index_add_mods()
                      * We need to add index if necessary.
                      */
                     mod->sm_op = LDAP_MOD_ADD;

                     err = modify_add_values( e, mod, get_permissiveModify(op),
                            text, textbuf, textlen );

                     mod->sm_op = SLAP_MOD_SOFTADD;

                     if ( err == LDAP_TYPE_OR_VALUE_EXISTS ) {
                            err = LDAP_SUCCESS;
                     }

                     if( err != LDAP_SUCCESS ) {
                            Debug(LDAP_DEBUG_ARGS, "mdb_modify_internal: %d %s\n",
                                   err, *text, 0);
                     }
                     break;

              case SLAP_MOD_SOFTDEL:
                     Debug(LDAP_DEBUG_ARGS,
                            "mdb_modify_internal: softdel %s\n",
                            mod->sm_desc->ad_cname.bv_val, 0, 0);
                     /* Avoid problems in index_delete_mods()
                      * We need to add index if necessary.
                      */
                     mod->sm_op = LDAP_MOD_DELETE;

                     err = modify_delete_values( e, mod, get_permissiveModify(op),
                            text, textbuf, textlen );

                     mod->sm_op = SLAP_MOD_SOFTDEL;

                     if ( err == LDAP_NO_SUCH_ATTRIBUTE ) {
                            err = LDAP_SUCCESS;
                     }

                     if( err != LDAP_SUCCESS ) {
                            Debug(LDAP_DEBUG_ARGS, "mdb_modify_internal: %d %s\n",
                                   err, *text, 0);
                     }
                     break;

              case SLAP_MOD_ADD_IF_NOT_PRESENT:
                     if ( attr_find( e->e_attrs, mod->sm_desc ) != NULL ) {
                            /* skip */
                            err = LDAP_SUCCESS;
                            break;
                     }

                     Debug(LDAP_DEBUG_ARGS,
                            "mdb_modify_internal: add_if_not_present %s\n",
                            mod->sm_desc->ad_cname.bv_val, 0, 0);
                     /* Avoid problems in index_add_mods()
                      * We need to add index if necessary.
                      */
                     mod->sm_op = LDAP_MOD_ADD;

                     err = modify_add_values( e, mod, get_permissiveModify(op),
                            text, textbuf, textlen );

                     mod->sm_op = SLAP_MOD_ADD_IF_NOT_PRESENT;

                     if( err != LDAP_SUCCESS ) {
                            Debug(LDAP_DEBUG_ARGS, "mdb_modify_internal: %d %s\n",
                                   err, *text, 0);
                     }
                     break;

              default:
                     Debug(LDAP_DEBUG_ANY, "mdb_modify_internal: invalid op %d\n",
                            mod->sm_op, 0, 0);
                     *text = "Invalid modify operation";
                     err = LDAP_OTHER;
                     Debug(LDAP_DEBUG_ARGS, "mdb_modify_internal: %d %s\n",
                            err, *text, 0);
              }

              if ( err != LDAP_SUCCESS ) {
                     attrs_free( e->e_attrs );
                     e->e_attrs = save_attrs;
                     /* unlock entry, delete from cache */
                     return err; 
              }

              /* If objectClass was modified, reset the flags */
              if ( mod->sm_desc == slap_schema.si_ad_objectClass ) {
                     e->e_ocflags = 0;
              }

              if ( glue_attr_delete ) e->e_ocflags = 0;


              /* check if modified attribute was indexed
               * but not in case of NOOP... */
              if ( !op->o_noop ) {
                     mdb_modify_idxflags( op, mod->sm_desc, got_delete, e->e_attrs, save_attrs );
              }
       }

       /* check that the entry still obeys the schema */
       ap = NULL;
       rc = entry_schema_check( op, e, save_attrs, get_relax(op), 0, &ap,
              text, textbuf, textlen );
       if ( rc != LDAP_SUCCESS || op->o_noop ) {
              attrs_free( e->e_attrs );
              /* clear the indexing flags */
              for ( ap = save_attrs; ap != NULL; ap = ap->a_next ) {
                     ap->a_flags &= ~(SLAP_ATTR_IXADD|SLAP_ATTR_IXDEL);
              }
              e->e_attrs = save_attrs;

              if ( rc != LDAP_SUCCESS ) {
                     Debug( LDAP_DEBUG_ANY,
                            "entry failed schema check: %s\n",
                            *text, 0, 0 );
              }

              /* if NOOP then silently revert to saved attrs */
              return rc;
       }

       /* structuralObjectClass modified! */
       if ( ap ) {
              assert( ap->a_desc == slap_schema.si_ad_structuralObjectClass );
              if ( !op->o_noop ) {
                     mdb_modify_idxflags( op, slap_schema.si_ad_structuralObjectClass,
                            1, e->e_attrs, save_attrs );
              }
       }

       /* update the indices of the modified attributes */

       /* start with deleting the old index entries */
       for ( ap = save_attrs; ap != NULL; ap = ap->a_next ) {
              if ( ap->a_flags & SLAP_ATTR_IXDEL ) {
                     struct berval *vals;
                     Attribute *a2;
                     ap->a_flags &= ~SLAP_ATTR_IXDEL;
                     a2 = attr_find( e->e_attrs, ap->a_desc );
                     if ( a2 ) {
                            /* need to detect which values were deleted */
                            int i, j;
                            vals = op->o_tmpalloc( (ap->a_numvals + 1) *
                                   sizeof(struct berval), op->o_tmpmemctx );
                            j = 0;
                            for ( i=0; i < ap->a_numvals; i++ ) {
                                   rc = attr_valfind( a2, SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
                                          &ap->a_nvals[i], NULL, op->o_tmpmemctx );
                                   /* Save deleted values */
                                   if ( rc == LDAP_NO_SUCH_ATTRIBUTE )
                                          vals[j++] = ap->a_nvals[i];
                            }
                            BER_BVZERO(vals+j);
                     } else {
                            /* attribute was completely deleted */
                            vals = ap->a_nvals;
                     }
                     rc = 0;
                     if ( !BER_BVISNULL( vals )) {
                            rc = mdb_index_values( op, tid, ap->a_desc,
                                   vals, e->e_id, SLAP_INDEX_DELETE_OP );
                            if ( rc != LDAP_SUCCESS ) {
                                   Debug( LDAP_DEBUG_ANY,
                                          "%s: attribute \"%s\" index delete failure\n",
                                          op->o_log_prefix, ap->a_desc->ad_cname.bv_val, 0 );
                                   attrs_free( e->e_attrs );
                                   e->e_attrs = save_attrs;
                            }
                     }
                     if ( vals != ap->a_nvals )
                            op->o_tmpfree( vals, op->o_tmpmemctx );
                     if ( rc ) return rc;
              }
       }

       /* add the new index entries */
       for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) {
              if (ap->a_flags & SLAP_ATTR_IXADD) {
                     ap->a_flags &= ~SLAP_ATTR_IXADD;
                     rc = mdb_index_values( op, tid, ap->a_desc,
                            ap->a_nvals,
                            e->e_id, SLAP_INDEX_ADD_OP );
                     if ( rc != LDAP_SUCCESS ) {
                            Debug( LDAP_DEBUG_ANY,
                                   "%s: attribute \"%s\" index add failure\n",
                                   op->o_log_prefix, ap->a_desc->ad_cname.bv_val, 0 );
                            attrs_free( e->e_attrs );
                            e->e_attrs = save_attrs;
                            return rc;
                     }
              }
       }

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 422 of file monitor.c.

{
       struct mdb_info             *mdb = (struct mdb_info *) be->be_private;

       if ( !BER_BVISNULL( &mdb->mi_monitor.mdm_ndn ) ) {
              BackendInfo          *mi = backend_info( "monitor" );
              monitor_extra_t             *mbe;

              if ( mi && &mi->bi_extra ) {
                     mbe = mi->bi_extra;
                     mbe->unregister_entry_callback( &mdb->mi_monitor.mdm_ndn,
                            (monitor_callback_t *)mdb->mi_monitor.mdm_cb,
                            NULL, 0, NULL );
              }

              memset( &mdb->mi_monitor, 0, sizeof( mdb->mi_monitor ) );
       }

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 447 of file monitor.c.

{
#ifdef MDB_MONITOR_IDX
       struct mdb_info             *mdb = (struct mdb_info *) be->be_private;

       /* TODO: free tree */
       ldap_pvt_thread_mutex_destroy( &mdb->mi_idx_mutex );
       avl_free( mdb->mi_idx, ch_free );
#endif /* MDB_MONITOR_IDX */

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 260 of file monitor.c.

{
       struct mdb_info             *mdb = (struct mdb_info *) be->be_private;

       if ( mdb_monitor_initialize() == LDAP_SUCCESS ) {
              /* monitoring in back-mdb is on by default */
              SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_MONITORING;
       }

#ifdef MDB_MONITOR_IDX
       mdb->mi_idx = NULL;
       ldap_pvt_thread_mutex_init( &mdb->mi_idx_mutex );
#endif /* MDB_MONITOR_IDX */

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 281 of file monitor.c.

{
       struct mdb_info             *mdb = (struct mdb_info *) be->be_private;
       Attribute            *a, *next;
       monitor_callback_t   *cb = NULL;
       int                  rc = 0;
       BackendInfo          *mi;
       monitor_extra_t             *mbe;
       struct berval dummy = BER_BVC("");

       if ( !SLAP_DBMONITORING( be ) ) {
              return 0;
       }

       mi = backend_info( "monitor" );
       if ( !mi || !mi->bi_extra ) {
              SLAP_DBFLAGS( be ) ^= SLAP_DBFLAG_MONITORING;
              return 0;
       }
       mbe = mi->bi_extra;

       /* don't bother if monitor is not configured */
       if ( !mbe->is_configured() ) {
              static int warning = 0;

              if ( warning++ == 0 ) {
                     Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_monitor_db_open)
                            ": monitoring disabled; "
                            "configure monitor database to enable\n",
                            0, 0, 0 );
              }

              return 0;
       }

       /* alloc as many as required (plus 1 for objectClass) */
       a = attrs_alloc( 1 + 1 );
       if ( a == NULL ) {
              rc = 1;
              goto cleanup;
       }

       a->a_desc = slap_schema.si_ad_objectClass;
       attr_valadd( a, &oc_olmMDBDatabase->soc_cname, NULL, 1 );
       next = a->a_next;

       {
              struct berval bv, nbv;
              ber_len_t     pathlen = 0, len = 0;
              char          path[ MAXPATHLEN ] = { '\0' };
              char          *fname = mdb->mi_dbenv_home,
                            *ptr;

              len = strlen( fname );
              if ( fname[ 0 ] != '/' ) {
                     /* get full path name */
                     getcwd( path, sizeof( path ) );
                     pathlen = strlen( path );

                     if ( fname[ 0 ] == '.' && fname[ 1 ] == '/' ) {
                            fname += 2;
                            len -= 2;
                     }
              }

              bv.bv_len = pathlen + STRLENOF( "/" ) + len;
              ptr = bv.bv_val = ch_malloc( bv.bv_len + STRLENOF( "/" ) + 1 );
              if ( pathlen ) {
                     ptr = lutil_strncopy( ptr, path, pathlen );
                     ptr[ 0 ] = '/';
                     ptr++;
              }
              ptr = lutil_strncopy( ptr, fname, len );
              if ( ptr[ -1 ] != '/' ) {
                     ptr[ 0 ] = '/';
                     ptr++;
              }
              ptr[ 0 ] = '\0';
              
              attr_normalize_one( ad_olmDbDirectory, &bv, &nbv, NULL );

              next->a_desc = ad_olmDbDirectory;
              next->a_vals = ch_calloc( sizeof( struct berval ), 2 );
              next->a_vals[ 0 ] = bv;
              next->a_numvals = 1;

              if ( BER_BVISNULL( &nbv ) ) {
                     next->a_nvals = next->a_vals;

              } else {
                     next->a_nvals = ch_calloc( sizeof( struct berval ), 2 );
                     next->a_nvals[ 0 ] = nbv;
              }

              next = next->a_next;
       }

       cb = ch_calloc( sizeof( monitor_callback_t ), 1 );
       cb->mc_update = mdb_monitor_update;
#if 0  /* uncomment if required */
       cb->mc_modify = mdb_monitor_modify;
#endif
       cb->mc_free = mdb_monitor_free;
       cb->mc_private = (void *)mdb;

       /* make sure the database is registered; then add monitor attributes */
       rc = mbe->register_database( be, &mdb->mi_monitor.mdm_ndn );
       if ( rc == 0 ) {
              rc = mbe->register_entry_attrs( &mdb->mi_monitor.mdm_ndn, a, cb,
                     &dummy, 0, &dummy );
       }

cleanup:;
       if ( rc != 0 ) {
              if ( cb != NULL ) {
                     ch_free( cb );
                     cb = NULL;
              }

              if ( a != NULL ) {
                     attrs_free( a );
                     a = NULL;
              }
       }

       /* store for cleanup */
       mdb->mi_monitor.mdm_cb = (void *)cb;

       /* we don't need to keep track of the attributes, because
        * mdb_monitor_free() takes care of everything */
       if ( a != NULL ) {
              attrs_free( a );
       }

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_next_id ( BackendDB be,
MDB_cursor mc,
ID id 
)

Definition at line 24 of file nextid.c.

{
       int rc;
       ID id = 0;
       MDB_val key;

       rc = mdb_cursor_get(mc, &key, NULL, MDB_LAST);

       switch(rc) {
       case MDB_NOTFOUND:
              rc = 0;
              *out = 1;
              break;
       case 0:
              memcpy( &id, key.mv_data, sizeof( id ));
              *out = ++id;
              break;

       default:
              Debug( LDAP_DEBUG_ANY,
                     "=> mdb_next_id: get failed: %s (%d)\n",
                     mdb_strerror(rc), rc, 0 );
              goto done;
       }

done:
       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_opinfo_get ( Operation op,
struct mdb_info mdb,
int  rdonly,
mdb_op_info **  moi 
)

Definition at line 380 of file id2entry.c.

{
       int rc, renew = 0;
       void *data;
       void *ctx;
       mdb_op_info *moi = NULL;
       OpExtra *oex;

       assert( op != NULL );

       if ( !mdb || !moip ) return -1;

       /* If no op was provided, try to find the ctx anyway... */
       if ( op ) {
              ctx = op->o_threadctx;
       } else {
              ctx = ldap_pvt_thread_pool_context();
       }

       if ( op ) {
              LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) {
                     if ( oex->oe_key == mdb ) break;
              }
              moi = (mdb_op_info *)oex;
       }

       if ( !moi ) {
              moi = *moip;

              if ( !moi ) {
                     if ( op ) {
                            moi = op->o_tmpalloc(sizeof(struct mdb_op_info),op->o_tmpmemctx);
                     } else {
                            moi = ch_malloc(sizeof(mdb_op_info));
                     }
                     moi->moi_flag = MOI_FREEIT;
                     *moip = moi;
              }
              LDAP_SLIST_INSERT_HEAD( &op->o_extra, &moi->moi_oe, oe_next );
              moi->moi_oe.oe_key = mdb;
              moi->moi_ref = 0;
              moi->moi_txn = NULL;
       }

       if ( !rdonly ) {
              /* This op started as a reader, but now wants to write. */
              if ( moi->moi_flag & MOI_READER ) {
                     moi = *moip;
                     LDAP_SLIST_INSERT_HEAD( &op->o_extra, &moi->moi_oe, oe_next );
              } else {
              /* This op is continuing an existing write txn */
                     *moip = moi;
              }
              moi->moi_ref++;
              if ( !moi->moi_txn ) {
                     rc = mdb_txn_begin( mdb->mi_dbenv, NULL, 0, &moi->moi_txn );
                     if (rc) {
                            Debug( LDAP_DEBUG_ANY, "mdb_opinfo_get: err %s(%d)\n",
                                   mdb_strerror(rc), rc, 0 );
                     }
                     return rc;
              }
              return 0;
       }

       /* OK, this is a reader */
       if ( !moi->moi_txn ) {
              if ( !ctx ) {
                     /* Shouldn't happen unless we're single-threaded */
                     rc = mdb_txn_begin( mdb->mi_dbenv, NULL, MDB_RDONLY, &moi->moi_txn );
                     if (rc) {
                            Debug( LDAP_DEBUG_ANY, "mdb_opinfo_get: err %s(%d)\n",
                                   mdb_strerror(rc), rc, 0 );
                     }
                     return rc;
              }
              if ( ldap_pvt_thread_pool_getkey( ctx, mdb->mi_dbenv, &data, NULL ) ) {
                     rc = mdb_txn_begin( mdb->mi_dbenv, NULL, MDB_RDONLY, &moi->moi_txn );
                     if (rc) {
                            Debug( LDAP_DEBUG_ANY, "mdb_opinfo_get: err %s(%d)\n",
                                   mdb_strerror(rc), rc, 0 );
                            return rc;
                     }
                     data = moi->moi_txn;
                     if ( ( rc = ldap_pvt_thread_pool_setkey( ctx, mdb->mi_dbenv,
                            data, mdb_reader_free, NULL, NULL ) ) ) {
                            mdb_txn_abort( moi->moi_txn );
                            moi->moi_txn = NULL;
                            Debug( LDAP_DEBUG_ANY, "mdb_opinfo_get: thread_pool_setkey failed err (%d)\n",
                                   rc, 0, 0 );
                            return rc;
                     }
              } else {
                     moi->moi_txn = data;
                     renew = 1;
              }
              moi->moi_flag |= MOI_READER;
       }
       if ( moi->moi_ref < 1 ) {
              moi->moi_ref = 0;
       }
       if ( renew ) {
              mdb_txn_renew( moi->moi_txn );
       }
       moi->moi_ref++;
       if ( *moip != moi )
              *moip = moi;

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 368 of file id2entry.c.

{
       void *data;
       void *ctx = ldap_pvt_thread_pool_context();

       if ( !ldap_pvt_thread_pool_getkey( ctx, env, &data, NULL ) ) {
              ldap_pvt_thread_pool_setkey( ctx, env, NULL, 0, NULL, NULL );
              mdb_reader_free( env, data );
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_tool_idl_add ( MDB_cursor mc,
struct berval keys,
ID  id 
)

Definition at line 1136 of file tools.c.

{
       MDB_dbi dbi;
       mdb_tool_idl_cache *ic, itmp;
       mdb_tool_idl_cache_entry *ice;
       int i, rc, lcount;
       AttrInfo *ai = (AttrInfo *)mc;
       mc = ai->ai_cursor;

       dbi = ai->ai_dbi;
       for (i=0; keys[i].bv_val; i++) {
       itmp.kstr = keys[i];
       ic = tavl_find( (Avlnode *)ai->ai_root, &itmp, mdb_tool_idl_cmp );

       /* No entry yet, create one */
       if ( !ic ) {
              MDB_val key, data;
              ID nid;
              int rc;

              if ( ai->ai_clist ) {
                     ic = ai->ai_clist;
                     ai->ai_clist = ic->head;
              } else {
                     ic = ch_malloc( sizeof( mdb_tool_idl_cache ) + itmp.kstr.bv_len + 4 );
              }
              ic->kstr.bv_len = itmp.kstr.bv_len;
              ic->kstr.bv_val = (char *)(ic+1);
              memcpy( ic->kstr.bv_val, itmp.kstr.bv_val, ic->kstr.bv_len );
              ic->head = ic->tail = NULL;
              ic->last = 0;
              ic->count = 0;
              ic->offset = 0;
              ic->flags = 0;
              tavl_insert( (Avlnode **)&ai->ai_root, ic, mdb_tool_idl_cmp,
                     avl_dup_error );

              /* load existing key count here */
              key.mv_size = keys[i].bv_len;
              key.mv_data = keys[i].bv_val;
              rc = mdb_cursor_get( mc, &key, &data, MDB_SET );
              if ( rc == 0 ) {
                     ic->flags |= WAS_FOUND;
                     nid = *(ID *)data.mv_data;
                     if ( nid == 0 ) {
                            ic->count = MDB_IDL_DB_SIZE+1;
                            ic->flags |= WAS_RANGE;
                     } else {
                            size_t count;

                            mdb_cursor_count( mc, &count );
                            ic->count = count;
                            ic->first = nid;
                            ic->offset = count & (IDBLOCK-1);
                     }
              }
       }
       /* are we a range already? */
       if ( ic->count > MDB_IDL_DB_SIZE ) {
              ic->last = id;
              continue;
       /* Are we at the limit, and converting to a range? */
       } else if ( ic->count == MDB_IDL_DB_SIZE ) {
              if ( ic->head ) {
                     ic->tail->next = ai->ai_flist;
                     ai->ai_flist = ic->head;
              }
              ic->head = ic->tail = NULL;
              ic->last = id;
              ic->count++;
              continue;
       }
       /* No free block, create that too */
       lcount = ic->count & (IDBLOCK-1);
       if ( !ic->tail || lcount == 0) {
              if ( ai->ai_flist ) {
                     ice = ai->ai_flist;
                     ai->ai_flist = ice->next;
              } else {
                     ice = ch_malloc( sizeof( mdb_tool_idl_cache_entry ));
              }
              ice->next = NULL;
              if ( !ic->head ) {
                     ic->head = ice;
              } else {
                     ic->tail->next = ice;
              }
              ic->tail = ice;
              if ( lcount )
                     ice->ids[lcount-1] = 0;
              if ( !ic->count )
                     ic->first = id;
       }
       ice = ic->tail;
       if (!lcount || ice->ids[lcount-1] != id)
              ice->ids[lcount] = id;
       ic->count++;
       }

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

BI_db_config mdb_db_config

Definition at line 137 of file proto-mdb.h.

BI_entry_get_rw mdb_entry_get

Definition at line 180 of file proto-mdb.h.

BI_entry_release_rw mdb_entry_release

Definition at line 179 of file proto-mdb.h.

BI_has_subordinates mdb_hasSubordinates

Definition at line 210 of file proto-mdb.h.

Definition at line 209 of file proto-mdb.h.

BI_operational mdb_operational
BI_tool_dn2id_get mdb_tool_dn2id_get
BI_tool_entry_close mdb_tool_entry_close
BI_tool_entry_first_x mdb_tool_entry_first_x
BI_tool_entry_get mdb_tool_entry_get
BI_tool_entry_modify mdb_tool_entry_modify
BI_tool_entry_next mdb_tool_entry_next
BI_tool_entry_open mdb_tool_entry_open
BI_tool_entry_put mdb_tool_entry_put
BI_tool_entry_reindex mdb_tool_entry_reindex