]> git.sur5r.net Git - openldap/commitdiff
Subtree rename support for the cache
authorHoward Chu <hyc@openldap.org>
Wed, 23 Apr 2003 08:46:23 +0000 (08:46 +0000)
committerHoward Chu <hyc@openldap.org>
Wed, 23 Apr 2003 08:46:23 +0000 (08:46 +0000)
servers/slapd/back-bdb/back-bdb.h
servers/slapd/back-bdb/cache.c
servers/slapd/back-bdb/dn2id.c
servers/slapd/back-bdb/proto-bdb.h

index 8c850999799dfd53d3dce4f959c16e0514483ffc..bd789d43cb341d5c8d16e77450f557e842a3f00b 100644 (file)
@@ -92,6 +92,7 @@ typedef struct bdb_entry_info {
        struct berval bei_nrdn;
 #ifdef BDB_HIER
        struct berval bei_rdn;
+       int     bei_modrdns;
 #endif
        Entry   *bei_e;
        Avlnode *bei_kids;
index 069dcaec5a0f08c724072aed229560ebdb916924..b4d0c9f2313b2f6190a91b6b49f7b66abad35883 100644 (file)
@@ -260,6 +260,9 @@ bdb_entryinfo_add_internal(
                                        elru->bei_lrunext = NULL;
                                        elru->bei_lruprev = NULL;
                                        elru->bei_state = 0;
+#ifdef BDB_HIER
+                                       elru->bei_modrdns = 0;
+#endif
                                        ei2 = elru;
                                }
                                if (cache->c_cursize < cache->c_maxsize)
@@ -561,15 +564,29 @@ bdb_cache_find_id(
                                        *eip, 1, 0, lock );
                                ep->e_private = *eip;
 #ifdef BDB_HIER
-                               bdb_fix_dn( ep );
+                               bdb_fix_dn( ep, 0 );
 #endif
                                (*eip)->bei_e = ep;
                                bdb_cache_entry_db_relock( bdb->bi_dbenv, locker,
                                        *eip, 0, 0, lock );
                        }
                } else {
+#ifdef BDB_HIER
+                       rc = bdb_fix_dn( (*eip)->bei_e, 1 );
+                       if ( rc ) {
+                               bdb_cache_entry_db_lock( bdb->bi_dbenv,
+                                       locker, *eip, 1, 0, lock );
+                               rc = bdb_fix_dn( (*eip)->bei_e, 2 );
+                               bdb_cache_entry_db_relock( bdb->bi_dbenv,
+                                       locker, *eip, 0, 0, lock );
+                       } else {
+                               bdb_cache_entry_db_lock( bdb->bi_dbenv,
+                                       locker, *eip, 0, 0, lock );
+                       }
+#else
                        bdb_cache_entry_db_lock( bdb->bi_dbenv, locker,
                                        *eip, 0, 0, lock );
+#endif
                }
        }
        if ( rc == 0 && (*eip)->bei_kids == NULL ) {
@@ -731,6 +748,16 @@ bdb_cache_modrdn(
                bdb_cache_entryinfo_unlock( pei );
                bdb_cache_entryinfo_lock( ein );
        }
+#ifdef BDB_HIER
+       { int max = ei->bei_modrdns;
+       /* Record the generation number of this change */
+               for ( pei = ein; pei->bei_parent; pei = pei->bei_parent ) {
+                       if ( pei->bei_modrdns > max )
+                               max = pei->bei_modrdns;
+               }
+               ei->bei_modrdns = max + 1;
+       }
+#endif
        avl_insert( &ein->bei_kids, ei, bdb_rdn_cmp, avl_dup_error );
        bdb_cache_entryinfo_unlock( ein );
        return rc;
index fa0c7e601f78165b7112600decce1327a82e1e54..eed36ae231495031254ce4f4c7f83f0eeaaefbe6 100644 (file)
@@ -545,17 +545,34 @@ bdb_dup_compare(
 /* This function constructs a full DN for a given entry.
  */
 int bdb_fix_dn(
-       Entry *e
+       Entry *e,
+       int checkit
 )
 {
        EntryInfo *ei;
        int rlen = 0, nrlen = 0;
        char *ptr, *nptr;
+       int max = 0;
        
        for ( ei = BEI(e); ei && ei->bei_id; ei=ei->bei_parent ) {
                rlen += ei->bei_rdn.bv_len + 1;
                nrlen += ei->bei_nrdn.bv_len + 1;
+               if (ei->bei_modrdns > max) max = ei->bei_modrdns;
        }
+
+       /* See if the entry DN was invalidated by a subtree rename */
+       if ( checkit ) {
+               if ( BEI(e)->bei_modrdns >= max ) {
+                       return 0;
+               }
+               /* We found a mismatch, tell the caller to lock it */
+               if ( checkit == 1 ) {
+                       return 1;
+               }
+               /* checkit == 2. do the fix. */
+               free( e->e_name.bv_val );
+       }
+
        e->e_name.bv_len = rlen - 1;
        e->e_nname.bv_len = nrlen - 1;
        e->e_name.bv_val = ch_malloc(rlen + nrlen);
@@ -570,6 +587,7 @@ int bdb_fix_dn(
                        *nptr++ = ',';
                }
        }
+       BEI(e)->bei_modrdns = max;
        ptr[-1] = '\0';
        nptr[-1] = '\0';
 
index 5ea2d12b69af2a6ff2197be73312eb44094099e3..2c3d16a5341a370ce9e95ae50a1045f816c1bbac 100644 (file)
@@ -114,7 +114,7 @@ int bdb_dup_compare(
        const DBT *usrkey,
        const DBT *curkey );
 
-int bdb_fix_dn( Entry *e );
+int bdb_fix_dn( Entry *e, int checkit );
 #endif