package org.wonderdb.cache.impl; /******************************************************************************* * Copyright 2013 Vilas Athavale * * 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. *******************************************************************************/ import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.wonderdb.cache.CacheResourceProvider; import org.wonderdb.cache.Cacheable; import org.wonderdb.seralizers.block.SerializedBlockImpl; import org.wonderdb.types.BlockPtr; public class SecondaryCacheResourceProvider implements CacheResourceProvider<BlockPtr, ChannelBuffer> { private CacheBean cacheBean = null; private CacheState cacheState = null; private CacheLock cacheLock = null; private BlockingQueue<ChannelBuffer> freeList = null; private int bufferSize = 0; private CacheWriter<BlockPtr, ChannelBuffer> cacheWriter = null; public SecondaryCacheResourceProvider(CacheWriter<BlockPtr, ChannelBuffer> cacheWrtier, CacheBean cacheBean, CacheState cacheState, CacheLock cacheLock, int bufferCount, int bufferSize, CacheWriter<BlockPtr, ChannelBuffer> writer) { this.cacheWriter = writer; this.cacheBean = cacheBean; this.cacheState = cacheState; this.cacheLock = cacheLock; this.bufferSize = bufferSize; freeList = new ArrayBlockingQueue<ChannelBuffer>(bufferCount); for (int i = 0; i < bufferCount; i++) { freeList.add(ChannelBuffers.directBuffer(bufferSize)); } } public Cacheable<BlockPtr, ChannelBuffer> getResource(BlockPtr ptr, int resourceCount) { ChannelBuffer[] bufferList = new ChannelBuffer[resourceCount]; for (int i = 0; i < resourceCount; i++) { ChannelBuffer buffer; while (true) { try { buffer = freeList.take(); break; } catch (InterruptedException e) { e.printStackTrace(); } } cacheState.updateTotalCountBy(1); buffer.clear(); buffer.writerIndex(buffer.capacity()); bufferList[i] = buffer; } if (cacheState.getTotalCount() >= cacheBean.getCleanupHighWaterMark()) { // cacheWriter.forceStartWriting(); cacheLock.notifyEagerCleanup(); } if (cacheState.getTotalCount() >= cacheBean.getCleanupHighWaterMark()) { cacheLock.notifyStartCleanup(); } SerializedBlockImpl buf = new SerializedBlockImpl(ptr, bufferList); buf.getFull().clear(); return buf; } public ChannelBuffer[] getBuffers(ChannelBuffer buffer) { int size = 0; ChannelBuffer[] retVal = new ChannelBuffer[buffer.capacity()/bufferSize]; for (int i = 0; i < retVal.length; i++) { ChannelBuffer cb = buffer.slice(size, bufferSize); size = size + bufferSize; retVal[i] = cb; } return retVal; } @Override public void returnResource(Cacheable<BlockPtr, ChannelBuffer> ref) { if (ref == null) { return; } Cacheable<BlockPtr, ChannelBuffer> block = ref; ChannelBuffer[] buffers = getBuffers(block.getFull()); for (int i = 0; i < buffers.length; i++) { ChannelBuffer buffer = buffers[i]; buffer.clear(); freeList.add(buffer); cacheState.updateTotalCountBy(-1); } } }