package com.neocoretechs.bigsack.io.cluster; import java.io.IOException; import java.util.Enumeration; import java.util.concurrent.ConcurrentHashMap; import com.neocoretechs.bigsack.io.IoInterface; import com.neocoretechs.bigsack.io.pooled.Datablock; /** * Implementation of the simple block pool cache for a remote worker node. * We deal strictly with long pointers and datablocks, no further semantics at this level. * A concurrentHashMap of entries with fundamental operations is supported. * @author jg * */ public final class NodeBlockBuffer { private static boolean DEBUG = true; private static int NODEPOOLBLOCKS = 10000; private ConcurrentHashMap<Long, Datablock> blockBuffer; private IoInterface rawStore; public NodeBlockBuffer(IoInterface rawStore) { this.rawStore = rawStore; blockBuffer = new ConcurrentHashMap<Long,Datablock>(NODEPOOLBLOCKS); } public void put(Long ptr, Datablock dblk) { if( blockBuffer.size() >= NODEPOOLBLOCKS ) { // must toss one first Enumeration<Long> e = blockBuffer.keys(); Long rec = -1L; while(e.hasMoreElements()) { rec = e.nextElement(); if( rec != 0L ) { Datablock tblk = blockBuffer.get(rec); // if it is still waiting for outstanding write, dont dump it if( !tblk.isIncore() ) break; } } if( rec == -1L ) throw new RuntimeException("NodeBlockBuffer unable to clear buffer slot for new block, buffer full."); blockBuffer.remove(rec); } blockBuffer.put(ptr, dblk); } /** * Stop a designated ioUnit attached to this buffer * @throws IOException */ public void force() throws IOException { if( DEBUG ) System.out.println("NodeBlockBuffer.force writing node block buffer with "+blockBuffer.size()+" entries."); int stillIn = 0; Enumeration<Long> e = blockBuffer.keys(); Long rec = -1L; while(e.hasMoreElements()) { rec = e.nextElement(); Datablock tblk = blockBuffer.get(rec); // if it is still waiting for outstanding write, dont dump it if( tblk.isIncore() ) { if( DEBUG ) System.out.println("!!!!!NodeBlockBuffer, block "+rec+" is in core during shutdown:"+tblk); tblk.write(rawStore); tblk.setIncore(false); ++stillIn; } } rawStore.Fforce(); // synch if( DEBUG ) System.out.println("Node block buffer cleared with "+stillIn+" blocks outstanding written."); } public Datablock get(Long ptr) { return blockBuffer.get(ptr); } }