asmuts      02/01/14 22:21:50

  Added:       src/java/org/apache/stratum/jcs/auxiliary/disk/jisp
                        JISPCache.java JISPCacheAttributes.java
                        JISPCacheFactory.java JISPCacheManager.java
                        JISPCacheNoWaitBuffer.java JISPKey.java
                        JISPLockManager.java PurgatoryElement.java
  Log:
  JISP disk cache implementation
  disk swap key storage
  need to get it to reuse existing files and data
  quick
  purgatory for incoming items
  
  Revision  Changes    Path
  1.1                  
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/auxiliary/disk/jisp/JISPCache.java
  
  Index: JISPCache.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  
  package org.apache.stratum.jcs.auxiliary.disk.jisp;
  
  import  java.io.*;
  import  java.util.*;
  import  java.sql.*;
  
  import org.apache.stratum.jcs.access.*;
  import org.apache.stratum.jcs.access.exception.*;
  import org.apache.stratum.jcs.auxiliary.disk.jisp.*;
  import org.apache.stratum.jcs.auxiliary.disk.jisp.behavior.*;
  import org.apache.stratum.jcs.engine.control.*;
  import org.apache.stratum.jcs.engine.control.Cache;
  import org.apache.stratum.jcs.engine.behavior.*;
  import org.apache.stratum.jcs.engine.*;
  
  import org.apache.stratum.jcs.utils.data.*;
  import org.apache.stratum.jcs.utils.log.*;
  
  import com.coyotegulch.jisp.*;
  
  
  ////////////////////////////////////////////////////////////////////////
  public class JISPCache implements ICache, Serializable {
  
    private static  Logger log;
    private static int numCreated = 0;
    private int numInstances = 0;
  
    // trivial debugging that should be removed by the compiler
    private static final boolean debug =  true;
    private static final boolean debugR =  true;
    private static final boolean debugPut = true;
    private static final boolean debugGet = true;
  
    private String cacheName;
  
    public boolean isAlive = false;
  
     // not used
    private String source_id = "org.apache.stratum.jcs.auxiliary.disk.jisp.HSQLCache";
  
    IJISPCacheAttributes cattr;
  
    // disk cache buffer, need to remove key from buffer on update, if its there
    JISPCacheNoWaitBuffer buffer;
  
    //JISP ACCESS
    IndexedObjectDatabase database;
    BTreeIndex index1;
    private static int s_order =  101; //?
    String jispDataFileName = "default_this_is_BAD";
    String jispIndexFileName = "default_this_is_BAD";
  
    private final static JISPLockManager locker = JISPLockManager.getInstance();
  
  
    ///////////////////////////////////////////////////
    public Serializable getSourceId() {
      return this.source_id;
    }
  
    ////////////////////////////////////////////////////////////////////
    // should use this method
    public JISPCache ( JISPCacheNoWaitBuffer buffer, IJISPCacheAttributes cattr ) {
      //this( cattr.getCacheName(), cattr.getDiskPath() );
      this( cattr );
      this.cattr = cattr;
      this.buffer = buffer;
    }
    //protected JISPCache ( String cacheName ) {
    //  this( cacheName, null);
    //}
    //////////////////////////////////////////////////////////////////////
    protected JISPCache ( IJISPCacheAttributes cattr ) {
      numInstances++;
  
      // TODO: Change to log4j
      log = LoggerManager.getLogger( this );
  
      String rafroot = cattr.getDiskPath();
  
      this.cacheName = cattr.getCacheName();
  
      if ( rafroot == null ) {
        log.warn( "The JISP directory was not defined in the cache.ccf " );
        rafroot = "";
      }
  
      jispDataFileName = rafroot + cacheName + "DATA.jisp";
      jispIndexFileName = rafroot + cacheName + "INDEX.jisp";
  
      p( "jispDataFileName = " + jispDataFileName );
      ////////////////////////////////////////
      // See if the JISP Cache has already been created.
      // build b-tree database if it doesn't already exist
      try {
  
        File finddb = new File( jispDataFileName );
  
        if ( !finddb.exists() || cattr.getClearOnStart() ) {
          setupTABLE();
        }
  
        createDB( cattr.getClearOnStart() );
  
        isAlive = true;
  
      } catch (Exception e) {
        p("QueryTool.init: " + e.getMessage());
        e.printStackTrace();
        log.error( e );
      }
  
    }             // end constructor
  
    /**
     * SETUP TABLE FOR CACHE
     *
     */
    void setupTABLE() {
  
      try {
  
        // delete old files
        File killit = new File(jispDataFileName );
  
        if (killit.exists()) {
            killit.delete();
        }
  
        killit = new File(jispIndexFileName );
  
        if (killit.exists()) {
            killit.delete();
        }
  
      } catch ( Exception e) {
        System.out.println("Exception: " + e);
        log.error( e );
      }
  
    } // end setupTable
  
  
    ///////////////////////////////////////////////////////////
    public void createDB( boolean clear ) throws Exception {
      try {
  
        // create database
        // it seems to alwasy lose the data on retstart
        database = new IndexedObjectDatabase( jispDataFileName, clear );
  
        index1 = new BTreeIndex( jispIndexFileName, s_order, new JISPKey(), false );
        database.attachIndex(index1);
      } catch ( Exception e) {
        System.out.println("Exception: " + e);
        log.error( e );
        throw e;
      }
    }
  
  
    ////////////////////////////////////////////////////////
    public void add (Serializable key, Serializable value)   throws IOException {
      put(key, value);
    }
  
    // ignore the multicast field.
    public void put (Serializable key, Serializable value, boolean multicast)  throws 
IOException {
      put(key, value);
    }
  
    public void put (Serializable key, Serializable value)  throws IOException {
      put( key, value, null );
    }
    public void put (Serializable key, Serializable value, Attributes attr)  throws 
IOException {
      CacheElement ce = null;
      ce = new CacheElement( cacheName, key, value );
      ce.setAttributes( attr );
      update( ce );
    }
    ///////////////////////////////////////////////////////////
    public void update( ICacheElement ce ) throws IOException {
  
      if ( debug ) {
        p( "update" );
      }
  
      if (!isAlive) {
        log.warn( "not alive" );
        return;
      }
  
      if ( ce instanceof PurgatoryElement ) {
        PurgatoryElement pe = (PurgatoryElement)ce;
        ce = pe.ice;
        if ( !pe.isSpoolable ) {
          if ( debug ) {
            p( "pe is not spoolable" );
          }
          // it has been plucked from purgatory
          return;
        }
      }
  
      // remove item from purgatory since we are putting it on disk
      // assume that the disk cache will never break
      // disk breakage is akin to an out of memory exception
      buffer.purgatory.remove( ce.getKey() );
      if ( debug ) {
        p( "putting " + ce.getKey() + " on disk, removing from purgatory" );
      }
  
      if ( debug ) {
        p( "putting " + ce );
      }
  
      // make sure this only locks for one particular cache region
      //locker.writeLock();
  
      try {
  
        KeyObject[] keyArray = new JISPKey[1];
        keyArray[0] = new JISPKey( ce.getKey() );
  
        // akin to an update, should insert as well
        database.write( keyArray, (Serializable)ce );
        //p( "put " + ce.getKey() );
  
      } catch (Exception e) {
        log.error( e );
      } finally {
        //locker.done();          // release write lock.
      }
  
  
      return;
    }
  
    ///////////////////////////////////////////////////////////////
    public Serializable get (Serializable key) {
      return  get(key, true, true);
    }
  
    ///////////////////////////////////////////////////////////////
    public Serializable get (Serializable key, boolean container ) {
      return  get(key, true, true);
    }
  
    //////////////////////////////////////////////////////////////////////
    private Serializable get (Serializable key, boolean container, final boolean lock) 
{
  
      if ( debugGet ) {
        p( "getting " + key + " from disk" );
      }
  
      if (!isAlive) {
        return  null;
      }
  
      ICacheElement obj = null;
  
      try {
  
        obj = (ICacheElement)database.read(new JISPKey(key),index1);
  
      } catch (Exception e ) {
        log.error( e );
      }
  
      if ( obj == null ) {
        return null;
      }
      if ( container ) {
        return  (Serializable)obj;
      }
      return obj.getVal();
    }
  
    /**
     * Returns true if the removal was succesful; or false if there is nothing to 
remove.
     * Current implementation always result in a disk orphan.
     */
    public boolean remove (Serializable key) {
  
      KeyObject[] keyArray = new JISPKey[1];
      keyArray[0] = new JISPKey( key );
  
      try {
  
        if (key instanceof String && 
key.toString().endsWith(NAME_COMPONENT_DELIMITER)) {
          // remove all keys of the same name group.
          //sql = "delete from " + cacheName + " where KEY = like '" + key + "%'";
          // need to figure how to do this in JISP
        } else {
          database.remove( keyArray );
        }
  
      } catch (Exception e) {
        log.error(e);
        reset();
      }
      return  false;
    }
  
    /////////////////////////////////////////////
    public void removeAll () {
      try {
        reset();
      } catch (Exception e) {
        log.error(e);
        //reset();
      } finally {}
    }             // end removeAll
  
    ////////////////////////////////////////////////////////////////
    // handle error by last resort, force content update, or removeall
    public void reset () {
  
      try {
        setupTABLE();
        createDB( true );
      } catch( Exception e ) {
        log.error(e);
      }
    }             // end reset
  
    ////////////////////////////////////////////////////////////////////////////
    public String getStats () {
      return   "numInstances = " + numInstances;
    }
  
    /////////////////////////////////////////////////////////////
    // shold be called by cachemanager, since it knows how
    // many are checked out
    public void dispose () {
  //    if (!isAlive) {
  //      log.logIt("is not alive and close() was called -- " + fileName);
  //      return;
  //    }
  //    locker.writeLock();
  //    try {
  //      if (!isAlive) {
  //        log.logIt("is not alive and close() was called -- " + fileName);
  //        return;
  //      }
  //      try {
  //        optimizeFile();
  //      } catch (Exception e) {
  //        JISPKey(e, "-- " + fileName);
  //      }
  //      try {
  //        numInstances--;
  //        if (numInstances == 0) {
  //          p( "dispose -- Closing files -- in close -- " + fileName );
  //          log.warn("dispose -- Closing files -- in close -- " + fileName);
  //          dataFile.close();
  //          dataFile = null;
  //          keyFile.close();
  //          keyFile = null;
  //        }
  //      } catch (Exception e) {
  //        JISPKey(e, "-- " + fileName);
  //      }
  //    } finally {
  //      isAlive = false;
  //      locker.done();            // release write lock;
  //    }
    }             // end dispose
  
  
  
    /** Returns the cache status. */
    public int getStatus () {
      return  isAlive ? STATUS_ALIVE : STATUS_DISPOSED;
    }
  
    /** Returns the current cache size. */
    public int getSize () {
      return  0; // need to get count
    }
  
    public int getCacheType () {
      return  DISK_CACHE;
    }
  
    /** For debugging. */
    public void dump () {
  //    log.debug("keyHash.size()=" + keyHash.size());
  //    for (Iterator itr = keyHash.entrySet().iterator(); itr.hasNext();) {
  //      Map.Entry e = (Map.Entry)itr.next();
  //      Serializable key = (Serializable)e.getKey();
  //      DiskElementDescriptor ded = (DiskElementDescriptor)e.getValue();
  //      Serializable val = get(key);
  //      log.debug("disk dump> key=" + key + ", val=" + val + ", pos=" + ded.pos);
  //    }
    }
  
  
    //////////////////////////////////////////
      void trace(String s) {
        p(s);
      }
    //////////////
    public void p( String s ) {
      log.debug(s);
      System.out.println( "JISPCache: " + s );
    }
  
  
    /** Returns cache name, ha */
    public String getCacheName () {
      return  cacheName;
    }
  
    /////////////////////////////////////////////////////////////////////////
    /** Returns the serialized form of the given object in a byte array. */
    static byte[] serialize (Serializable obj) throws IOException {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      ObjectOutputStream oos = new ObjectOutputStream(baos);
      try {
        oos.writeObject(obj);
      } finally {
        oos.close();
      }
      return  baos.toByteArray();
    }
  
  }               // end class
  
  
  
  
  
  
  1.1                  
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/auxiliary/disk/jisp/JISPCacheAttributes.java
  
  Index: JISPCacheAttributes.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  
  package org.apache.stratum.jcs.auxiliary.disk.jisp;
  
  import org.apache.stratum.jcs.auxiliary.disk.jisp.behavior.IJISPCacheAttributes;
  import org.apache.stratum.jcs.auxiliary.behavior.IAuxiliaryCacheAttributes;
  
  
  //////////////////////////////////////////////////
  public class JISPCacheAttributes implements IJISPCacheAttributes {
  
    private String cacheName;
    private String name;
  
    private String diskPath;
  
    private boolean clearOnStart;
  
    /////////////////////////////////////////
    public JISPCacheAttributes() {
      clearOnStart = false;
    }
  
    ////////////////////////////////////
    public void setDiskPath( String path ) {
      this.diskPath = path;
    }
  
    ////////////////////////////////////
    public String getDiskPath( ) {
      return this.diskPath;
    }
  
  
    ////////////////////////////////////
    // whether the disk cache should clear the old files
    // so there are no lingering elements.
    public void setClearOnStart( boolean clear ) {
      clearOnStart = clear;
    }
    ////////////////////////////////////
    public boolean getClearOnStart( ) {
      return clearOnStart;
    }
  
  
    ////////////////////////////////////////////////////
    public void setCacheName( String s ) {
      this.cacheName = s;
    }
    public String getCacheName( ) {
      return this.cacheName;
    }
  
    /////////////////////////////////////////////////////////////////////
    public String getName() {
      return this.name;
    }
    public void setName( String name ) {
      this.name = name;
    }
  
    /////////////////////////////////////////////////
    public IAuxiliaryCacheAttributes copy() {
      try {
        return (IAuxiliaryCacheAttributes)this.clone();
      } catch( Exception e ){}
      return (IAuxiliaryCacheAttributes)this;
    }
  
    ///////////////////////////////////////////////////////////////
    public String toString() {
      StringBuffer str = new StringBuffer();
      str.append( "diskPath = " + diskPath );
      return str.toString();
    }
  
  
  }
  
  
  
  1.1                  
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/auxiliary/disk/jisp/JISPCacheFactory.java
  
  Index: JISPCacheFactory.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  
  package org.apache.stratum.jcs.auxiliary.disk.jisp;
  
  import org.apache.stratum.jcs.auxiliary.behavior.IAuxiliaryCacheFactory;
  import org.apache.stratum.jcs.engine.behavior.ICache;
  import org.apache.stratum.jcs.auxiliary.behavior.IAuxiliaryCacheAttributes;
  
  /**
   * @author Aaron Smuts
   * @version 1.0
   */
  
  import org.apache.stratum.jcs.auxiliary.behavior.*;
  import org.apache.stratum.jcs.auxiliary.disk.jisp.behavior.*;
  import org.apache.stratum.jcs.utils.log.*;
  
  ///////////////////////////////////////////////////////////////
  public class JISPCacheFactory implements IAuxiliaryCacheFactory {
  
    private static Logger log = LoggerManager.getLogger( JISPCacheFactory.class );
  
    private static String name;
  
    ///////////////////////////////////////////////
    public JISPCacheFactory() {
    }
  
    ////////////////////////////////////////////////////////////////////
    public ICache createCache(IAuxiliaryCacheAttributes iaca) {
      IJISPCacheAttributes idca = (IJISPCacheAttributes)iaca;
      JISPCacheManager dcm = JISPCacheManager.getInstance( idca );
      return dcm.getCache( idca );
    }
  
    /////////////////////////////////////////////////////////////////////
    public String getName() {
      return this.name;
    }
    public void setName( String name ) {
      this.name = name;
    }
  }
  
  
  
  1.1                  
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/auxiliary/disk/jisp/JISPCacheManager.java
  
  Index: JISPCacheManager.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  
  package org.apache.stratum.jcs.auxiliary.disk.jisp;
  
  import org.apache.stratum.jcs.auxiliary.disk.*;
  import java.io.*;
  import java.util.*;
  import java.sql.*;
  
  import org.apache.stratum.jcs.auxiliary.disk.jisp.*;
  import org.apache.stratum.jcs.auxiliary.disk.jisp.behavior.*;
  import org.apache.stratum.jcs.engine.behavior.*;
  import org.apache.stratum.jcs.utils.log.*;
  
  /////////////////////////////////////////////
  public class JISPCacheManager implements ICacheManager {
  
    private static int clients;
  
    private static Hashtable caches = new Hashtable();
  
    private static Logger log;
    private static final boolean debug = false; //true;
    private static final boolean pOut = false; //true;
  
    private static JISPCacheManager instance;
  
    private static IJISPCacheAttributes defaultCattr;
  
    ///////////////////////////////////////////////////////////////////
     private JISPCacheManager( IJISPCacheAttributes cattr ) {
      log = LoggerManager.getLogger( this );
      this.defaultCattr = cattr;
    }
  
    ////////////////////////////////////////
    public IJISPCacheAttributes getDefaultCattr() {
      return this.defaultCattr;
    }
  
    ///////////////////////////////////////////////////////////////////
     public static JISPCacheManager getInstance( IJISPCacheAttributes cattr ) {
        if (instance == null) {
          synchronized(JISPCacheManager.class) {
            if (instance == null) {
              instance = new JISPCacheManager( cattr );
            }
          }
        }
        if ( debug ) {
          log.logIt( "Manager stats : " + instance.getStats() + "<br> -- in 
getInstance()" );
        }
        clients++;
        return instance;
     }
  
     /////////////////////////////////////////////////////////
    public ICache getCache( String cacheName ) {
      IJISPCacheAttributes cattr = (IJISPCacheAttributes)defaultCattr.copy();
      cattr.setCacheName( cacheName );
      return getCache( cattr );
    }
  
    //////////////////////////////////////////////////////////
    public ICache getCache( IJISPCacheAttributes cattr ) {
        ICache raf=null;
  
        p( "cacheName = " + cattr.getCacheName() );
  
        synchronized(caches) {
          raf = (ICache)caches.get( cattr.getCacheName() );
  
          if (raf == null) {
            // make use cattr
            //raf = new JISPCache( cattr.getCacheName(), cattr.getDiskPath() );
            raf = new JISPCacheNoWaitBuffer( cattr );
            caches.put( cattr.getCacheName(), raf );
          }
        }
        if ( debug ) {
          log.logIt( "Manager stats : " + instance.getStats() );
        }
        return raf;
     }
  
  
  
    ////////////////////////////////////////////////////////////////
     public void freeCache( String name ) {
        JISPCache raf = (JISPCache)caches.get(name);
        if (raf != null) {
           raf.dispose();
        }
     }
  
    // Don't care if there is a concurrency failure ?
    public String getStats(){
      StringBuffer stats = new StringBuffer();
      Enumeration allCaches = caches.elements();
  
      while (allCaches.hasMoreElements()) {
        JISPCache raf = (JISPCache)allCaches.nextElement();
        if (raf != null) {
         stats.append( "<br>&nbsp;&nbsp;&nbsp;" + raf.getStats() );
        }
      }
      return stats.toString();
    }
  
    ///////////////////////////////////////
    public int getCacheType() {
      return DISK_CACHE;
    }
  
  
    /////////////////////////////////////////////////////////////////
    public void release() {
      // Wait until called by the last client
      if (--clients != 0) {
        return;
      }
      synchronized(caches) {
        Enumeration allCaches = caches.elements();
  
        while (allCaches.hasMoreElements()) {
          JISPCache raf = (JISPCache)allCaches.nextElement();
          if (raf != null) {
            raf.dispose();
          }
        }
      }
    } //end release()
  
  
    /////////////////////////////////////////////
    public void p( String s ) {
      if ( log.logLevel >= log.DEBUG ) {
        log.debug( s );
      }
      if ( pOut ) {
        System.out.println( "JISPCacheManager: " + s );
      }
    }
  
  
  } // end class
  
  
  
  1.1                  
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/auxiliary/disk/jisp/JISPCacheNoWaitBuffer.java
  
  Index: JISPCacheNoWaitBuffer.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  
  package org.apache.stratum.jcs.auxiliary.disk.jisp;
  
  import java.io.*;
  import java.rmi.*;
  import java.util.*;
  
  import org.apache.stratum.jcs.engine.control.*;
  import org.apache.stratum.jcs.engine.*;
  import org.apache.stratum.jcs.access.exception.*;
  import org.apache.stratum.jcs.engine.behavior.*;
  import org.apache.stratum.jcs.auxiliary.disk.jisp.behavior.*;
  import org.apache.stratum.jcs.utils.log.*;
  
  
  /**
   * Store recent arivals in a temporary queue.
   * Used to queue up update requests to the underlying cache.
   * These requests will be processed in their order of arrival
   * via the cache event queue processor.
   *
   *
   *  Note:  There is a a problem lurking in all queued distributed
   *  systems, where repopulzation of memory can occur dispite a removal
   *  if the tow arrive in different order than issued.  The possible solution
   *  to never delete, but only invlidate.  The cache can act ina cvs like mode,
   *  enforcing versions of element, checking to see if a newer version exists
   *  adding.  So a remote put could amke sure a new version hasn't arrived.
   *  Invalidaions would have version.  We could avoid spooling these since it will
   *  have been a while.  This will be called garuanteed mode and can be added
   *  to any listener.
   *
   *
   */
  public class JISPCacheNoWaitBuffer implements ICache {
  
    private static final boolean debug =  false;//true;
  
    // accessed by disk cache
    protected Hashtable purgatory = new Hashtable();
    private static final boolean debugPH =  false;//true;
    private int purgHits = 0;
  
    private IJISPCacheAttributes cattr;
    private JISPCache cache;
    private ICacheEventQueue q;
    private transient Logger log = LoggerManager.getInstance().getLogger(this);
  
    private String source_id = 
"org.apache.stratum.jcs.auxiliary.disk.jisp.JISPCacheNoWaitBuffer";
  
  
  
    ///////////////////////////////////////////////////
    public Serializable getSourceId() {
      return this.source_id;
    }
  
    /**
     * Constructs with the given disk cache,
     * and fires up an event queue for aysnchronous processing.
     */
    public JISPCacheNoWaitBuffer(IJISPCacheAttributes cattr) {
        cache = new JISPCache( this, cattr );
        this.cattr = cattr;
        this.q = new CacheEventQueue(new CacheAdaptor(cache), CacheInfo.listenerId, 
cache.getCacheName());
  
        // need each no wait to handle each of its real updates and removes, since 
there may
        // be more than one per cache?  alternativve is to have the cache
        // perform updates using a different method that spcifies the listener
        //this.q = new CacheEventQueue(new CacheAdaptor(this), 
JISPCacheInfo.listenerId, cache.getCacheName());
        if (cache.getStatus() == cache.STATUS_ERROR) {
          log.error( "destroying queue" );
          q.destroy();
        }
    }
  
    /** Adds a put request to the disk cache. */
    public void put(Serializable key, Serializable value ) throws IOException {
      put( key, value, null );
    }
    public void put(Serializable key, Serializable value,  Attributes attr ) throws 
IOException {
      try {
        CacheElement ce = new CacheElement( cache.getCacheName(), key, value );
        ce.setAttributes( attr );
        update( ce );
      } catch(IOException ex) {
        log.error(ex);
        q.destroy();
      }
    }
    public void update( ICacheElement ce ) throws IOException {
      try {
        if ( debug ) {
          p( "putting in purgatory" );
        }
  
  
        PurgatoryElement pe = new PurgatoryElement( ce );
        pe.isSpoolable = true;
        q.addPutEvent( (ICacheElement)pe );
  
        //q.addPutEvent( ce );
  
        /*
        // may be too slow
        IDiskElement ide = new DiskElement( ce );
        ide.setAttributes( ce.getAttributes() );
        purgatory.put( ide.getKey(), ide );
        //CacheElement ice = new CacheElement(ce.getCacheName(), ce.getKey(), 
ce.getVal() );
        //ice.setAttributes( ce.getAttributes() );
        ide.setIsSpoolable( true );
        q.addPutEvent( ide );
        */
  
      } catch(IOException ex) {
        log.error(ex);
        // should we destroy purgatory.  it will swell
        q.destroy();
      }
    }
  
    /** Synchronously reads from the disk cache. */
    public Serializable get(Serializable key) {
      return get( key, true );
    }
    public Serializable get(Serializable key, boolean container ) {
      //IDiskElement ide = (IDiskElement)purgatory.get( key );
      PurgatoryElement pe = (PurgatoryElement)purgatory.get(key);
      //if ( ide != null ) {
      if ( pe != null ) {
        purgHits++;
        if( debugPH ) {
          if ( purgHits % 100 == 0 ) {
            p( "purgatory hits = " + purgHits );
          }
        }
  
        //ide.setIsSpoolable( false );
        pe.isSpoolable = false;
        if ( debug ) {
          p( "found in purgatory" );
        }
        if ( container ) {
          purgatory.remove( key );
          //return (ICacheElement)ide;
          return pe.ice;
        } else {
          purgatory.remove( key );
          //return (Serializable)ide.getVal();
          return (Serializable)pe.ice.getVal();
        }
      }
      try {
        return cache.get(key);
      } catch(Exception ex) {
        q.destroy();
        // not sure we should do this.  What about purgatory?
        // must assume that we will not loose disk access
        // can make a repairer, but it complicates purgatory.
      }
      return null;
    }
  
  
    /** Adds a remove request to the disk cache. */
    public boolean remove(Serializable key) {
      purgatory.remove( key );
      try {
        q.addRemoveEvent(key);
      } catch(IOException ex) {
        log.error(ex);
        q.destroy();
      }
      return false;
    }
    /** Adds a removeAll request to the disk cache. */
    public void removeAll() {
  
      Hashtable temp = purgatory;
      purgatory = new Hashtable();
      temp = null;
  
      try {
        q.addRemoveAllEvent();
      } catch(IOException ex) {
        log.error(ex);
        q.destroy();
      }
    }
    /** Adds a dispose request to the disk cache. */
    public void dispose() {
      cache.dispose();
      // may loose the end of the queue, need to be more graceful
      q.destroy();
      /*
      try {
        q.addDisposeEvent();
      } catch(IOException ex) {
        log.error(ex);
        q.destroy();
      }
      */
  
    }
    /** No disk invokation. */
    public String getStats() {
      return cache.getStats();
    }
    /** No disk invokation. */
    public int getSize() {
      return cache.getSize();
    }
    /** No disk invokation. */
    public int getCacheType() {
      return cache.getCacheType();
    }
    /**
     * Returns the asyn cache status.
     * An error status indicates either the disk connection is not available,
     * or the asyn queue has been unexpectedly destroyed.
     * No disk invokation.
     */
    public int getStatus() {
      return q.isAlive() ? cache.getStatus() : cache.STATUS_ERROR;
    }
    public String getCacheName() {
      return cache.getCacheName();
    }
  
    /** NOT USED NOW
     * Replaces the disk cache service handle with the given handle and
     * reset the event queue by starting up a new instance.
     */
    public void fixCache(IJISPCacheService disk) {
      //cache.fixCache(disk);
      resetEventQ();
      return;
    }
    /** Resets the event q by first destroying the existing one and starting up new 
one. */
    public void resetEventQ() {
      if (q.isAlive()) {
        q.destroy();
      }
      this.q = new CacheEventQueue(new CacheAdaptor(cache), CacheInfo.listenerId, 
cache.getCacheName());
    }
    public String toString() {
      return "JISPCacheNoWaitBuffer: " + cache.toString();
    }
    private void p(String s) {
      System.out.println("JISPCacheNoWaitBuffer:" + s);
    }
  }
  
  
  
  1.1                  
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/auxiliary/disk/jisp/JISPKey.java
  
  Index: JISPKey.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  
  package org.apache.stratum.jcs.auxiliary.disk.jisp;
  
  import com.coyotegulch.jisp.*;
  
  import java.io.*;
  
  public class JISPKey extends KeyObject {
  
      //
      // working storage
      //
      public Serializable m_key;
  
      public JISPKey(Serializable key_value)
      {
          m_key = key_value;
  
      }
  
      public JISPKey()
      {
          m_key = "";
      }
  
  
      public int compareTo(KeyObject key) {
  
          if (key instanceof JISPKey) {
              int orig = ((JISPKey)key).m_key.hashCode();
              int test = key.hashCode();
              int cv = test - orig;
              if ( cv == 0  )  {
                return KEY_EQUAL;
              } else if ( cv < 0  )  {
                return KEY_LESS;
              } else {
                return KEY_MORE;
              }
              /* for string
              int cv = ((JISPKey)key).m_key.compareTo(m_key);
              if ( cv == 0  )  {
                return KEY_EQUAL;
              } else if ( cv < 0  )  {
                return KEY_LESS;
              } else {
                return KEY_MORE;
              }
              */
          }
          else
              return KEY_ERROR;
      }
  
      public KeyObject makeNullKey()
      {
          JISPKey nullKey = new JISPKey();
          nullKey.m_key = "0xFFFFFFFF";
          return nullKey;
      }
  
      public void writeExternal(ObjectOutput out) throws IOException
      {
          out.writeObject( m_key);
      }
  
      public void readExternal(ObjectInput in) throws IOException, 
ClassNotFoundException
      {
          m_key = ((Serializable)(in.readObject()));
      }
  
  //    public int intValue()
  //    {
  //        return m_key;
  //    }
  
      public String toString()
      {
          return m_key.toString();
      }
  
      public boolean equals(Object obj)
      {
          if ((obj != null) && (obj instanceof JISPKey))
              return (m_key.equals( ((JISPKey)obj).m_key ) );
          else
              return false;
      }
  
      public int hashCode()
      {
          return m_key.hashCode(); // new Integer(m_key).hashCode();
      }
  }
  
  
  
  1.1                  
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/auxiliary/disk/jisp/JISPLockManager.java
  
  Index: JISPLockManager.java
  ===================================================================
  package org.apache.stratum.jcs.auxiliary.disk.jisp;
  
  import org.apache.stratum.jcs.auxiliary.disk.*;
  import org.apache.stratum.jcs.utils.reuse.*;
  
  import java.util.*;
  
  /** Read/Write lock manager for Disk. */
  class JISPLockManager extends ReadWriteLockManager {
  
    /**
     *    @TODO might need to have this lock for only one cache at a time
     *    might want to lock on a Diskcache instance
     */
    public static final String Disk = "Disk";
    private static JISPLockManager instance;
  
    boolean debug = false;
    private final Hashtable ht = new Hashtable();
  
    ///////////////////////////////////////////////
    private JISPLockManager() {
    }
    static JISPLockManager getInstance() {
      if (instance == null) {
        synchronized(JISPLockManager.class) {
          if (instance == null) {
            instance = new JISPLockManager();
          }
        }
      }
      return instance;
    }
  
    ///////////////////////////////////////////
    protected Hashtable getLocks() {
      return ht;
    }
  
    ////////////////////////////////////////////
    void readLock() {
      try {
        readLock(Disk);
      } catch(InterruptedException ex) {
        // should never happen.
        ex.printStackTrace();
        throw new IllegalStateException(ex.getMessage());
      }
    }
  
    ////////////////////////////////////////////
    void writeLock() {
      try {
        writeLock(Disk);
      } catch(InterruptedException ex) {
        // should never happen.
        ex.printStackTrace();
        throw new IllegalStateException(ex.getMessage());
      }
    }
  
    ///////////////////////////////////////////////////
    void done() {
      done(Disk);
    }
  }
  
  
  
  1.1                  
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/auxiliary/disk/jisp/PurgatoryElement.java
  
  Index: PurgatoryElement.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  
  package org.apache.stratum.jcs.auxiliary.disk.jisp;
  
  import java.io.Serializable;
  
  import org.apache.stratum.jcs.engine.behavior.*;
  import org.apache.stratum.jcs.engine.*;
  import org.apache.stratum.jcs.engine.control.*;
  
  
  ////////////////////////////////////////////////////////////////
  public class PurgatoryElement implements ICacheElement, Serializable {
  
    // need speed here.  the method calls are unnecessary.   make protected
    protected boolean isSpoolable = false;
    protected ICacheElement ice;
  
    public PurgatoryElement( ICacheElement ice ) {
      this.ice = ice;
    }
  
   // lets the queue know that is ready to be spooled
    public boolean getIsSpoolable() {
      return isSpoolable;
    }
    public void setIsSpoolable( boolean isSpoolable ) {
      this.isSpoolable = isSpoolable;
    }
  
    // ICacheElement Methods
    public String getCacheName() {
      return ice.getCacheName();
    }
    public Serializable getKey() {
      return ice.getKey();
    }
    public Serializable getVal() {
      return ice.getVal();
    }
    public Attributes getAttributes() {
      return ice.getAttributes();
    }
    public void setAttributes( IAttributes attr ) {
      ice.setAttributes( attr );
    }
    public long getCreateTime() {
      return ice.getCreateTime();
    }
  
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to