package krati.io;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

/**
 * MappedWriter
 * 
 * @author jwu
 * 
 */
public class MappedWriter implements DataWriter {
    private final File _file;
    private RandomAccessFile _raf;
    private MappedByteBuffer _mmapBuffer;
    
    public MappedWriter(File file) {
        this._file = file;
    }
    
    @Override
    public File getFile() {
        return _file;
    }
    
    @Override
    public void open() throws IOException {
        if(!_file.exists()) {
            File dir = _file.getParentFile();
            if(dir.exists())  _file.createNewFile();
            else if(dir.mkdirs()) _file.createNewFile();
            else throw new IOException("Failed to create file " + _file.getAbsolutePath());
        }
        
        if(_file.isDirectory()) {
            throw new IOException("Cannot open directory " + _file.getAbsolutePath());
        }
        
        _raf = new RandomAccessFile(_file, "rw");
        _mmapBuffer = _raf.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, _raf.length());
    }
    
    @Override
    public void close() throws IOException {
        try {
            _mmapBuffer.force();
            _raf.close();
        } finally {
            _mmapBuffer = null;
            _raf = null;
        }
    }
    
    @Override
    public void flush() throws IOException {
        _mmapBuffer.force();
    }
    
    @Override
    public void writeInt(int value) throws IOException {
        _mmapBuffer.putInt(value);
    }
    
    @Override
    public void writeLong(long value) throws IOException {
        _mmapBuffer.putLong(value);
    }
    
    @Override
    public void writeShort(short value) throws IOException {
        _mmapBuffer.putShort(value);
    }
    
    @Override
    public void writeInt(long position, int value) throws IOException {
        _mmapBuffer.putInt((int)position, value);
    }
    
    @Override
    public void writeLong(long position, long value) throws IOException {
        _mmapBuffer.putLong((int)position, value);
    }
    
    @Override
    public void writeShort(long position, short value) throws IOException {
        _mmapBuffer.putShort((int)position, value);
    }
    
    @Override
    public long position() throws IOException {
        return _mmapBuffer.position();
    }
    
    @Override
    public void position(long newPosition) throws IOException {
        _mmapBuffer.position((int)newPosition);
    }
}

@@ -210,16 +210,119 @@
 jwu%0A * %0A
+ * %3Cp%3E%0A * 06/08, 2011 - Revert to FileChannel.force to fix performance degradation introduced in 0.3.8%0A
  */%0Apubl
@@ -393,24 +393,58 @@
 File _file;%0A
+    private FileChannel _channel;%0A
     private 
@@ -1217,26 +1217,23 @@
        _
-mmapBuffer
+channel
  = _raf.
@@ -1244,16 +1244,48 @@
 hannel()
+;%0A        _mmapBuffer = _channel
 .map(Fil
@@ -1425,39 +1425,70 @@
            _
-mmapBuffer.forc
+channel.force(true);%0A            _channel.clos
 e();%0A       
@@ -1550,32 +1550,61 @@
 pBuffer = null;%0A
+            _channel = null;%0A
             _raf
@@ -1705,25 +1705,26 @@
    _
-mmapBuffer
+channel
 .force(
+true
 );%0A 

Revert to FileChannel.force to fix performance degradation introduced in 0.3.8