package com.jivesoftware.os.amza.service.storage.filer;

import com.jivesoftware.os.amza.api.filer.IReadable;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.FileChannel;

/**
 * @author jonathan.colt
 */
public class DiskBackedWALFilerChannelReader implements IReadable {

    private final DiskBackedWALFiler parent;
    private FileChannel fc;
    private long fp;

    private final ByteBuffer singleByteBuffer = ByteBuffer.allocate(1);

    public DiskBackedWALFilerChannelReader(DiskBackedWALFiler parent, FileChannel fc) {
        this.parent = parent;
        this.fc = fc;
    }

    @Override
    public Object lock() {
        return this;
    }

    @Override
    public void seek(long position) throws IOException {
        if (position < 0 || position > parent.length()) {
            throw new IOException("seek overflow " + position + " " + this);
        }
        fp = position;
    }

    @Override
    public long length() throws IOException {
        return parent.length();
    }

    @Override
    public long getFilePointer() throws IOException {
        return fp;
    }

    @Override
    public int read() throws IOException {
        while (true) {
            try {
                singleByteBuffer.position(0);
                int read = fc.read(singleByteBuffer, fp);
                fp++;
                singleByteBuffer.position(0);
                return read != 1 ? -1 : singleByteBuffer.get();
            } catch (ClosedChannelException e) {
                fc = parent.getFileChannel();
            }
        }
    }

    @Override
    public int read(byte[] b) throws IOException {
        return read(b, 0, b.length);
    }

    @Override
    public int read(byte[] b, int _offset, int _len) throws IOException {
        ByteBuffer bb = ByteBuffer.wrap(b, _offset, _len);
        while (true) {
            try {
                fc.read(bb, fp);
                fp += _len;
                return _len;
            } catch (ClosedChannelException e) {
                fc = parent.getFileChannel();
                bb.position(0);
            }
        }
    }

    @Override
    public void close() throws IOException {
        fc.close();
    }

}

@@ -438,15 +438,69 @@
 ate 
-long fp
+volatile long fp;%0A    private volatile boolean closed = false
 ;%0A%0A 
@@ -1290,36 +1290,39 @@
 %0A        while (
-true
+!closed
 ) %7B%0A            
@@ -1674,32 +1674,51 @@
     %7D%0A        %7D%0A
+        return -1;%0A
     %7D%0A%0A    @Over
@@ -1983,12 +1983,15 @@
 le (
-true
+!closed
 ) %7B%0A
@@ -2245,24 +2245,43 @@
 %7D%0A        %7D%0A
+        return -1;%0A
     %7D%0A%0A    @
@@ -2281,32 +2281,32 @@
 %0A%0A    @Override%0A
-
     public void 
@@ -2326,32 +2326,55 @@
 s IOException %7B%0A
+        closed = true;%0A
         fc.close

Make DiskBackedWALFilerChannelReader closable.