]> git.sur5r.net Git - openldap/commitdiff
Add prelim index code from LDBM, needs work...
authorKurt Zeilenga <kurt@openldap.org>
Thu, 4 Oct 2001 02:55:09 +0000 (02:55 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Thu, 4 Oct 2001 02:55:09 +0000 (02:55 +0000)
servers/slapd/back-bdb/Makefile.in
servers/slapd/back-bdb/attr.c
servers/slapd/back-bdb/index.c [new file with mode: 0644]
servers/slapd/back-bdb/proto-bdb.h

index 414c89e486a8c95a0aefac9e52ee7b1ab0476f87..c284240f5a823a07ae822c4b3e5481a3392ef8c9 100644 (file)
@@ -3,12 +3,12 @@
 SRCS = init.c tools.c config.c \
        add.c bind.c compare.c delete.c modify.c modrdn.c search.c \
        extended.c passwd.c referral.c \
-       attr.c \
+       attr.c index.c \
        dn2entry.c dn2id.c error.c id2entry.c idl.c nextid.c
 OBJS = init.lo tools.lo config.lo \
        add.lo bind.lo compare.lo delete.lo modify.lo modrdn.lo search.lo \
        extended.lo passwd.lo referral.lo \
-       attr.lo \
+       attr.lo index.lo \
        dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo nextid.lo
 
 LDAP_INCDIR= ../../../include       
index 732e8b69084f20463a14cffd4a802263144b8938..fb69dddb2e233903c611895398831d2b3bbaaee7 100644 (file)
@@ -18,7 +18,7 @@
 #if BDB_CONFIG_INDICES
 
 /* for the cache of attribute information (which are indexed, etc.) */
-typedef struct ldbm_attrinfo {
+typedef struct bdb_attrinfo {
 #ifdef SLAPD_USE_AD
        AttributeDescription *ai_desc; /* attribute description cn;lang-en      */
 #else
diff --git a/servers/slapd/back-bdb/index.c b/servers/slapd/back-bdb/index.c
new file mode 100644 (file)
index 0000000..f549767
--- /dev/null
@@ -0,0 +1,377 @@
+/* index.c - routines for dealing with attribute indexes */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "back-bdb.h"
+
+#if BDB_INDEX
+
+static slap_mask_t index_mask(
+       Backend *be,
+       AttributeDescription *desc,
+       char **dbname,
+       char **atname )
+{
+       AttributeType *at;
+       slap_mask_t mask = 0;
+
+       /* we do not support indexing of binary attributes */
+       if( slap_ad_is_binary( desc ) ) return 0;
+
+       attr_mask( be->be_private, desc->ad_cname->bv_val, &mask );
+
+       if( mask ) {
+               *atname = desc->ad_cname->bv_val;
+               *dbname = desc->ad_cname->bv_val;
+               return mask;
+       }
+
+       if( slap_ad_is_lang( desc ) ) {
+               /* has language tag */
+               attr_mask( be->be_private, desc->ad_type->sat_cname, &mask );
+
+               if( mask & SLAP_INDEX_AUTO_LANG ) {
+                       *atname = desc->ad_cname->bv_val;
+                       *dbname = desc->ad_type->sat_cname;
+                       return mask;
+               }
+               if( mask & SLAP_INDEX_LANG ) {
+                       *atname = desc->ad_type->sat_cname;
+                       *dbname = desc->ad_type->sat_cname;
+                       return mask;
+               }
+       }
+
+       /* see if supertype defined mask for its subtypes */
+       for( at = desc->ad_type; at != NULL ; at = at->sat_sup ) {
+               attr_mask( be->be_private, at->sat_cname, &mask );
+
+               if( mask & SLAP_INDEX_AUTO_SUBTYPES ) {
+                       *atname = desc->ad_type->sat_cname;
+                       *dbname = at->sat_cname;
+                       return mask;
+               }
+               if( mask & SLAP_INDEX_SUBTYPES ) {
+                       *atname = at->sat_cname;
+                       *dbname = at->sat_cname;
+                       return mask;
+               }
+
+               if( mask ) break;
+       }
+
+       return 0;
+}
+
+int bdb_index_param(
+       Backend *be,
+       AttributeDescription *desc,
+       int ftype,
+       char **dbnamep,
+       slap_mask_t *maskp,
+       struct berval **prefixp )
+{
+       slap_mask_t mask;
+       char *dbname;
+       char *atname;
+
+       mask = index_mask( be, desc, &dbname, &atname );
+
+       if( mask == 0 ) {
+               return LDAP_INAPPROPRIATE_MATCHING;
+       }
+
+       switch(ftype) {
+       case LDAP_FILTER_PRESENT:
+               if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) {
+                       goto done;
+               }
+               break;
+
+       case LDAP_FILTER_APPROX:
+               if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) {
+                       goto done;
+               }
+               /* fall thru */
+
+       case LDAP_FILTER_EQUALITY:
+               if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) {
+                       goto done;
+               }
+               break;
+
+       case LDAP_FILTER_SUBSTRINGS:
+               if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) {
+                       goto done;
+               }
+               break;
+
+       default:
+               return LDAP_OTHER;
+       }
+
+       return LDAP_INAPPROPRIATE_MATCHING;
+
+done:
+       *dbnamep = dbname;
+       *prefixp = ber_bvstrdup( atname );
+       *maskp = mask;
+       return LDAP_SUCCESS;
+}
+
+static int indexer(
+       Backend *be,
+       DB_TXN *txn,
+       char *dbname,
+       char *atname,
+       struct berval **vals,
+       ID id,
+       int op,
+       slap_mask_t mask )
+{
+       int rc, i;
+       const char *text;
+       DB *db;
+       AttributeDescription *ad = NULL;
+       struct berval **keys;
+       struct berval prefix;
+
+       assert( mask );
+
+       rc = slap_str2ad( atname, &ad, &text );
+
+       if( rc != LDAP_SUCCESS ) return rc;
+
+       prefix.bv_val = atname;
+       prefix.bv_len = strlen( atname );
+
+       rc = bdb_db_cache( be, dbname, &db );
+       
+       if ( rc != LDAP_SUCCESS ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "index", LDAP_LEVEL_ERR,
+                       "bdb_index_read: Could not open DB %s\n", dbname));
+#else
+               Debug( LDAP_DEBUG_ANY,
+                       "<= bdb_index_read NULL (could not open %s)\n",
+                       dbname, 0, 0 );
+#endif
+
+               ad_free( ad, 1 );
+               return LDAP_OTHER;
+       }
+
+       if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) {
+               key_change( be, db, &prefix, id, op );
+       }
+
+       if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) {
+               rc = ad->ad_type->sat_equality->smr_indexer(
+                       LDAP_FILTER_EQUALITY,
+                       mask,
+                       ad->ad_type->sat_syntax,
+                       ad->ad_type->sat_equality,
+                       &prefix, vals, &keys );
+
+               if( rc == LDAP_SUCCESS && keys != NULL ) {
+                       for( i=0; keys[i] != NULL; i++ ) {
+                               key_change( be, db, keys[i], id, op );
+                       }
+                       ber_bvecfree( keys );
+               }
+       }
+
+       if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) {
+               rc = ad->ad_type->sat_approx->smr_indexer(
+                       LDAP_FILTER_APPROX,
+                       mask,
+                       ad->ad_type->sat_syntax,
+                       ad->ad_type->sat_approx,
+                       &prefix, vals, &keys );
+
+               if( rc == LDAP_SUCCESS && keys != NULL ) {
+                       for( i=0; keys[i] != NULL; i++ ) {
+                               key_change( be, db, keys[i], id, op );
+                       }
+                       ber_bvecfree( keys );
+               }
+       }
+
+       if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) {
+               rc = ad->ad_type->sat_substr->smr_indexer(
+                       LDAP_FILTER_SUBSTRINGS,
+                       mask,
+                       ad->ad_type->sat_syntax,
+                       ad->ad_type->sat_substr,
+                       &prefix, vals, &keys );
+
+               if( rc == LDAP_SUCCESS && keys != NULL ) {
+                       for( i=0; keys[i] != NULL; i++ ) {
+                               key_change( be, db, keys[i], id, op );
+                       }
+                       ber_bvecfree( keys );
+               }
+       }
+
+       ad_free( ad, 1 );
+       return LDAP_SUCCESS;
+}
+
+static int index_at_values(
+       Backend *be,
+       DB_TXN *txn,
+       AttributeType *type,
+       const char *lang,
+       struct berval **vals,
+       ID id,
+       int op,
+       char ** dbnamep,
+       slap_mask_t *maskp )
+{
+       int rc;
+       slap_mask_t mask;
+       slap_mask_t tmpmask = 0;
+       int lindex = 0;
+
+       if( type->sat_sup ) {
+               /* recurse */
+               rc = index_at_values( be, txn,
+                       type->sat_sup, lang,
+                       vals, id, op,
+                       dbnamep, &tmpmask );
+       }
+
+       attr_mask( be->be_private, type->sat_cname, &mask );
+
+       if( mask ) {
+               *dbnamep = type->sat_cname;
+       } else if ( tmpmask & SLAP_INDEX_AUTO_SUBTYPES ) {
+               mask = tmpmask;
+       }
+
+       if( mask ) {
+               rc = indexer( be, txn, *dbnamep,
+                       type->sat_cname,
+                       vals, id, op,
+                       mask );
+       }
+
+       if( lang ) {
+               char *dbname = NULL;
+               size_t tlen = strlen( type->sat_cname );
+               size_t llen = strlen( lang );
+               char *lname = ch_malloc( tlen + llen + sizeof(";") );
+
+               sprintf( lname, "%s;%s", type->sat_cname, lang );
+
+               attr_mask( be->be_private, lname, &tmpmask );
+
+               if( tmpmask ) {
+                       dbname = lname;
+               } else if ( mask & SLAP_INDEX_AUTO_LANG ) {
+                       dbname = *dbnamep;
+                       tmpmask = mask;
+               }
+
+               if( dbname != NULL ) {
+                       rc = indexer( be, txn, dbname, lname,
+                               vals, id, op,
+                               tmpmask );
+               }
+
+               ch_free( lname );
+       }
+
+       return LDAP_SUCCESS;
+}
+
+int bdb_index_values(
+       Backend *be,
+       DB_TXN *txn,
+       AttributeDescription *desc,
+       struct berval **vals,
+       ID id,
+       int op )
+{
+       int rc;
+       char *dbname = NULL;
+       slap_mask_t mask;
+
+       if( slap_ad_is_binary( desc ) ) {
+               /* binary attributes have no index capabilities */
+               return LDAP_SUCCESS;
+       }
+
+       rc = index_at_values( be, txn,
+               desc->ad_type, desc->ad_lang,
+               vals, id, op,
+               &dbname, &mask );
+
+       return rc;
+}
+
+int
+bdb_index_entry(
+       Backend *be,
+       DB_TXN *txn,
+       int op,
+       Entry   *e,
+       Attribute *ap
+)
+{
+       int rc;
+
+#ifdef NEW_LOGGING
+       LDAP_LOG(( "index", LDAP_LEVEL_ENTRY,
+               "index_entry: %s (%s)%ld\n",
+               op == SLAP_INDEX_ADD_OP ? "add" : "del",
+               e->e_dn, e->e_id ));
+#else
+       Debug( LDAP_DEBUG_TRACE, "=> index_entry_%s( %ld, \"%s\" )\n",
+               op == SLAP_INDEX_ADD_OP ? "add" : "del",
+               e->e_id, e->e_dn );
+#endif
+
+       /* add each attribute to the indexes */
+       for ( ; ap != NULL; ap = ap->a_next ) {
+               rc = index_values( be, txn,
+                       ap->a_desc, ap->a_vals, e->e_id, op );
+
+               if( rc != LDAP_SUCCESS ) {
+#ifdef NEW_LOGGING
+                       LDAP_LOG(( "index", LDAP_LEVEL_ENTRY,
+                          "index_entry: success\n" ));
+#else
+                       Debug( LDAP_DEBUG_TRACE,
+                               "<= index_entry_%s( %ld, \"%s\" ) success\n",
+                               op == SLAP_INDEX_ADD_OP ? "add" : "del",
+                               e->e_id, e->e_dn );
+#endif
+                       return rc;
+               }
+       }
+
+#ifdef NEW_LOGGING
+       LDAP_LOG(( "index", LDAP_LEVEL_ENTRY,
+                  "index_entry: success\n" ));
+#else
+       Debug( LDAP_DEBUG_TRACE, "<= index_entry_%s( %ld, \"%s\" ) success\n",
+               op == SLAP_INDEX_ADD_OP ? "add" : "del",
+               e->e_id, e->e_dn );
+#endif
+
+       return LDAP_SUCCESS;
+}
+
+#endif
index 0ee000d280fa7c17c98fa2f7d5c545f49ffa4b56..93711f362dcc3abfab6f22b23af172f00075a52f 100644 (file)
@@ -173,14 +173,31 @@ ID bdb_idl_next( ID *ids, ID *cursor );
  * index.c
  */
 extern int
-bdb_index_param(
+bdb_index_param LDAP_P((
        Backend *be,
        AttributeDescription *desc,
        int ftype,
-       DB **db,
+       char **dbname,
        slap_mask_t *mask,
-       struct berval **prefix );
-       
+       struct berval **prefix ));
+
+extern int
+bdb_index_values LDAP_P((
+       Backend *be,
+       DB_TXN *txn,
+       AttributeDescription *desc,
+       struct berval **vals,
+       ID id,
+       int op ));
+
+int bdb_index_entry LDAP_P(( Backend *be, DB_TXN *t,
+       int r, Entry *e, Attribute *ap ));
+
+#define bdb_index_entry_add(be,t,e,ap) \
+       index_entry((be),(t),SLAP_INDEX_ADD_OP,(e),(ap))
+#define bdb_index_entry_del(be,t,e,ap) \
+       index_entry((be),(t),SLAP_INDEX_DELETE_OP,(e),(ap))
+
 /*
  * key.c
  */