You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@labs.apache.org by el...@apache.org on 2012/08/02 17:56:58 UTC
svn commit: r1368565 -
/labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTree.java
Author: elecharny
Date: Thu Aug 2 15:56:57 2012
New Revision: 1368565
URL: http://svn.apache.org/viewvc?rev=1368565&view=rev
Log:
Implemented a read() method (not tested yet)
Modified:
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTree.java
Modified: labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTree.java
URL: http://svn.apache.org/viewvc/labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTree.java?rev=1368565&r1=1368564&r2=1368565&view=diff
==============================================================================
--- labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTree.java (original)
+++ labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTree.java Thu Aug 2 15:56:57 2012
@@ -21,16 +21,20 @@ package org.apache.mavibot.btree;
import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
+import org.apache.mavibot.btree.serializer.BufferHandler;
import org.apache.mavibot.btree.serializer.Serializer;
@@ -601,78 +605,157 @@ public class BTree<K, V>
/**
- * Flush the latest revision to disk
- * @param file The file into which the data will be written
+ * Write the data in the ByteBuffer, and eventually on disk if needed.
+ *
+ * @param channel The channel we want to write to
+ * @param bb The ByteBuffer we wat to feed
+ * @param buffer The data to inject
+ * @throws IOException If the write failed
*/
- public void flush( File file )
+ private void writeBuffer( FileChannel channel, ByteBuffer bb, byte[] buffer ) throws IOException
{
+ int size = buffer.length;
+ // Loop until we have written all the data
+ do
+ {
+ if ( bb.remaining() >= size )
+ {
+ // No flush, as the ByteBuffer is big enough
+ bb.put( buffer );
+ size = 0;
+ }
+ else
+ {
+ // Flush the data on disk, reinitialize the ByteBuffer
+ int len = bb.limit() - bb.position();
+ size -= len;
+ bb.put( buffer, bb.position(), len );
+
+ bb.flip();
+ channel.write( bb );
+ bb.clear();
+ }
+ }
+ while ( size > 0 );
}
/**
- * Flush the latest revision to disk. We will replace the current file by the new one, as
- * we flush in a temporaty file.
+ * Flush the latest revision to disk
+ * @param file The file into which the data will be written
*/
- public void flush() throws IOException
+ public void flush( File file ) throws IOException
{
- File tmpFileFD = File.createTempFile( "mavibot", null );
- RandomAccessFile tempFile = new RandomAccessFile(
- tmpFileFD.getCanonicalPath(), "rw" );
+ File baseDirectory = new File( file.getParentFile().getAbsolutePath() );
+
+ // Create a temporary file in the same directory to flush the current btree
+ File tmpFileFD = File.createTempFile( "mavibot", null, baseDirectory );
+ FileOutputStream stream = new FileOutputStream( tmpFileFD );
+ FileChannel ch = stream.getChannel();
+ ByteBuffer bb = ByteBuffer.allocateDirect( 65536 );
Cursor<K, V> cursor = browse();
if ( serializer == null )
{
- serializer = new Serializer<K, V>()
- {
- public byte[] serializeKey( K key )
- {
- return null;
- }
-
-
- public K deserializeKey( byte[] in )
- {
- return null;
- }
-
-
- public byte[] serializeValue( V value )
- {
- return null;
- }
-
-
- public V deserializeValue( byte[] in )
- {
- return null;
- }
- };
+ throw new RuntimeException( "Cannot flush the btree without a serializer" );
}
// Write the number of elements first
- tempFile.writeLong( nbElems.get() );
+ bb.putLong( nbElems.get() );
while ( cursor.hasNext() )
{
Tuple<K, V> tuple = cursor.next();
byte[] keyBuffer = serializer.serializeKey( tuple.getKey() );
- tempFile.write( keyBuffer );
+
+ writeBuffer( ch, bb, keyBuffer );
byte[] valueBuffer = serializer.serializeValue( tuple.getValue() );
- tempFile.write( valueBuffer );
+ writeBuffer( ch, bb, valueBuffer );
+ }
+
+ // Write the buffer if needed
+ if ( bb.position() > 0 )
+ {
+ bb.flip();
+ ch.write( bb );
}
- tempFile.close();
- tempFile.getFD().sync();
+ // Flush to the disk for real
+ ch.force( true );
+ ch.close();
// Rename the current file to save a backup
- file.renameTo( new File( file.getName() + ".bak" ) );
+ File backupFile = File.createTempFile( "mavibot", null, baseDirectory );
+ file.renameTo( backupFile );
+
+ // Rename the temporary file to the initial file
+ tmpFileFD.renameTo( file );
+
+ // We can now delete the backup file
+ backupFile.delete();
+ }
- // And rename the temporary file
- tmpFileFD.renameTo( file.getCanonicalFile() );
+
+ /**
+ * Read the data from the disk into this BTree. All the existing data in the
+ * BTree are kept, the read data will be associated with a new revision.
+ * @param file
+ * @throws IOException
+ */
+ public void read( File file ) throws IOException
+ {
+ long revision = generateRevision();
+
+ if ( !file.exists() )
+ {
+ throw new IOException( "The file does not exist" );
+ }
+
+ FileChannel channel =
+ new RandomAccessFile( file, "rw" ).getChannel();
+ ByteBuffer buffer = ByteBuffer.allocate( 65536 );
+
+ BufferHandler bufferHandler = new BufferHandler( channel, buffer );
+
+ long nbElems = buffer.getLong();
+
+ // Prepare a list of keys and values rad from the disk
+ //List<K> keys = new ArrayList<K>();
+ //List<V> values = new ArrayList<V>();
+
+ // Loop on all the elements, store them in lists atm
+ for ( long i = 0; i < nbElems; i++ )
+ {
+ // Read the key
+ K key = serializer.deserializeKey( bufferHandler );
+
+ //keys.add( key );
+
+ // Read the value
+ V value = serializer.deserializeValue( bufferHandler );
+
+ //values.add( value );
+
+ // Inject the data in the tree. (to be replaced by a bulk load)
+ insert( key, value, revision );
+ }
+
+ // Now, process the lists to create the btree
+ // TODO... BulkLoad
+ }
+
+
+ /**
+ * Flush the latest revision to disk. We will replace the current file by the new one, as
+ * we flush in a temporary file.
+ */
+ public void flush() throws IOException
+ {
+ flush( file );
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org