You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2011/07/01 18:29:21 UTC

svn commit: r1141978 - in /directory/apacheds/branches/apacheds-no-reverse-index: jdbm-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/ xdbm-partition/src/main/java/org/apache/directory/server/xdbm/

Author: elecharny
Date: Fri Jul  1 16:29:21 2011
New Revision: 1141978

URL: http://svn.apache.org/viewvc?rev=1141978&view=rev
Log:
Fixed the move() operation

Modified:
    directory/apacheds/branches/apacheds-no-reverse-index/jdbm-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmStoreTest.java
    directory/apacheds/branches/apacheds-no-reverse-index/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/AbstractStore.java

Modified: directory/apacheds/branches/apacheds-no-reverse-index/jdbm-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmStoreTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-no-reverse-index/jdbm-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmStoreTest.java?rev=1141978&r1=1141977&r2=1141978&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-no-reverse-index/jdbm-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmStoreTest.java (original)
+++ directory/apacheds/branches/apacheds-no-reverse-index/jdbm-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmStoreTest.java Fri Jul  1 16:29:21 2011
@@ -736,34 +736,46 @@ public class JdbmStoreTest
     @Test
     public void testMove() throws Exception
     {
-        Dn childDn = new Dn( schemaManager, "cn=Pivate Ryan,ou=Engineering,o=Good Times Co." );
-        Entry childEntry = new DefaultEntry( schemaManager, childDn );
-        childEntry.add( "objectClass", "top", "person", "organizationalPerson" );
-        childEntry.add( "ou", "Engineering" );
-        childEntry.add( "cn", "Private Ryan" );
-        childEntry.add( "entryCSN", new CsnFactory( 1 ).newInstance().toString() );
-        childEntry.add( "entryUUID", UUID.randomUUID().toString() );
+        Dn childDn = new Dn( schemaManager, "cn=Private Ryan,ou=Apache,ou=Board of Directors,o=Good Times Co." );
+        
+        Entry childEntry = new DefaultEntry( schemaManager, childDn, 
+            "objectClass: top", 
+            "objectClass: person", 
+            "objectClass: organizationalPerson",
+            "ou", "Engineering",
+            "cn", "Private Ryan",
+            "entryCSN", new CsnFactory( 1 ).newInstance().toString(),
+            "entryUUID", UUID.randomUUID().toString() );
 
         store.add( childEntry );
 
-        Dn parentDn = new Dn( schemaManager, "ou=Sales,o=Good Times Co." );
+        Dn oldParentDn = childDn.getParent();
+        long oldParentId = store.getEntryId( oldParentDn );
+        int oldParentCount = store.getChildCount( oldParentId );
+        assertEquals( 2, oldParentCount );
+
+        Dn newParentDn = new Dn( schemaManager, "ou=Sales,o=Good Times Co." );
+        long newParentId = store.getEntryId( newParentDn );
+        int newParentCount = store.getChildCount( newParentId );
+        assertEquals( 2, newParentCount );
 
-        Rdn rdn = new Rdn( "cn=Ryan" );
+        //Rdn rdn = new Rdn( "cn=Ryan" );
 
-        store.moveAndRename( childDn, parentDn, rdn, childEntry, true );
+        //store.moveAndRename( childDn, parentDn, rdn, childEntry, true );
 
         // to drop the alias indices
-        childDn = new Dn( schemaManager, "commonName=Jim Bean,ou=Apache,ou=Board of Directors,o=Good Times Co." );
+        //childDn = new Dn( schemaManager, "commonName=Jim Bean,ou=Apache,ou=Board of Directors,o=Good Times Co." );
 
-        parentDn = new Dn( schemaManager, "ou=Engineering,o=Good Times Co." );
+        //parentDn = new Dn( schemaManager, "ou=Engineering,o=Good Times Co." );
 
-        assertEquals( 3, store.getSubAliasIndex().count() );
+        //assertEquals( 3, store.getSubAliasIndex().count() );
 
-        Dn newDn = parentDn.add( childDn.getRdn() );
+        Dn newDn = newParentDn.add( childDn.getRdn() );
 
-        store.move( childDn, parentDn, newDn, childEntry );
+        store.move( childDn, newParentDn, newDn, childEntry );
 
-        assertEquals( 4, store.getSubAliasIndex().count() );
+        assertEquals( oldParentCount - 1, store.getChildCount( oldParentId ) );
+        assertEquals( newParentCount + 1, store.getChildCount( newParentId ) );
     }
 
 

Modified: directory/apacheds/branches/apacheds-no-reverse-index/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/AbstractStore.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-no-reverse-index/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/AbstractStore.java?rev=1141978&r1=1141977&r2=1141978&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-no-reverse-index/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/AbstractStore.java (original)
+++ directory/apacheds/branches/apacheds-no-reverse-index/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/AbstractStore.java Fri Jul  1 16:29:21 2011
@@ -1004,7 +1004,6 @@ public abstract class AbstractStore<E, I
         oneLevelIdx.add( parentId, newId );
         
         // The subLevel index : we must link all the hierarchy to the added entry.
-        // 
         for ( ID id : parentIds )
         {
             if ( id.equals( rootId ) || id.equals( contextEntryId ) )
@@ -1015,12 +1014,10 @@ public abstract class AbstractStore<E, I
             
             // Add the <ancestor, newId> tuple
             subLevelIdx.add( id, newId );
-            //System.out.println( "Adding <" + id + ", " + newId + ">" );
         }
 
         // making entry an ancestor/descendent of itself in sublevel index
         subLevelIdx.add( newId, newId );
-        //System.out.println( "Adding self <" + newId + ", " + newId + ">" );
 
         // The entryCSN index
         Attribute entryCsn = entry.get( ENTRY_CSN_AT );
@@ -1211,10 +1208,9 @@ public abstract class AbstractStore<E, I
         oneLevelIdx.drop( parentId, id );
         
         // Drop the subLevel index
-        
         for ( ID ancestor : parentIds )
         {
-            if ( ancestor.equals(  rootId ) )
+            if ( ancestor.equals( rootId ) )
             {
                 continue;
             }
@@ -1493,17 +1489,22 @@ public abstract class AbstractStore<E, I
 
         // Get the entry and the old parent IDs
         ID entryId = getEntryId( oldDn );
-        ID oldParentId = getParentId( entryId );
+        List<ID> oldParentIds = getParentIds( oldDn );
+        List<ID> newParentIds = getParentIds( newDn );
+        ID rootId = getRootId();
+        ID oldParentId = rootId;
+        
+        if ( oldParentIds.size() > 2 )
+        {
+            oldParentId = oldParentIds.get( oldParentIds.size() - 1 );
+        }
 
-        /*
-         * All aliases including and below oldChildDn, will be affected by
-         * the move operation with respect to one and subtree userIndices since
-         * their relationship to ancestors above oldChildDn will be
-         * destroyed.  For each alias below and including oldChildDn we will
-         * drop the index tuples mapping ancestor ids above oldChildDn to the
-         * respective target ids of the aliases.
-         */
-        dropMovedAliasIndices( oldDn );
+        ID contextEntryId = rootId;
+        
+        if ( newParentIds.size() > 1 )
+        {
+            contextEntryId = newParentIds.get( 1 );
+        }
 
         /*
          * Drop the old parent child relationship and add the new one
@@ -1512,31 +1513,68 @@ public abstract class AbstractStore<E, I
         oneLevelIdx.drop( oldParentId, entryId );
         oneLevelIdx.add( newParentId, entryId );
 
-        updateSubLevelIndex( entryId, oldParentId, newParentId );
+        // Update the sublevel index
+        // first, drop the old position in the subLevel index
+        for ( ID ancestor : oldParentIds )
+        {
+            if ( ancestor.equals( rootId ) )
+            {
+                continue;
+            }
+            
+            subLevelIdx.drop( ancestor, oldParentId );
+        }
+        
+        // find all the children of the childId
+        Cursor<IndexEntry<ID, E, ID>> cursor = subLevelIdx.forwardCursor( entryId );
 
-        // Update the Rdn index
-        rdnIdx.drop( entryId );
-        ParentIdAndRdn<ID> key = new ParentIdAndRdn<ID>( newParentId, oldDn.getRdn() );
-        rdnIdx.add( key, entryId );
+        List<ID> childIds = new ArrayList<ID>();
+        childIds.add( entryId );
 
+        while ( cursor.next() )
+        {
+            childIds.add( cursor.get().getId() );
+        }
 
-        /*
-         * Read Alias Index Tuples
-         *
-         * If this is a name change due to a move operation then the one and
-         * subtree userIndices for aliases were purged before the aliases were
-         * moved.  Now we must add them for each alias entry we have moved.
-         *
-         * aliasTarget is used as a marker to tell us if we're moving an
-         * alias.  If it is null then the moved entry is not an alias.
-         */
-        String aliasTarget = aliasIdx.reverseLookup( entryId );
+        // detach the childId and all its children from oldParentId and all it parents excluding the root
+        for ( ID pid : oldParentIds )
+        {
+            for ( ID cid : childIds )
+            {
+                subLevelIdx.drop( pid, cid );
+            }
+        }
 
-        if ( null != aliasTarget )
+        // then add the new position in the sublevel index
+        for ( ID id : newParentIds )
         {
-            addAliasIndices( entryId, buildEntryDn( entryId ), aliasTarget );
+            if ( id.equals( rootId ) || id.equals( contextEntryId ) )
+            {
+                // Skip the rootDSE and the context entry
+                continue;
+            }
+            
+            // Add the <ancestor, newId> tuple
+            subLevelIdx.add( id, entryId );
         }
 
+        // attach the childId and all its children to newParentId and all it parents excluding the root
+        for ( ID id : newParentIds )
+        {
+            for ( ID cid : childIds )
+            {
+                subLevelIdx.add( id, cid );
+            }
+        }
+
+        // Update the Rdn index
+        ParentIdAndRdn<ID> oldKey = new ParentIdAndRdn<ID>( oldParentId, oldDn.getRdn() );
+
+        rdnIdx.drop( oldKey, entryId );
+
+        ParentIdAndRdn<ID> newKey = new ParentIdAndRdn<ID>( newParentId, oldDn.getRdn() );
+        rdnIdx.add( newKey, entryId );
+
         // the below case arises only when the move( Dn oldDn, Dn newSuperiorDn, Dn newDn  ) is called
         // directly using the Store API, in this case the value of modified entry will be null
         // we need to lookup the entry to update the parent ID