You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ka...@apache.org on 2010/09/19 12:13:15 UTC
svn commit: r998624 -
/directory/apacheds/trunk/ldif-partition/src/main/java/org/apache/directory/server/core/partition/ldif/SingleFileLdifPartition.java
Author: kayyagari
Date: Sun Sep 19 10:13:15 2010
New Revision: 998624
URL: http://svn.apache.org/viewvc?rev=998624&view=rev
Log:
o added support for inserting LDIF entry in the middle of the other existing entries
o added entry's id to the EntryOffset class
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=998624&r1=998623&r2=998624&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 Sun Sep 19 10:13:15 2010
@@ -21,12 +21,15 @@
package org.apache.directory.server.core.partition.ldif;
-import java.io.FileNotFoundException;
+import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
import java.util.UUID;
import javax.naming.InvalidNameException;
@@ -66,6 +69,9 @@ 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>();
@@ -88,8 +94,13 @@ public class SingleFileLdifPartition ext
try
{
ldifFile = new RandomAccessFile( file, "rws" );
+
+ File tmpFile = File.createTempFile( "ldifpartition", ".buf" );
+ tmpFile.deleteOnExit();
+
+ tempBufFile = new RandomAccessFile( tmpFile.getAbsolutePath(), "rws" );
}
- catch ( FileNotFoundException e )
+ catch ( IOException e )
{
throw new RuntimeException( e );
}
@@ -157,7 +168,11 @@ public class SingleFileLdifPartition ext
{
addMandatoryOpAt( contextEntry );
store.add( contextEntry );
- offsetMap.put( store.getEntryId( suffix ), new EntryOffset( curEnryStart, curEntryEnd ) );
+
+ Comparable id = store.getEntryId( suffix );
+ EntryOffset entryOffset = new EntryOffset( id, curEnryStart, curEntryEnd );
+
+ offsetMap.put( id, entryOffset );
}
else
{
@@ -169,7 +184,8 @@ public class SingleFileLdifPartition ext
while ( itr.hasNext() )
{
- EntryOffset offset = new EntryOffset( curEnryStart, curEntryEnd );
+ long tmpStart = curEnryStart;
+ long tmpEnd = curEntryEnd;
ldifEntry = itr.next();
@@ -182,7 +198,11 @@ public class SingleFileLdifPartition ext
addMandatoryOpAt( entry );
store.add( entry );
- offsetMap.put( store.getEntryId( entry.getDn() ), offset );
+
+ Comparable id = store.getEntryId( entry.getDn() );
+ EntryOffset offset = new EntryOffset( id, tmpStart, tmpEnd );
+
+ offsetMap.put( id, offset );
}
parser.close();
@@ -219,13 +239,13 @@ public class SingleFileLdifPartition ext
// entry has a parent
Long parentId = wrappedPartition.getEntryId( dn.getParent() );
EntryOffset parentOffset = offsetMap.get( parentId );
- if ( parentOffset.end == ldifFile.length() )
+ if ( parentOffset.getEnd() == ldifFile.length() )
{
appendLdif( id, parentOffset, ldif );
}
else
{
- System.out.println( "====================implement insertion====================" );
+ insertLdif( id, parentOffset, ldif );
}
}
catch ( IOException e )
@@ -271,61 +291,85 @@ public class SingleFileLdifPartition ext
/**
- * append data to the LDIF file
+ * inserts a given LDIF entry in the middle of the LDIF file
*
- * @param entryId
- * @param parentOffset
- * @param ldif
+ * @param entryId the entry's id
+ * @param parentOffset entry parent's offsets
+ * @param ldif the entry's ldif to be injected
* @throws LdapException
*/
- private void appendLdif( Comparable<Long> entryId, EntryOffset parentOffset, String ldif ) throws LdapException
+ private void insertLdif( Comparable<Long> entryId, EntryOffset parentOffset, String ldif ) throws LdapException
{
+ if ( parentOffset == null )
+ {
+ throw new IllegalStateException( "parent offset is null" );
+ }
+
try
{
- long pos = 0L;
+ FileChannel tmpBufChannel = tempBufFile.getChannel();
+ FileChannel mainChannel = ldifFile.getChannel();
- if ( parentOffset != null )
- {
- pos = parentOffset.end;
- }
+ // clear the buffer
+ tempBufFile.setLength( 0 );
- ldifFile.seek( pos );
+ long count = ( ldifFile.length() - parentOffset.getEnd() );
- ldifFile.write( StringTools.getBytesUtf8( ldif + "\n" ) );
+ mainChannel.transferTo( parentOffset.getEnd(), count, tmpBufChannel );
+ ldifFile.setLength( parentOffset.getEnd() );
- offsetMap.put( entryId, new EntryOffset( pos, ldifFile.getFilePointer() ) );
+ Set<EntryOffset> belowParentOffsets = greaterThan( parentOffset );
+
+ EntryOffset entryOffset = appendLdif( entryId, parentOffset, ldif );
+
+ long diff = entryOffset.length();
+
+ for ( EntryOffset o : belowParentOffsets )
+ {
+ o.increaseOffsetsBy( diff );
+ }
+
+ tmpBufChannel.transferTo( 0, tmpBufChannel.size(), mainChannel );
}
catch ( IOException e )
{
throw new LdapException( e );
}
}
-
+
/**
- * a holder class for containing an entry's start and end offset positions
- * in the LDIF file
+ * append data to the LDIF file
+ *
+ * @param entryId
+ * @param parentOffset
+ * @param ldif
+ * @throws LdapException
*/
- private class EntryOffset
+ private EntryOffset appendLdif( Comparable<Long> entryId, EntryOffset parentOffset, String ldif )
+ throws LdapException
{
- /** starting position */
- long start;
-
- /** ending position */
- long end;
+ try
+ {
+ long pos = 0L;
+ if ( parentOffset != null )
+ {
+ pos = parentOffset.getEnd();
+ }
- public EntryOffset( long start, long end )
- {
- this.start = start;
- this.end = end;
- }
+ ldifFile.seek( pos );
+ ldifFile.write( StringTools.getBytesUtf8( ldif + "\n" ) );
- @Override
- public String toString()
+ EntryOffset entryOffset = new EntryOffset( entryId, pos, ldifFile.getFilePointer() );
+ offsetMap.put( entryId, entryOffset );
+
+ return entryOffset;
+ }
+ catch ( IOException e )
{
- return "EntryOffset [start=" + start + ", end=" + end + "]";
+ throw new LdapException( e );
}
}
@@ -384,6 +428,29 @@ public class SingleFileLdifPartition ext
/**
+ * gets all the EntryOffset objects whose start pos is greater than the given offset mark's start pos
+ *
+ * @param mark an EntryOffset object which is considered as a mark
+ *
+ * @return a sorted set of EntryOffset objects
+ */
+ private Set<EntryOffset> greaterThan( EntryOffset mark )
+ {
+ Set<EntryOffset> gtSet = new TreeSet<EntryOffset>();
+
+ for ( EntryOffset o : offsetMap.values() )
+ {
+ if ( o.getStart() > mark.getStart() )
+ {
+ gtSet.add( o );
+ }
+ }
+
+ return gtSet;
+ }
+
+
+ /**
* add the CSN and UUID attributes to the entry if they are not present
*/
private void addMandatoryOpAt( Entry entry ) throws LdapException
@@ -400,3 +467,87 @@ public class SingleFileLdifPartition ext
}
}
}
+
+/**
+ * a holder class for containing an entry's start and end offset positions
+ * in the LDIF file
+ */
+class EntryOffset implements Comparable<EntryOffset>
+{
+ /** starting position */
+ private long start;
+
+ /** ending position */
+ private long end;
+
+ /** entry id */
+ private Comparable id;
+
+
+ public EntryOffset( Comparable id, long start, long end )
+ {
+ this.start = start;
+ this.end = end;
+ this.id = id;
+ }
+
+
+ public int compareTo( EntryOffset o )
+ {
+ if ( end > o.end )
+ {
+ return 1;
+ }
+ else if ( end < o.end )
+ {
+ return -1;
+ }
+
+ return 0;
+ }
+
+
+ public long getStart()
+ {
+ return start;
+ }
+
+
+ public long getEnd()
+ {
+ return end;
+ }
+
+
+ public Comparable getId()
+ {
+ return id;
+ }
+
+
+ public void increaseOffsetsBy( long val )
+ {
+ start += val;
+ end += val;
+ }
+
+
+ public void decreaseOffsetsBy( long val )
+ {
+ start -= val;
+ end -= val;
+ }
+
+
+ public long length()
+ {
+ return ( end - start );
+ }
+
+
+ @Override
+ public String toString()
+ {
+ return "EntryOffset [start=" + start + ", end=" + end + ", id=" + id + "]";
+ }
+}