directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kayyag...@apache.org
Subject svn commit: r1000076 - /directory/apacheds/trunk/ldif-partition/src/main/java/org/apache/directory/server/core/partition/ldif/SingleFileLdifPartition.java
Date Wed, 22 Sep 2010 16:37:15 GMT
Author: kayyagari
Date: Wed Sep 22 16:37:15 2010
New Revision: 1000076

URL: http://svn.apache.org/viewvc?rev=1000076&view=rev
Log:
o implemented rename() method
o added a method to replace existing entry in the LDIF file
o formatting and code cleanup

Modified:
    directory/apacheds/trunk/ldif-partition/src/main/java/org/apache/directory/server/core/partition/ldif/SingleFileLdifPartition.java

Modified: directory/apacheds/trunk/ldif-partition/src/main/java/org/apache/directory/server/core/partition/ldif/SingleFileLdifPartition.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/ldif-partition/src/main/java/org/apache/directory/server/core/partition/ldif/SingleFileLdifPartition.java?rev=1000076&r1=1000075&r2=1000076&view=diff
==============================================================================
--- directory/apacheds/trunk/ldif-partition/src/main/java/org/apache/directory/server/core/partition/ldif/SingleFileLdifPartition.java
(original)
+++ directory/apacheds/trunk/ldif-partition/src/main/java/org/apache/directory/server/core/partition/ldif/SingleFileLdifPartition.java
Wed Sep 22 16:37:15 2010
@@ -42,6 +42,8 @@ import org.apache.directory.server.core.
 import org.apache.directory.server.core.interceptor.context.RenameOperationContext;
 import org.apache.directory.server.core.partition.impl.avl.AvlPartition;
 import org.apache.directory.server.i18n.I18n;
+import org.apache.directory.server.xdbm.IndexCursor;
+import org.apache.directory.server.xdbm.IndexEntry;
 import org.apache.directory.server.xdbm.impl.avl.AvlStore;
 import org.apache.directory.shared.ldap.constants.SchemaConstants;
 import org.apache.directory.shared.ldap.entry.DefaultEntry;
@@ -69,11 +71,8 @@ public class SingleFileLdifPartition ext
     /** the LDIF file holding the partition's data */
     private RandomAccessFile ldifFile;
 
-    /** a temporary file used for swapping contents while performing update operations */
-    private RandomAccessFile tempBufFile;
-
     /** offset map for entries in the ldif file */
-    Map<Comparable, EntryOffset> offsetMap = new HashMap<Comparable, EntryOffset>();
+    Map<Long, EntryOffset> offsetMap = new HashMap<Long, EntryOffset>();
 
     /** file name of the underlying LDIF store */
     private String fileName;
@@ -98,11 +97,6 @@ public class SingleFileLdifPartition ext
         {
             ldifFile = new RandomAccessFile( file, "rws" );
             fileName = file;
-
-            File tmpFile = File.createTempFile( "ldifpartition", ".buf" );
-            tmpFile.deleteOnExit();
-
-            tempBufFile = new RandomAccessFile( tmpFile.getAbsolutePath(), "rws" );
         }
         catch ( IOException e )
         {
@@ -173,10 +167,10 @@ public class SingleFileLdifPartition ext
             addMandatoryOpAt( contextEntry );
             store.add( contextEntry );
 
-            Comparable id = store.getEntryId( suffix );
-            EntryOffset entryOffset = new EntryOffset( id, curEnryStart, curEntryEnd );
+            Long entryId = ( Long ) store.getEntryId( suffix );
+            EntryOffset entryOffset = new EntryOffset( entryId, curEnryStart, curEntryEnd
);
 
-            offsetMap.put( id, entryOffset );
+            offsetMap.put( entryId, entryOffset );
         }
         else
         {
@@ -203,10 +197,10 @@ public class SingleFileLdifPartition ext
             addMandatoryOpAt( entry );
             store.add( entry );
 
-            Comparable id = store.getEntryId( entry.getDn() );
-            EntryOffset offset = new EntryOffset( id, tmpStart, tmpEnd );
+            Long entryId = ( Long ) store.getEntryId( entry.getDn() );
+            EntryOffset offset = new EntryOffset( entryId, tmpStart, tmpEnd );
 
-            offsetMap.put( id, offset );
+            offsetMap.put( entryId, offset );
         }
 
         parser.close();
@@ -227,7 +221,7 @@ public class SingleFileLdifPartition ext
         Entry entry = addContext.getEntry();
 
         DN dn = entry.getDn();
-        Long id = wrappedPartition.getEntryId( dn );
+        Long entryId = wrappedPartition.getEntryId( dn );
 
         String ldif = LdifUtils.convertEntryToLdif( entry );
 
@@ -236,7 +230,7 @@ public class SingleFileLdifPartition ext
             if ( dn.equals( suffix ) )
             {
                 contextEntry = entry;
-                appendLdif( id, null, ldif );
+                appendLdif( entryId, null, ldif );
                 return;
             }
 
@@ -245,11 +239,11 @@ public class SingleFileLdifPartition ext
             EntryOffset parentOffset = offsetMap.get( parentId );
             if ( parentOffset.getEnd() == ldifFile.length() )
             {
-                appendLdif( id, parentOffset, ldif );
+                appendLdif( entryId, parentOffset, ldif );
             }
             else
             {
-                insertNAppendLdif( id, parentOffset, ldif );
+                insertNAppendLdif( entryId, parentOffset, ldif );
             }
         }
         catch ( IOException e )
@@ -267,66 +261,46 @@ public class SingleFileLdifPartition ext
         Entry entry = modifyContext.getAlteredEntry();
 
         DN dn = entry.getDn();
-        Long id = wrappedPartition.getEntryId( dn );
+        Long entryId = wrappedPartition.getEntryId( dn );
 
         String ldif = LdifUtils.convertEntryToLdif( entry );
 
-        byte[] utf8Data = StringTools.getBytesUtf8( ldif + "\n" );
+        replaceLdif( entryId, ldif );
+    }
 
-        EntryOffset entryOffset = offsetMap.get( id );
+
+    @Override
+    public synchronized void rename( RenameOperationContext renameContext ) throws LdapException
+    {
+        Long id = wrappedPartition.getEntryId( renameContext.getDn() );
+
+        wrappedPartition.rename( renameContext );
 
         try
         {
-            long fileLen = ldifFile.length();
-            long diff = utf8Data.length - entryOffset.length();
+            // perform for the first id
+            Entry entry = wrappedPartition.lookup( id );
+            String ldif = LdifUtils.convertEntryToLdif( entry );
+            replaceLdif( id, ldif );
 
-            // check if modified entry occupies the same space
-            if ( diff == 0 )
-            {
-                ldifFile.seek( entryOffset.getStart() );
-                ldifFile.write( utf8Data );
-            }
-            else if ( fileLen == entryOffset.getEnd() ) // modified entry is at the end of
file
-            {
-                ldifFile.setLength( entryOffset.getStart() );
-                ldifFile.write( utf8Data );
-
-                fileLen = ldifFile.length();
+            IndexCursor<Long, Entry, Long> cursor = wrappedPartition.getOneLevelIndex().forwardCursor(
id );
+            cursor.beforeFirst();
 
-                // change the offsets, the modified entry size changed
-                if ( fileLen != entryOffset.getEnd() )
-                {
-                    entryOffset = new EntryOffset( id, entryOffset.getStart(), fileLen );
-                    offsetMap.put( id, entryOffset );
-                }
-            }
-            else
-            // modified entry size got changed and is in the middle somewhere
+            while ( cursor.next() )
             {
-                FileChannel tmpBufChannel = tempBufFile.getChannel();
-                FileChannel mainChannel = ldifFile.getChannel();
+                IndexEntry<Long, Entry, Long> idxEntry = cursor.get();
 
-                // clear the buffer
-                tempBufFile.setLength( 0 );
+                Long tmpId = idxEntry.getId();
+                entry = wrappedPartition.lookup( tmpId );
+                ldif = LdifUtils.convertEntryToLdif( entry );
+                replaceLdif( tmpId, ldif );
 
-                long count = ( ldifFile.length() - entryOffset.getEnd() );
-
-                mainChannel.transferTo( entryOffset.getEnd(), count, tmpBufChannel );
-                ldifFile.setLength( entryOffset.getStart() );
-
-                Set<EntryOffset> belowParentOffsets = greaterThan( entryOffset );
-
-                entryOffset = appendLdif( id, getAboveEntry( entryOffset ), ldif );
-
-                for ( EntryOffset o : belowParentOffsets )
-                {
-                    o.changeOffsetsBy( diff );
-                }
-
-                tmpBufChannel.transferTo( 0, tmpBufChannel.size(), mainChannel );
+                replaceRecursive( tmpId, null );
             }
+
+            cursor.close();
         }
-        catch ( IOException e )
+        catch ( Exception e )
         {
             throw new LdapException( e );
         }
@@ -334,13 +308,6 @@ public class SingleFileLdifPartition ext
 
 
     @Override
-    public void rename( RenameOperationContext renameContext ) throws LdapException
-    {
-        wrappedPartition.rename( renameContext );
-    }
-
-
-    @Override
     public void move( MoveOperationContext moveContext ) throws LdapException
     {
         wrappedPartition.move( moveContext );
@@ -375,12 +342,9 @@ public class SingleFileLdifPartition ext
             }
             else
             {
-                FileChannel tmpBufChannel = tempBufFile.getChannel();
+                FileChannel tmpBufChannel = createTempBuf();
                 FileChannel mainChannel = ldifFile.getChannel();
 
-                // clear the buffer
-                tempBufFile.setLength( 0 );
-
                 long count = ( ldifFile.length() - entryOffset.getEnd() );
 
                 mainChannel.transferTo( entryOffset.getEnd(), count, tmpBufChannel );
@@ -389,17 +353,18 @@ public class SingleFileLdifPartition ext
                 Set<EntryOffset> belowParentOffsets = greaterThan( entryOffset );
 
                 long diff = entryOffset.length();
-                diff -= (2 * diff); // this offset change should always be negative
-                
+                diff -= ( 2 * diff ); // this offset change should always be negative
+
                 for ( EntryOffset o : belowParentOffsets )
                 {
                     o.changeOffsetsBy( diff );
                 }
 
                 tmpBufChannel.transferTo( 0, tmpBufChannel.size(), mainChannel );
+                tmpBufChannel.truncate( 0 );
             }
         }
-        catch( IOException e )
+        catch ( IOException e )
         {
             throw new LdapException( e );
         }
@@ -419,7 +384,7 @@ public class SingleFileLdifPartition ext
     {
         for ( EntryOffset e : offsetMap.values() )
         {
-            if( e.getEnd() == offset.getStart() )
+            if ( e.getEnd() == offset.getStart() )
             {
                 return e;
             }
@@ -431,6 +396,56 @@ public class SingleFileLdifPartition ext
 
 
     /**
+     * replaces entries present at ONE level scope of a parent entry in a recursive manner
+     *
+     * @param id the parent entry's id
+     * @param cursorMap the map which holds open cursors
+     * @throws Exception
+     */
+    private void replaceRecursive( Long id, Map<Long, IndexCursor<Long, Entry, Long>>
cursorMap ) throws Exception
+    {
+        IndexCursor<Long, Entry, Long> cursor = null;
+        if ( cursorMap == null )
+        {
+            cursorMap = new HashMap<Long, IndexCursor<Long, Entry, Long>>();
+        }
+
+        cursor = cursorMap.get( id );
+
+        if ( cursor == null )
+        {
+            cursor = wrappedPartition.getOneLevelIndex().forwardCursor( id );
+            cursor.beforeFirst();
+            cursorMap.put( id, cursor );
+        }
+
+        if ( !cursor.next() ) // if this is a leaf entry's DN
+        {
+            cursorMap.remove( id );
+            cursor.close();
+        }
+        else
+        {
+            do
+            {
+                IndexEntry<Long, Entry, Long> idxEntry = cursor.get();
+                Entry entry = wrappedPartition.lookup( idxEntry.getId() );
+
+                Long entryId = wrappedPartition.getEntryId( entry.getDn() );
+                String ldif = LdifUtils.convertEntryToLdif( entry );
+
+                replaceLdif( entryId, ldif );
+
+                replaceRecursive( entryId, cursorMap );
+            }
+            while ( cursor.next() );
+            cursorMap.remove( id );
+            cursor.close();
+        }
+    }
+
+
+    /**
      * inserts a given LDIF entry in the middle of the LDIF entries
      *
      * @param entryId the entry's id
@@ -438,7 +453,7 @@ public class SingleFileLdifPartition ext
      * @param ldif the entry's ldif to be injected
      * @throws LdapException
      */
-    private void insertNAppendLdif( Comparable<Long> entryId, EntryOffset aboveEntryOffset,
String ldif )
+    private void insertNAppendLdif( Long entryId, EntryOffset aboveEntryOffset, String ldif
)
         throws LdapException
     {
         if ( aboveEntryOffset == null )
@@ -448,12 +463,9 @@ public class SingleFileLdifPartition ext
 
         try
         {
-            FileChannel tmpBufChannel = tempBufFile.getChannel();
+            FileChannel tmpBufChannel = createTempBuf();
             FileChannel mainChannel = ldifFile.getChannel();
 
-            // clear the buffer
-            tempBufFile.setLength( 0 );
-
             long count = ( ldifFile.length() - aboveEntryOffset.getEnd() );
 
             mainChannel.transferTo( aboveEntryOffset.getEnd(), count, tmpBufChannel );
@@ -471,6 +483,74 @@ public class SingleFileLdifPartition ext
             }
 
             tmpBufChannel.transferTo( 0, tmpBufChannel.size(), mainChannel );
+            tmpBufChannel.truncate( 0 );
+        }
+        catch ( IOException e )
+        {
+            throw new LdapException( e );
+        }
+    }
+
+
+    /**
+     * replaces an existing entry
+     *
+     * @param entryId the entry's id
+     * @param ldif entry data in LDIF
+     * @throws LdapException
+     */
+    private void replaceLdif( Long entryId, String ldif ) throws LdapException
+    {
+        try
+        {
+            EntryOffset entryOffset = offsetMap.get( entryId );
+            byte[] utf8Data = StringTools.getBytesUtf8( ldif + "\n" );
+            long fileLen = ldifFile.length();
+            long diff = utf8Data.length - entryOffset.length();
+
+            // check if modified entry occupies the same space
+            if ( diff == 0 )
+            {
+                ldifFile.seek( entryOffset.getStart() );
+                ldifFile.write( utf8Data );
+            }
+            else if ( fileLen == entryOffset.getEnd() ) // modified entry is at the end of
file
+            {
+                ldifFile.setLength( entryOffset.getStart() );
+                ldifFile.write( utf8Data );
+
+                fileLen = ldifFile.length();
+
+                // change the offsets, the modified entry size changed
+                if ( fileLen != entryOffset.getEnd() )
+                {
+                    entryOffset = new EntryOffset( entryId, entryOffset.getStart(), fileLen
);
+                    offsetMap.put( entryId, entryOffset );
+                }
+            }
+            else
+            // modified entry size got changed and is in the middle somewhere
+            {
+                FileChannel tmpBufChannel = createTempBuf();
+                FileChannel mainChannel = ldifFile.getChannel();
+
+                long count = ( ldifFile.length() - entryOffset.getEnd() );
+
+                mainChannel.transferTo( entryOffset.getEnd(), count, tmpBufChannel );
+                ldifFile.setLength( entryOffset.getStart() );
+
+                Set<EntryOffset> belowParentOffsets = greaterThan( entryOffset );
+
+                entryOffset = appendLdif( entryId, getAboveEntry( entryOffset ), ldif );
+
+                for ( EntryOffset o : belowParentOffsets )
+                {
+                    o.changeOffsetsBy( diff );
+                }
+
+                tmpBufChannel.transferTo( 0, tmpBufChannel.size(), mainChannel );
+                tmpBufChannel.truncate( 0 );
+            }
         }
         catch ( IOException e )
         {
@@ -487,7 +567,7 @@ public class SingleFileLdifPartition ext
      * @param ldif
      * @throws LdapException
      */
-    private EntryOffset appendLdif( Comparable<Long> entryId, EntryOffset aboveEntryOffset,
String ldif )
+    private EntryOffset appendLdif( Long entryId, EntryOffset aboveEntryOffset, String ldif
)
         throws LdapException
     {
         try
@@ -612,6 +692,19 @@ public class SingleFileLdifPartition ext
             entry.add( SchemaConstants.ENTRY_UUID_AT, uuid );
         }
     }
+
+
+    /** a temporary file used for swapping contents while performing update operations */
+    private FileChannel createTempBuf() throws IOException
+    {
+        File tmpFile = File.createTempFile( "ldifpartition", ".buf" );
+        tmpFile.deleteOnExit();
+
+        RandomAccessFile tempBufFile = new RandomAccessFile( tmpFile.getAbsolutePath(), "rws"
);
+        tempBufFile.setLength( 0 );
+
+        return tempBufFile.getChannel();
+    }
 }
 
 /**
@@ -627,10 +720,10 @@ class EntryOffset implements Comparable<
     private long end;
 
     /** entry id */
-    private Comparable id;
+    private Long id;
 
 
-    public EntryOffset( Comparable id, long start, long end )
+    public EntryOffset( Long id, long start, long end )
     {
         this.start = start;
         this.end = end;
@@ -665,7 +758,7 @@ class EntryOffset implements Comparable<
     }
 
 
-    public Comparable getId()
+    public Long getId()
     {
         return id;
     }
@@ -685,6 +778,42 @@ class EntryOffset implements Comparable<
 
 
     @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ( ( id == null ) ? 0 : id.hashCode() );
+        return result;
+    }
+
+
+    @Override
+    public boolean equals( Object obj )
+    {
+        if ( !( obj instanceof EntryOffset ) )
+        {
+            return false;
+        }
+
+        EntryOffset other = ( EntryOffset ) obj;
+
+        if ( id == null )
+        {
+            if ( other.id != null )
+            {
+                return false;
+            }
+        }
+        else if ( !id.equals( other.id ) )
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+
+    @Override
     public String toString()
     {
         return "EntryOffset [start=" + start + ", end=" + end + ", id=" + id + "]";



Mime
View raw message