/*
* 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.ggrandes.kvstore.pool;
import java.nio.ByteBuffer;
import com.github.ggrandes.kvstore.structures.hash.IntHashMap;
/**
* Pool of ByteBuffers ByteBuffer池. 就像连接池中存放的是多个连接. ByteBuffer池也存放多个ByteBuffer
* This class is Thread-Safe
*
* <a href="http://www.evanjones.ca/software/java-bytebuffers.html">Efficient Java I/O: ByteBuffer</a>
*
* @author Guillermo Grandes / guillermo.grandes[at]gmail.com
*/
public class BufferStacker {
//ByteBuffer池
private static IntHashMap<BufferStacker> INSTANCES = new IntHashMap<BufferStacker>(BufferStacker.class);
//
private java.util.Deque<ByteBuffer> stack = new java.util.ArrayDeque<ByteBuffer>();
private final int bufferLen;
private int created = 0;
//
private BufferStacker() {
this(1024);
}
private BufferStacker(final int bufferLen) {
this.bufferLen = bufferLen;
}
//
public static BufferStacker getInstance(final int bufferLen, final boolean isDirect) {
final int key = composeKey(bufferLen, isDirect);
synchronized (INSTANCES) {
BufferStacker bs = INSTANCES.get(key);
//如果这个ByteBuffer没有初始化, 则初始化, 并放入ByteBuffer池中
//如果已经存在, 则直接返回给调用者. 就像连接池中的连接如果已经存在, 则直接返回给客户端
if (bs == null) {
bs = new BufferStacker(bufferLen);
INSTANCES.put(key, bs);
}
return bs;
}
}
//给定一个长度, 使用ByteBuffer池给它分配一个ByteBuffer
private static final int composeKey(final int bufferLen, final boolean isDirect) {
return (((bufferLen & 0x3FFFFFFF) << 1) | (isDirect ? 1 : 0));
}
//
public synchronized void push(final ByteBuffer buf) {
stack.addFirst(buf);
}
public synchronized ByteBuffer pop() {
final ByteBuffer buf = stack.pollFirst();
if (buf == null) {
created++;
return ByteBuffer.allocate(bufferLen);
}
buf.clear();
return buf;
}
public String toString() {
return super.toString() + ": created=" + created;
}
}