package com.tesora.dve.db.mysql.portal.protocol;
/*
* #%L
* Tesora Inc.
* Database Virtualization Engine
* %%
* Copyright (C) 2011 - 2014 Tesora Inc.
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.internal.PlatformDependent;
import java.nio.ByteOrder;
/**
*
*/
public class CachedAppendBuffer {
public static final int SLAB_SIZE = 1024 * 8;//start with a 8K slab for transcoding outbound writes.
static boolean PREFER_DIRECT = PlatformDependent.directBufferPreferred();
int appendStartedAtIndex;
ByteBuf cachedSlab;
public void allocateSlabIfNeeded(ChannelHandlerContext ctx) {
if (cachedSlab != null) //we already have a slab.
return;
if (PREFER_DIRECT) {
cachedSlab = ctx.alloc().ioBuffer(SLAB_SIZE);
} else {
cachedSlab = ctx.alloc().heapBuffer(SLAB_SIZE);
}
cachedSlab = cachedSlab.order(ByteOrder.LITTLE_ENDIAN);
}
public ByteBuf startAppend(ChannelHandlerContext ctx){
allocateSlabIfNeeded(ctx);
//if we don't have any outbound slices holding references, reset to full slab.
if (cachedSlab.refCnt() == 1){
cachedSlab.clear();
}
appendStartedAtIndex = cachedSlab.writerIndex();
return cachedSlab;
}
public ByteBuf sliceWritableData(){
int writtenLength = cachedSlab.writerIndex() - appendStartedAtIndex;
if (writtenLength <= 0)
return Unpooled.EMPTY_BUFFER;
else {
ByteBuf sliceSinceStarted = cachedSlab.slice(appendStartedAtIndex, writtenLength).retain(); //this will be written out to netty, so inc the ref count.
return sliceSinceStarted;
}
}
public void releaseSlab() {
ReferenceCountUtil.release(cachedSlab);
cachedSlab = null;
}
}