]> git.sur5r.net Git - openldap/commitdiff
Moved IDL cache code to standalone functions.
authorHoward Chu <hyc@openldap.org>
Tue, 22 Apr 2003 05:14:27 +0000 (05:14 +0000)
committerHoward Chu <hyc@openldap.org>
Tue, 22 Apr 2003 05:14:27 +0000 (05:14 +0000)
Use IDL cache in bdb_dn2id_children.

servers/slapd/back-bdb/dn2id.c
servers/slapd/back-bdb/idl.c
servers/slapd/back-bdb/proto-bdb.h

index 24c958145d81a97b7dbcc7b044b5bd611eaa8ac2..aebec37282307977ac268526d5ba2b87854b5992 100644 (file)
@@ -376,6 +376,15 @@ bdb_dn2id_children(
        ((char *)key.data)[0] = DN_ONE_PREFIX;
        AC_MEMCPY( &((char *)key.data)[1], e->e_nname.bv_val, key.size - 1 );
 
+#ifdef SLAP_IDL_CACHE
+       if ( bdb->bi_idl_cache_size ) {
+               rc = bdb_idl_cache_get( bdb, db, &key, NULL );
+               if ( rc != LDAP_NO_SUCH_OBJECT ) {
+                       sl_free( key.data, o->o_tmpmemctx );
+                       return rc;
+               }
+       }
+#endif
        /* we actually could do a empty get... */
        DBTzero( &data );
        data.data = &id;
@@ -513,26 +522,21 @@ bdb_hdb_compare(
        return rc;
 }
 
-/* This function constructs a full DN for a given id.
+/* This function constructs a full DN for a given entry.
  */
 int bdb_fix_dn(
        BackendDB *be,
-       ID id,
        Entry *e
 )
 {
        struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-       idNode *n, *o;
-       int rlen, nrlen;
+       EntryInfo *ei;
+       int rlen = 0, nrlen = 0;
        char *ptr, *nptr;
        
-       ldap_pvt_thread_rdwr_rlock(&bdb->bi_tree_rdwr);
-       o = bdb_find_id_node(id, bdb->bi_tree);
-       rlen = be->be_suffix[0].bv_len + 1;
-       nrlen = be->be_nsuffix[0].bv_len + 1;
-       for (n = o; n && n->i_parent; n=n->i_parent) {
-               rlen += n->i_rdn->rdn.bv_len + 1;
-               nrlen += n->i_rdn->nrdn.bv_len + 1;
+       for ( ei = BEI(e); ei; ei=ei->bei_parent ) {
+               rlen += ei->bei_rdn.bv_len + 1;
+               nrlen += ei->bei_nrdn.bv_len + 1;
        }
        e->e_name.bv_len = rlen - 1;
        e->e_nname.bv_len = nrlen - 1;
@@ -540,16 +544,16 @@ int bdb_fix_dn(
        e->e_nname.bv_val = e->e_name.bv_val + rlen;
        ptr = e->e_name.bv_val;
        nptr = e->e_nname.bv_val;
-       for (n = o; n && n->i_parent; n=n->i_parent) {
-               ptr = lutil_strcopy(ptr, n->i_rdn->rdn.bv_val);
-               *ptr++ = ',';
-               nptr = lutil_strcopy(nptr, n->i_rdn->nrdn.bv_val);
-               *nptr++ = ',';
+       for ( ei = BEI(e); ei; ei=ei->bei_parent ) {
+               ptr = lutil_strcopy(ptr, ei->bei_rdn.bv_val);
+               nptr = lutil_strcopy(nptr, ei->bei_nrdn.bv_val);
+               if ( ei->bei_parent ) {
+                       *ptr++ = ',';
+                       *nptr++ = ',';
+               }
        }
-       ldap_pvt_thread_rdwr_runlock(&bdb->bi_tree_rdwr);
-
-       strcpy(ptr, be->be_suffix[0].bv_val);
-       strcpy(nptr, be->be_nsuffix[0].bv_val);
+       *ptr = '\0';
+       *nptr = '\0';
 
        return 0;
 }
@@ -594,6 +598,11 @@ bdb_dn2id_add(
        key.size = sizeof(ID);
        key.flags = DB_DBT_USERMEM;
 
+#ifdef SLAP_IDL_CACHE
+       if ( bdb->bi_idl_cache_size ) {
+               bdb_idl_cache_del( bdb, db, &key );
+       }
+#endif
        data.data = d;
        data.size = sizeof(diskNode) + rlen + nrlen + 2;
        data.flags = DB_DBT_USERMEM;
@@ -648,6 +657,11 @@ bdb_dn2id_delete(
        data.dlen = data.size;
        data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
 
+#ifdef SLAP_IDL_CACHE
+       if ( bdb->bi_idl_cache_size ) {
+               bdb_idl_cache_del( bdb, db, &key );
+       }
+#endif
        rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags );
        if ( rc ) return rc;
 
@@ -717,54 +731,40 @@ bdb_dn2id_children(
        Entry *e )
 {
        struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
+       DB *db = bdb->bi_dn2id->bdi_db;
+       DBT             key, data;
+       DBC             *cursor;
        int             rc;
        ID              id;
-       idNode *n;
-
-       rc = bdb_dn2id(be, txn, dn, &id, flags);
-       if (rc != 0)
-               return rc;
-
-       ldap_pvt_thread_rdwr_rlock(&bdb->bi_tree_rdwr);
-       n = bdb_find_id_node(id, bdb->bi_tree);
-       ldap_pvt_thread_rdwr_runlock(&bdb->bi_tree_rdwr);
+       diskNode d;
 
-       if (!n->i_kids)
-               return DB_NOTFOUND;
-       else
-               return 0;
-}
+       DBTzero(&key);
+       key.size = sizeof(ID);
+       key.data = &e->e_id;
+       key.flags = DB_DBT_USERMEM;
 
-/* Since we don't store IDLs for onelevel or subtree, we have to construct
- * them on the fly... Perhaps the i_kids tree ought to just be an IDL?
- */
-static int
-insert_one(
-       void *v_n,
-       void *v_ids
-)
-{
-       idNode *n = v_n;
-       ID *ids = v_ids;
-       return bdb_idl_insert(ids, n->i_id);
-}
+#ifdef SLAP_IDL_CACHE
+       if ( bdb->bi_idl_cache_size ) {
+               rc = bdb_idl_cache_get( bdb, db, &key, NULL );
+               if ( rc != LDAP_NO_SUCH_OBJECT ) {
+                       sl_free( key.data, o->o_tmpmemctx );
+                       return rc;
+               }
+       }
+#endif
+       DBTzero(&data);
+       data.ulen = sizeof(d);
+       data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
+       data.dlen = sizeof(d);
 
-static int
-insert_sub(
-       void *v_n,
-       void *v_ids
-)
-{
-       idNode *n = v_n;
-       ID *ids = v_ids;
-       int rc;
+       rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags );
+       if ( rc ) return rc;
 
-       rc = bdb_idl_insert(ids, n->i_id);
-       if (rc == 0) {
-               ldap_pvt_thread_rdwr_rlock(&n->i_kids_rdwr);
-               rc = avl_apply(n->i_kids, insert_sub, ids, -1, AVL_INORDER);
-               ldap_pvt_thread_rdwr_runlock(&n->i_kids_rdwr);
+       rc = cursor->c_get( cursor, &key, &data, DB_FIRST );
+       if ( rc == 0 ) {
+               rc = cursor->c_get( cursor, &key, &data, DB_NEXT_DUP );
        }
+       cursor->c_close( cursor );
        return rc;
 }
 
index 17e56241e80a958dc33e401001463d6572737c46..42bd02dbe2c39888d297742dd040ba364e95df37 100644 (file)
@@ -295,6 +295,146 @@ bdb_show_key(
        }
 }
 
+#ifdef SLAP_IDL_CACHE
+
+/* Find a db/key pair in the IDL cache. If ids is non-NULL,
+ * copy the cached IDL into it, otherwise just return the status.
+ */
+int
+bdb_idl_cache_get(
+       struct bdb_info *bdb,
+       DB                      *db,
+       DBT                     *key,
+       ID                      *ids )
+{
+       bdb_idl_cache_entry_t idl_tmp;
+       bdb_idl_cache_entry_t *matched_idl_entry;
+
+       DBT2bv( key, &idl_tmp.kstr );
+       idl_tmp.db = db;
+       ldap_pvt_thread_rdwr_rlock( &bdb->bi_idl_tree_rwlock );
+       matched_idl_entry = avl_find( bdb->bi_idl_tree, &idl_tmp,
+                                     bdb_idl_entry_cmp );
+       if ( matched_idl_entry != NULL ) {
+               if ( matched_idl_entry->idl && ids )
+                       BDB_IDL_CPY( ids, matched_idl_entry->idl );
+               ldap_pvt_thread_rdwr_runlock( &bdb->bi_idl_tree_rwlock );
+               ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
+               IDL_LRU_DELETE( bdb, matched_idl_entry );
+               IDL_LRU_ADD( bdb, matched_idl_entry );
+               ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
+               if ( matched_idl_entry->idl )
+                       return LDAP_SUCCESS;
+               else
+                       return DB_NOTFOUND;
+       }
+       ldap_pvt_thread_rdwr_runlock( &bdb->bi_idl_tree_rwlock );
+
+       return LDAP_NO_SUCH_OBJECT;
+}
+
+void
+bdb_idl_cache_put(
+       struct bdb_info *bdb,
+       DB                      *db,
+       DBT                     *key,
+       ID                      *ids,
+       int                     rc )
+{
+       bdb_idl_cache_entry_t idl_tmp;
+       bdb_idl_cache_entry_t *ee;
+
+       ee = (bdb_idl_cache_entry_t *) ch_malloc(
+               sizeof( bdb_idl_cache_entry_t ) );
+       ee->db = db;
+       if ( rc == DB_NOTFOUND) {
+               ee->idl = NULL;
+       } else {
+               ee->idl = (ID*) ch_malloc( BDB_IDL_SIZEOF ( ids ) );
+               BDB_IDL_CPY( ee->idl, ids );
+       }
+       ee->idl_lru_prev = NULL;
+       ee->idl_lru_next = NULL;
+       ber_dupbv( &ee->kstr, &idl_tmp.kstr );
+       ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock );
+       if ( avl_insert( &bdb->bi_idl_tree, (caddr_t) ee,
+               bdb_idl_entry_cmp, avl_dup_error ))
+       {
+               ch_free( ee->kstr.bv_val );
+               ch_free( ee->idl );
+               ch_free( ee );
+               ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock );
+               return;
+       }
+       ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
+       IDL_LRU_ADD( bdb, ee );
+       if ( ++bdb->bi_idl_cache_size > bdb->bi_idl_cache_max_size ) {
+               int i = 0;
+               while ( bdb->bi_idl_lru_tail != NULL && i < 10 ) {
+                       ee = bdb->bi_idl_lru_tail;
+                       if ( avl_delete( &bdb->bi_idl_tree, (caddr_t) ee,
+                                   bdb_idl_entry_cmp ) == NULL ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG( INDEX, ERR, 
+                                       "bdb_idl_cache_put: AVL delete failed\n", 
+                                       0, 0, 0 );
+#else
+                               Debug( LDAP_DEBUG_ANY, "=> bdb_idl_cache_put: "
+                                       "AVL delete failed\n",
+                                       0, 0, 0 );
+#endif
+                       }
+                       IDL_LRU_DELETE( bdb, ee );
+                       i++;
+                       --bdb->bi_idl_cache_size;
+                       ch_free( ee->kstr.bv_val );
+                       ch_free( ee->idl );
+                       ch_free( ee );
+               }
+       }
+
+       ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
+       ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock );
+}
+
+void
+bdb_idl_cache_del(
+       struct bdb_info *bdb,
+       DB                      *db,
+       DBT                     *key )
+{
+       bdb_idl_cache_entry_t *matched_idl_entry, idl_tmp;
+       DBT2bv( key, &idl_tmp.kstr );
+       idl_tmp.db = db;
+       ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock );
+       matched_idl_entry = avl_find( bdb->bi_idl_tree, &idl_tmp,
+                                     bdb_idl_entry_cmp );
+       if ( matched_idl_entry != NULL ) {
+               if ( avl_delete( &bdb->bi_idl_tree, (caddr_t) matched_idl_entry,
+                                   bdb_idl_entry_cmp ) == NULL ) {
+#ifdef NEW_LOGGING
+                       LDAP_LOG( INDEX, ERR, 
+                               "bdb_idl_cache_del: AVL delete failed\n", 
+                               0, 0, 0 );
+#else
+                       Debug( LDAP_DEBUG_ANY, "=> bdb_idl_cache_del: "
+                               "AVL delete failed\n",
+                               0, 0, 0 );
+#endif
+               }
+               --bdb->bi_idl_cache_size;
+               ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
+               IDL_LRU_DELETE( bdb, matched_idl_entry );
+               ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
+               free( matched_idl_entry->kstr.bv_val );
+               if ( matched_idl_entry->idl )
+                       free( matched_idl_entry->idl );
+               free( matched_idl_entry );
+       }
+       ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock );
+}
+#endif
+
 int
 bdb_idl_fetch_key(
        BackendDB       *be,
@@ -312,9 +452,6 @@ bdb_idl_fetch_key(
        size_t len;
        int rc2;
        int flags = bdb->bi_db_opflags | DB_MULTIPLE;
-#ifdef SLAP_IDL_CACHE
-       bdb_idl_cache_entry_t idl_tmp;
-#endif
 
        /* If using BerkeleyDB 4.0, the buf must be large enough to
         * grab the entire IDL in one get(), otherwise BDB will leak
@@ -348,27 +485,9 @@ bdb_idl_fetch_key(
        assert( ids != NULL );
 
 #ifdef SLAP_IDL_CACHE
-       if ( bdb->bi_idl_cache_max_size ) {
-               bdb_idl_cache_entry_t *matched_idl_entry;
-               DBT2bv( key, &idl_tmp.kstr );
-               idl_tmp.db = db;
-               ldap_pvt_thread_rdwr_rlock( &bdb->bi_idl_tree_rwlock );
-               matched_idl_entry = avl_find( bdb->bi_idl_tree, &idl_tmp,
-                                             bdb_idl_entry_cmp );
-               if ( matched_idl_entry != NULL ) {
-                       if ( matched_idl_entry->idl )
-                               BDB_IDL_CPY( ids, matched_idl_entry->idl );
-                       ldap_pvt_thread_rdwr_runlock( &bdb->bi_idl_tree_rwlock );
-                       ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
-                       IDL_LRU_DELETE( bdb, matched_idl_entry );
-                       IDL_LRU_ADD( bdb, matched_idl_entry );
-                       ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
-                       if ( matched_idl_entry->idl )
-                               return LDAP_SUCCESS;
-                       else
-                               return DB_NOTFOUND;
-               }
-               ldap_pvt_thread_rdwr_runlock( &bdb->bi_idl_tree_rwlock );
+       if ( bdb->bi_idl_cache_size ) {
+               rc = bdb_idl_cache_get( bdb, db, key, ids );
+               if ( rc != LDAP_NO_SUCH_OBJECT ) return rc;
        }
 #endif
 
@@ -491,58 +610,7 @@ bdb_idl_fetch_key(
 
 #ifdef SLAP_IDL_CACHE
        if ( bdb->bi_idl_cache_max_size ) {
-               bdb_idl_cache_entry_t *ee;
-               ee = (bdb_idl_cache_entry_t *) ch_malloc(
-                       sizeof( bdb_idl_cache_entry_t ) );
-               ee->db = db;
-               if ( rc == DB_NOTFOUND) {
-                       ee->idl = NULL;
-               } else {
-                       ee->idl = (ID*) ch_malloc( BDB_IDL_SIZEOF ( ids ) );
-                       BDB_IDL_CPY( ee->idl, ids );
-               }
-               ee->idl_lru_prev = NULL;
-               ee->idl_lru_next = NULL;
-               ber_dupbv( &ee->kstr, &idl_tmp.kstr );
-               ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock );
-               if ( avl_insert( &bdb->bi_idl_tree, (caddr_t) ee,
-                       bdb_idl_entry_cmp, avl_dup_error ))
-               {
-                       ch_free( ee->kstr.bv_val );
-                       ch_free( ee->idl );
-                       ch_free( ee );
-                       ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock );
-                       return rc;
-               }
-               ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
-               IDL_LRU_ADD( bdb, ee );
-               if ( ++bdb->bi_idl_cache_size > bdb->bi_idl_cache_max_size ) {
-                       int i = 0;
-                       while ( bdb->bi_idl_lru_tail != NULL && i < 10 ) {
-                               ee = bdb->bi_idl_lru_tail;
-                               if ( avl_delete( &bdb->bi_idl_tree, (caddr_t) ee,
-                                           bdb_idl_entry_cmp ) == NULL ) {
-#ifdef NEW_LOGGING
-                                       LDAP_LOG( INDEX, ERR, 
-                                               "bdb_idl_fetch_key: AVL delete failed\n", 
-                                               0, 0, 0 );
-#else
-                                       Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: "
-                                               "AVL delete failed\n",
-                                               0, 0, 0 );
-#endif
-                               }
-                               IDL_LRU_DELETE( bdb, ee );
-                               i++;
-                               --bdb->bi_idl_cache_size;
-                               ch_free( ee->kstr.bv_val );
-                               ch_free( ee->idl );
-                               ch_free( ee );
-                       }
-               }
-
-               ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
-               ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock );
+               bdb_idl_cache_put( bdb, db, key, ids, rc );
        }
 #endif
 
@@ -582,35 +650,7 @@ bdb_idl_insert_key(
 
 #ifdef SLAP_IDL_CACHE
        if ( bdb->bi_idl_cache_size ) {
-               bdb_idl_cache_entry_t *matched_idl_entry, idl_tmp;
-               DBT2bv( key, &idl_tmp.kstr );
-               idl_tmp.db = db;
-               ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock );
-               matched_idl_entry = avl_find( bdb->bi_idl_tree, &idl_tmp,
-                                             bdb_idl_entry_cmp );
-               if ( matched_idl_entry != NULL ) {
-                       if ( avl_delete( &bdb->bi_idl_tree, (caddr_t) matched_idl_entry,
-                                           bdb_idl_entry_cmp ) == NULL ) {
-#ifdef NEW_LOGGING
-                               LDAP_LOG( INDEX, ERR, 
-                                       "bdb_idl_fetch_key: AVL delete failed\n", 
-                                       0, 0, 0 );
-#else
-                               Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: "
-                                       "AVL delete failed\n",
-                                       0, 0, 0 );
-#endif
-                       }
-                       --bdb->bi_idl_cache_size;
-                       ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
-                       IDL_LRU_DELETE( bdb, matched_idl_entry );
-                       ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
-                       free( matched_idl_entry->kstr.bv_val );
-                       if ( matched_idl_entry->idl )
-                               free( matched_idl_entry->idl );
-                       free( matched_idl_entry );
-               }
-               ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock );
+               bdb_idl_cache_del( bdb, db, key );
        }
 #endif
 
@@ -807,35 +847,7 @@ bdb_idl_delete_key(
 
 #ifdef SLAP_IDL_CACHE
        if ( bdb->bi_idl_cache_max_size ) {
-               bdb_idl_cache_entry_t *matched_idl_entry, idl_tmp;
-               DBT2bv( key, &idl_tmp.kstr );
-               idl_tmp.db = db;
-               ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock );
-               matched_idl_entry = avl_find( bdb->bi_idl_tree, &idl_tmp,
-                                             bdb_idl_entry_cmp );
-               if ( matched_idl_entry != NULL ) {
-                       if ( avl_delete( &bdb->bi_idl_tree, (caddr_t) matched_idl_entry,
-                                           bdb_idl_entry_cmp ) == NULL ) {
-#ifdef NEW_LOGGING
-                               LDAP_LOG( INDEX, ERR, 
-                                       "bdb_idl_fetch_key: AVL delete failed\n", 
-                                       0, 0, 0 );
-#else
-                               Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: "
-                                       "AVL delete failed\n",
-                                       0, 0, 0 );
-#endif
-                       }
-                       --bdb->bi_idl_cache_size;
-                       ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
-                       IDL_LRU_DELETE( bdb, matched_idl_entry );
-                       ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
-                       free( matched_idl_entry->kstr.bv_val );
-                       if ( matched_idl_entry->idl )
-                               free( matched_idl_entry->idl );
-                       free( matched_idl_entry );
-               }
-               ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock );
+               bdb_idl_cache_del( bdb, db, key );
        }
 #endif
 
index bbfa5b4d20c630ab3da278c79ef6e7926f118506..43a6f5486966f936100ec5315f7ccf0d7e21ffc4 100644 (file)
@@ -145,6 +145,26 @@ void bdb_entry_free ( Entry *e );
  */
 #ifdef SLAP_IDL_CACHE
 int bdb_idl_entry_cmp( const void*, const void* );
+
+int bdb_idl_cache_get(
+       struct bdb_info *bdb,
+       DB *db,
+       DBT *key,
+       ID *ids );
+
+void
+bdb_idl_cache_put(
+       struct bdb_info *bdb,
+       DB              *db,
+       DBT             *key,
+       ID              *ids,
+       int             rc );
+
+void
+bdb_idl_cache_del(
+       struct bdb_info *bdb,
+       DB              *db,
+       DBT             *key );
 #endif
 
 unsigned bdb_idl_search( ID *ids, ID id );