/*
 * Copyright 2012 zhongl
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.github.zhongl.ipage;

import com.github.zhongl.util.RAFileChannel;
import com.google.common.io.Closeables;

import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;

/** @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a> */
public class LineAppender {

    private final InnerPage page;

    protected LineAppender(File dir, long position) {
        Offset offset = new Offset(position);
        page = new InnerPage(new File(dir, offset.toString() + ".line"), offset);
    }

    public int append(ByteBuffer buffer) {
        return page.append(buffer);
    }

    public void force() {
        page.force();
    }

    public Page page() {
        return page;
    }

    private static class InnerPage extends Page {

        private final RAFileChannel channel;

        protected InnerPage(File file, Offset number) {
            super(file, number);
            try {
                channel = new RAFileChannel(file);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        public int append(ByteBuffer buffer) {
            try {
                return channel.write(buffer);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        public void force() {
            try {
                channel.force(false);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                Closeables.closeQuietly(channel);
            }
        }
    }
}

@@ -642,16 +642,71 @@
 ipage;%0A%0A
+import com.github.zhongl.util.DirectByteBufferCleaner;%0A
 import c
@@ -1467,16 +1467,62 @@
 channel;
+%0A        private final ByteBuffer batchBuffer;
 %0A%0A      
@@ -1614,32 +1614,103 @@
           try %7B%0A
+                batchBuffer = ByteBuffer.allocateDirect(1 %3C%3C 20);// 1M%0A
                 
@@ -1917,57 +1917,373 @@
     
-try %7B%0A                return channel.write(buffer
+int length = buffer.remaining();%0A            if (length %3E batchBuffer.remaining()) %7B%0A                write0();%0A            %7D%0A            batchBuffer.put(buffer);%0A            return length;%0A        %7D%0A%0A        private void write0() %7B%0A            try %7B%0A                batchBuffer.flip();%0A                channel.write(batchBuffer);%0A                batchBuffer.rewind(
 );%0A 
@@ -2459,27 +2459,145 @@
     
-channel.force(false
+if (batchBuffer.position() %3E 0) write0();%0A                channel.force(false);%0A                DirectByteBufferCleaner.clean(batchBuffer
 );%0A 

Use batch buffer.