package org.wonderdb.block; import java.util.List; import java.util.Set; import org.jboss.netty.buffer.ChannelBuffer; import org.wonderdb.cache.impl.CacheEntryPinner; import org.wonderdb.cache.impl.CacheHandler; import org.wonderdb.cache.impl.InflightFileReader; import org.wonderdb.cache.impl.PrimaryCacheHandlerFactory; import org.wonderdb.cache.impl.PrimaryCacheResourceProvider; import org.wonderdb.cache.impl.PrimaryCacheResourceProviderFactory; import org.wonderdb.cache.impl.SecondaryCacheHandlerFactory; import org.wonderdb.cache.impl.SecondaryCacheResourceProvider; import org.wonderdb.cache.impl.SecondaryCacheResourceProviderFactory; import org.wonderdb.file.StorageUtils; import org.wonderdb.freeblock.FreeBlockFactory; import org.wonderdb.seralizers.block.SerializedBlockImpl; import org.wonderdb.serialize.block.BlockSerilizer; import org.wonderdb.types.BlockPtr; import org.wonderdb.types.SingleBlockPtr; import org.wonderdb.types.TypeMetadata; import org.wonderdb.types.record.Record; public class BlockManager { CacheHandler<BlockPtr, ChannelBuffer> secondaryCacheHandler = SecondaryCacheHandlerFactory.getInstance().getCacheHandler(); CacheHandler<BlockPtr, List<Record>> primaryCacheHandler = PrimaryCacheHandlerFactory.getInstance().getCacheHandler(); SecondaryCacheResourceProvider secondaryResourceProvider = SecondaryCacheResourceProviderFactory.getInstance().getResourceProvider(); PrimaryCacheResourceProvider primaryResourceProvider = PrimaryCacheResourceProviderFactory.getInstance().getResourceProvider(); private static BlockManager instance = new BlockManager(); private BlockManager() { } public static BlockManager getInstance() { return instance; } public Block getBlock(BlockPtr ptr, TypeMetadata meta, Set<Object> pinnedBlocks) { if (ptr == null || ptr.getFileId() < 0) { return null; } CacheEntryPinner.getInstance().pin(ptr, pinnedBlocks); Block block = (Block) primaryCacheHandler.get(ptr); if (block == null) { SerializedBlockImpl serializedBlock = (SerializedBlockImpl) secondaryCacheHandler.get(ptr); if (serializedBlock == null) { serializedBlock = (SerializedBlockImpl) InflightFileReader.getInstance().getBlock(ptr); } block = BlockSerilizer.getInstance().getBlock(serializedBlock, meta); Block b1 = (Block) primaryCacheHandler.addIfAbsent(block); if (b1 == block) { primaryResourceProvider.getResource(ptr, StorageUtils.getInstance().getSmallestBlockCount(ptr)); } } return block; } public Block createListBlock(byte fileId, Set<Object> pinnedBlocks) { SerializedBlockImpl serializedBlock = createSpace(fileId, pinnedBlocks); ListBlock block = new ListBlock(serializedBlock.getPtr()); primaryCacheHandler.forceAdd(block); return block; } public Block createListBlock(BlockPtr head) { SerializedBlockImpl serializedBlock = (SerializedBlockImpl) secondaryResourceProvider.getResource(head, StorageUtils.getInstance().getSmallestBlockCount(head)); secondaryCacheHandler.forceAdd(serializedBlock); primaryResourceProvider.getResource(head, StorageUtils.getInstance().getSmallestBlockCount(head)); ListBlock block = new ListBlock(head); primaryCacheHandler.forceAdd(block); return block; } public Block createIndexBlock(byte fileId, Set<Object> pinnedBlocks) { SerializedBlockImpl serializedBlock = createSpace(fileId, pinnedBlocks); IndexLeafBlock block = new IndexLeafBlock(serializedBlock.getPtr()); primaryCacheHandler.forceAdd(block); return block; } public Block createBranchBlock(byte fileId, Set<Object> pinnedBlocks) { SerializedBlockImpl serializedBlock = createSpace(fileId, pinnedBlocks); IndexBranchBlock block = new IndexBranchBlock(serializedBlock.getPtr()); primaryCacheHandler.forceAdd(block); return block; } public Block createBranchBlock(BlockPtr ptr, Set<Object> pinnedBlocks) { CacheEntryPinner.getInstance().pin(ptr, pinnedBlocks); SerializedBlockImpl serializedBlock = (SerializedBlockImpl) secondaryResourceProvider.getResource(ptr, StorageUtils.getInstance().getSmallestBlockCount(ptr)); secondaryCacheHandler.forceAdd(serializedBlock); primaryResourceProvider.getResource(ptr, StorageUtils.getInstance().getSmallestBlockCount(ptr)); IndexBranchBlock block = new IndexBranchBlock(ptr); primaryCacheHandler.forceAdd(block); return block; } public Block createIndexLefBlock(BlockPtr ptr, Set<Object> pinnedBlocks) { CacheEntryPinner.getInstance().pin(ptr, pinnedBlocks); SerializedBlockImpl serializedBlock = (SerializedBlockImpl) secondaryResourceProvider.getResource(ptr, StorageUtils.getInstance().getSmallestBlockCount(ptr)); secondaryCacheHandler.forceAdd(serializedBlock); primaryResourceProvider.getResource(ptr, StorageUtils.getInstance().getSmallestBlockCount(ptr)); IndexLeafBlock block = new IndexLeafBlock(ptr); primaryCacheHandler.forceAdd(block); return block; } private SerializedBlockImpl createSpace(byte fileId, Set<Object> pinnedBlocks) { long posn = FreeBlockFactory.getInstance().getFreeBlockPosn(fileId); BlockPtr ptr = new SingleBlockPtr(fileId, posn); CacheEntryPinner.getInstance().pin(ptr, pinnedBlocks); SerializedBlockImpl serializedBlock = (SerializedBlockImpl) secondaryResourceProvider.getResource(ptr, StorageUtils.getInstance().getSmallestBlockCount(ptr)); secondaryCacheHandler.forceAdd(serializedBlock); primaryResourceProvider.getResource(ptr, StorageUtils.getInstance().getSmallestBlockCount(ptr)); return serializedBlock; } }