You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@turbine.apache.org by as...@apache.org on 2002/02/17 07:59:19 UTC

cvs commit: jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/auxiliary/disk/indexed PurgatoryElement.java IndexedDiskLockManager.java IndexedDiskElementDescriptor.java IndexedDiskElement.java IndexedDiskDumper.java IndexedDiskCacheNoWaitBuffer.java IndexedDiskCacheManager.java IndexedDiskCacheFactory.java IndexedDiskCacheAttributes.java IndexedDiskCache.java IndexedDisk.java

asmuts      02/02/16 22:59:19

  Added:       src/java/org/apache/stratum/jcs/auxiliary/disk/indexed
                        PurgatoryElement.java IndexedDiskLockManager.java
                        IndexedDiskElementDescriptor.java
                        IndexedDiskElement.java IndexedDiskDumper.java
                        IndexedDiskCacheNoWaitBuffer.java
                        IndexedDiskCacheManager.java
                        IndexedDiskCacheFactory.java
                        IndexedDiskCacheAttributes.java
                        IndexedDiskCache.java IndexedDisk.java
  Log:
  changed disk to indexed subpackage
  
  Revision  Changes    Path
  1.1                  jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/auxiliary/disk/indexed/PurgatoryElement.java
  
  Index: PurgatoryElement.java
  ===================================================================
  package org.apache.stratum.jcs.auxiliary.disk.indexed;
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Velocity", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  import java.io.Serializable;
  
  import org.apache.stratum.jcs.engine.Attributes;
  
  import org.apache.stratum.jcs.engine.behavior.IAttributes;
  import org.apache.stratum.jcs.engine.behavior.ICacheElement;
  
  /**
   * Title: Description: This serves as a quickly createable wraper for
   * CacheElements in purgatory. Copyright: Copyright (c) 2001 Company:
   *
   * @author Aaron Smuts
   * @created January 15, 2002
   * @version 1.0
   */
  
  public class PurgatoryElement implements ICacheElement, Serializable
  {
  
      // need speed here.  the method calls are unnecessary.   make protected
      /**
       * Description of the Field
       */
      protected boolean isSpoolable = false;
      /**
       * Description of the Field
       */
      public ICacheElement ice;
  
  
      /**
       * Constructor for the PurgatoryElement object
       *
       * @param ice
       */
      public PurgatoryElement( ICacheElement ice )
      {
          this.ice = ice;
      }
  
  
  // lets the queue know that is ready to be spooled
      /**
       * Gets the isSpoolable attribute of the PurgatoryElement object
       *
       * @return The isSpoolable value
       */
      public boolean getIsSpoolable()
      {
          return isSpoolable;
      }
  
  
      /**
       * Sets the isSpoolable attribute of the PurgatoryElement object
       *
       * @param isSpoolable The new isSpoolable value
       */
      public void setIsSpoolable( boolean isSpoolable )
      {
          this.isSpoolable = isSpoolable;
      }
  
  
      // ICacheElement Methods
      /**
       * Gets the cacheName attribute of the PurgatoryElement object
       *
       * @return The cacheName value
       */
      public String getCacheName()
      {
          return ice.getCacheName();
      }
  
  
      /**
       * Gets the key attribute of the PurgatoryElement object
       *
       * @return The key value
       */
      public Serializable getKey()
      {
          return ice.getKey();
      }
  
  
      /**
       * Gets the val attribute of the PurgatoryElement object
       *
       * @return The val value
       */
      public Serializable getVal()
      {
          return ice.getVal();
      }
  
  
      /**
       * Gets the attributes attribute of the PurgatoryElement object
       *
       * @return The attributes value
       */
      public Attributes getAttributes()
      {
          return ice.getAttributes();
      }
  
  
      /**
       * Sets the attributes attribute of the PurgatoryElement object
       *
       * @param attr The new attributes value
       */
      public void setAttributes( IAttributes attr )
      {
          ice.setAttributes( attr );
      }
  
  
      /**
       * Gets the createTime attribute of the PurgatoryElement object
       *
       * @return The createTime value
       */
      public long getCreateTime()
      {
          return ice.getCreateTime();
      }
  
  }
  
  
  
  1.1                  jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/auxiliary/disk/indexed/IndexedDiskLockManager.java
  
  Index: IndexedDiskLockManager.java
  ===================================================================
  package org.apache.stratum.jcs.auxiliary.disk.indexed;
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Velocity", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  import java.util.Hashtable;
  
  import org.apache.stratum.jcs.utils.locking.ReadWriteLockManager;
  
  /**
   * Read/Write lock manager for Disk.
   *
   * @author asmuts
   * @created January 15, 2002
   */
  class IndexedDiskLockManager 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 final static String Disk = "Disk";
      private static IndexedDiskLockManager instance;
  
      private final Hashtable ht = new Hashtable();
  
  
      /**
       * Constructor for the DiskLockManager object
       */
      private IndexedDiskLockManager()
      {
      }
  
  
      /**
       * Gets the instance attribute of the DiskLockManager class
       *
       * @return The instance value
       */
      static IndexedDiskLockManager getInstance()
      {
          if ( instance == null )
          {
              synchronized ( IndexedDiskLockManager.class )
              {
                  if ( instance == null )
                  {
                      instance = new IndexedDiskLockManager();
                  }
              }
          }
          return instance;
      }
  
  
      /**
       * Gets the locks attribute of the DiskLockManager object
       *
       * @return The locks value
       */
      protected Hashtable getLocks()
      {
          return ht;
      }
  
  
      /**
       * Description of the Method
       */
      void readLock()
      {
          try
          {
              readLock( Disk );
          }
          catch ( InterruptedException ex )
          {
              // should never happen.
              ex.printStackTrace();
              throw new IllegalStateException( ex.getMessage() );
          }
      }
  
  
      /**
       * Description of the Method
       */
      void writeLock()
      {
          try
          {
              writeLock( Disk );
          }
          catch ( InterruptedException ex )
          {
              // should never happen.
              ex.printStackTrace();
              throw new IllegalStateException( ex.getMessage() );
          }
      }
  
  
      /**
       * Description of the Method
       */
      void done()
      {
          done( Disk );
      }
  }
  
  
  
  1.1                  jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/auxiliary/disk/indexed/IndexedDiskElementDescriptor.java
  
  Index: IndexedDiskElementDescriptor.java
  ===================================================================
  package org.apache.stratum.jcs.auxiliary.disk.indexed;
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Velocity", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  import java.io.Serializable;
  
  /**
   * Disk objects are located by descriptor entries. These are saved on shutdown
   * and loaded into memory on startup.
   *
   * @author asmuts
   * @created January 15, 2002
   */
  public class IndexedDiskElementDescriptor implements Serializable
  {
  
      /** Position of the cache data entry on disk. */
      long pos;
      /** Number of bytes the serialized form of the cache data takes. */
      public int len;
  
  
      /** Description of the Method */
      public void init( long pos, byte[] data )
      {
          this.pos = pos;
          this.len = data.length;
          //    this.hash = hashCode(data);
      }
  
  
      /** Constructor for the DiskElementDescriptor object */
      public IndexedDiskElementDescriptor() { }
  
  }
  
  
  
  1.1                  jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/auxiliary/disk/indexed/IndexedDiskElement.java
  
  Index: IndexedDiskElement.java
  ===================================================================
  package org.apache.stratum.jcs.auxiliary.disk.indexed;
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Velocity", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  import java.io.Serializable;
  
  import org.apache.stratum.jcs.auxiliary.disk.indexed.behavior.IIndexedDiskElement;
  
  import org.apache.stratum.jcs.engine.CacheElement;
  import org.apache.stratum.jcs.engine.behavior.ICacheElement;
  
  /**
   * Descriptor for each cache data entry stored on disk and put in purgatory. It
   * is used to set the spoolable flag so the queue knows that the element doesn't
   * need to be serialized.
   *
   * @author asmuts
   * @created January 15, 2002
   * @deprecated see PurgatoryElement
   */
  class IndexedDiskElement extends CacheElement implements IIndexedDiskElement, Serializable
  {
  
      private boolean isSpoolable = false;
  
  
      /**
       * Constructor for the DiskElement object
       *
       * @param ice
       */
      public IndexedDiskElement( ICacheElement ice )
      {
          this( ice.getCacheName(), ice.getKey(), ice.getVal() );
      }
  
  
      /**
       * Constructor for the DiskElement object
       *
       * @param cacheName
       * @param key
       * @param val
       */
      public IndexedDiskElement( String cacheName, Serializable key, Serializable val )
      {
          super( cacheName, key, val );
      }
  
  
      // lets the queue know that is ready to be spooled
      /**
       * Gets the isSpoolable attribute of the DiskElement object
       *
       * @return The isSpoolable value
       */
      public boolean getIsSpoolable()
      {
          return isSpoolable;
      }
  
  
      /**
       * Sets the isSpoolable attribute of the DiskElement object
       *
       * @param isSpoolable The new isSpoolable value
       */
      public void setIsSpoolable( boolean isSpoolable )
      {
          this.isSpoolable = isSpoolable;
      }
  
  }
  
  
  
  1.1                  jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/auxiliary/disk/indexed/IndexedDiskDumper.java
  
  Index: IndexedDiskDumper.java
  ===================================================================
  package org.apache.stratum.jcs.auxiliary.disk.indexed;
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Velocity", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  /**
   * Used to dump out a Disk cache from disk for debugging.
   *
   * @author asmuts
   * @created January 15, 2002
   */
  public class IndexedDiskDumper
  {
  
      /**
       * The main program for the DiskDumper class
       *
       * @param args The command line arguments
       */
      public static void main( String[] args )
      {
          if ( args.length != 1 )
          {
              System.out.println( "Usage: java org.apache.stratum.jcs.auxiliary.disk.DiskDump <cache_name>" );
              System.exit( 0 );
          }
          final IndexedDiskCache rc = new IndexedDiskCache( args[0], args[0] );
          rc.dump();
          System.exit( 0 );
      }
  }
  
  
  
  1.1                  jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/auxiliary/disk/indexed/IndexedDiskCacheNoWaitBuffer.java
  
  Index: IndexedDiskCacheNoWaitBuffer.java
  ===================================================================
  package org.apache.stratum.jcs.auxiliary.disk.indexed;
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Velocity", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  import java.io.IOException;
  import java.io.Serializable;
  
  import java.util.Hashtable;
  
  import org.apache.stratum.jcs.auxiliary.disk.indexed.behavior.IIndexedDiskCacheAttributes;
  import org.apache.stratum.jcs.auxiliary.disk.behavior.IDiskCacheService;
  
  import org.apache.stratum.jcs.engine.Attributes;
  import org.apache.stratum.jcs.engine.CacheAdaptor;
  import org.apache.stratum.jcs.engine.CacheElement;
  import org.apache.stratum.jcs.engine.CacheEventQueue;
  import org.apache.stratum.jcs.engine.CacheInfo;
  
  import org.apache.stratum.jcs.engine.behavior.ICache;
  import org.apache.stratum.jcs.engine.behavior.ICacheElement;
  import org.apache.stratum.jcs.engine.behavior.ICacheEventQueue;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogSource;
  
  /**
   * 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.
   *
   * @author asmuts
   * @created January 15, 2002
   */
  public class IndexedDiskCacheNoWaitBuffer implements ICache
  {
      private final static Log log =
          LogSource.getInstance( IndexedDiskCacheNoWaitBuffer.class );
  
      /**
       * Description of the Field
       */
      protected Hashtable purgatory = new Hashtable();
  
      private int purgHits = 0;
  
      private IIndexedDiskCacheAttributes cattr;
      private IndexedDiskCache cache;
      private ICacheEventQueue q;
  
      private String source_id = "org.apache.stratum.jcs.auxiliary.disk.DiskCacheNoWaitBuffer";
  
  
      /**
       * Gets the sourceId attribute of the DiskCacheNoWaitBuffer object
       *
       * @return The sourceId value
       */
      public Serializable getSourceId()
      {
          return this.source_id;
      }
  
  
      /**
       * Constructs with the given disk cache, and fires up an event queue for
       * aysnchronous processing.
       *
       * @param cattr
       */
      public IndexedDiskCacheNoWaitBuffer( IIndexedDiskCacheAttributes cattr )
      {
          cache = new IndexedDiskCache( 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), DiskCacheInfo.listenerId, cache.getCacheName());
          if ( cache.getStatus() == cache.STATUS_ERROR )
          {
              log.error( "destroying queue" );
              q.destroy();
          }
      }
  
  
      /**
       * Adds a put request to the disk cache.
       *
       * @param key
       * @param value
       * @exception IOException
       */
      public void put( Serializable key, Serializable value )
          throws IOException
      {
          put( key, value, null );
      }
  
  
      /**
       * Description of the Method
       *
       * @param key
       * @param value
       * @param attr
       * @exception IOException
       */
      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();
          }
      }
  
  
      /**
       * Description of the Method
       *
       * @param ce
       * @exception IOException
       */
      public void update( ICacheElement ce )
          throws IOException
      {
          try
          {
              log.debug( "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.
       *
       * @return
       * @param key
       */
      public Serializable get( Serializable key )
      {
          return get( key, true );
      }
  
  
      /**
       * Description of the Method
       *
       * @return
       * @param key
       * @param container
       */
      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 ( log.isDebugEnabled() )
              {
                  if ( purgHits % 100 == 0 )
                  {
                      log.debug( "purgatory hits = " + purgHits );
                  }
              }
  
              //ide.setIsSpoolable( false );
              pe.isSpoolable = false;
  
              log.debug( "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.
       *
       * @return
       * @param key
       */
      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.
       *
       * @return The stats value
       */
      public String getStats()
      {
          return cache.getStats();
      }
  
  
      /**
       * No disk invokation.
       *
       * @return The size value
       */
      public int getSize()
      {
          return cache.getSize();
      }
  
  
      /**
       * No disk invokation.
       *
       * @return The cacheType value
       */
      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.
       *
       * @return The status value
       */
      public int getStatus()
      {
          return q.isAlive() ? cache.getStatus() : cache.STATUS_ERROR;
      }
  
  
      /**
       * Gets the cacheName attribute of the DiskCacheNoWaitBuffer object
       *
       * @return The cacheName value
       */
      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.
       *
       * @param disk
       */
      public void fixCache( IDiskCacheService 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() );
      }
  
  
      /**
       * Description of the Method
       *
       * @return
       */
      public String toString()
      {
          return "DiskCacheNoWaitBuffer: " + cache.toString();
      }
  }
  
  
  
  1.1                  jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/auxiliary/disk/indexed/IndexedDiskCacheManager.java
  
  Index: IndexedDiskCacheManager.java
  ===================================================================
  package org.apache.stratum.jcs.auxiliary.disk.indexed;
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Velocity", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  import java.util.Enumeration;
  import java.util.Hashtable;
  
  import org.apache.stratum.jcs.auxiliary.disk.indexed.behavior.IIndexedDiskCacheAttributes;
  
  import org.apache.stratum.jcs.engine.behavior.ICache;
  import org.apache.stratum.jcs.engine.behavior.ICacheManager;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogSource;
  
  /**
   * Description of the Class
   *
   * @author asmuts
   * @created January 15, 2002
   */
  public class IndexedDiskCacheManager implements ICacheManager
  {
      private final static Log log =
          LogSource.getInstance( IndexedDiskCacheManager.class );
  
      private static int clients;
  
      private static Hashtable caches = new Hashtable();
  
      private static IndexedDiskCacheManager instance;
  
      private static IIndexedDiskCacheAttributes defaultCattr;
  
  
      /**
       * Constructor for the DiskCacheManager object
       *
       * @param cattr
       */
      private IndexedDiskCacheManager( IIndexedDiskCacheAttributes cattr )
      {
          this.defaultCattr = cattr;
      }
  
  
      /**
       * Gets the defaultCattr attribute of the DiskCacheManager object
       *
       * @return The defaultCattr value
       */
      public IIndexedDiskCacheAttributes getDefaultCattr()
      {
          return this.defaultCattr;
      }
  
  
      /**
       * Gets the instance attribute of the DiskCacheManager class
       *
       * @return The instance value
       * @param cattr
       */
      public static IndexedDiskCacheManager getInstance( IIndexedDiskCacheAttributes cattr )
      {
          if ( instance == null )
          {
              synchronized ( IndexedDiskCacheManager.class )
              {
                  if ( instance == null )
                  {
                      instance = new IndexedDiskCacheManager( cattr );
                  }
              }
          }
          if ( log.isDebugEnabled() )
          {
              log.debug( "Manager stats : " + instance.getStats() + "-- in getInstance()" );
          }
          clients++;
          return instance;
      }
  
  
      /**
       * Gets the cache attribute of the DiskCacheManager object
       *
       * @return The cache value
       * @param cacheName
       */
      public ICache getCache( String cacheName )
      {
          IIndexedDiskCacheAttributes cattr = ( IIndexedDiskCacheAttributes ) defaultCattr.copy();
          cattr.setCacheName( cacheName );
          return getCache( cattr );
      }
  
  
      /**
       * Gets the cache attribute of the DiskCacheManager object
       *
       * @return The cache value
       * @param cattr
       */
      public ICache getCache( IIndexedDiskCacheAttributes cattr )
      {
          ICache raf = null;
  
          log.debug( "cacheName = " + cattr.getCacheName() );
  
          synchronized ( caches )
          {
              raf = ( ICache ) caches.get( cattr.getCacheName() );
  
              if ( raf == null )
              {
                  // make use cattr
                  //raf = new DiskCache( cattr.getCacheName(), cattr.getDiskPath() );
                  raf = new IndexedDiskCacheNoWaitBuffer( cattr );
                  caches.put( cattr.getCacheName(), raf );
              }
          }
          if ( log.isDebugEnabled() )
          {
              log.debug( "Manager stats : " + instance.getStats() );
          }
          return raf;
      }
  
  
      /**
       * Description of the Method
       *
       * @param name
       */
      public void freeCache( String name )
      {
          IndexedDiskCache raf = ( IndexedDiskCache ) caches.get( name );
          if ( raf != null )
          {
              raf.dispose();
          }
      }
  
  
      // Don't care if there is a concurrency failure ?
      /**
       * Gets the stats attribute of the DiskCacheManager object
       *
       * @return The stats value
       */
      public String getStats()
      {
          StringBuffer stats = new StringBuffer();
          Enumeration allCaches = caches.elements();
  
          while ( allCaches.hasMoreElements() )
          {
              ICache raf = ( ICache ) allCaches.nextElement();
  
              if ( raf != null )
              {
                  stats.append( raf.getStats() );
                  stats.append( ", " );
              }
          }
  
          return stats.toString();
      }
  
  
      /**
       * Gets the cacheType attribute of the DiskCacheManager object
       *
       * @return The cacheType value
       */
      public int getCacheType()
      {
          return DISK_CACHE;
      }
  
  
      /**
       * Description of the Method
       */
      public void release()
      {
          // Wait until called by the last client
          if ( --clients != 0 )
          {
              return;
          }
          synchronized ( caches )
          {
              Enumeration allCaches = caches.elements();
  
              while ( allCaches.hasMoreElements() )
              {
                  IndexedDiskCache raf = ( IndexedDiskCache ) allCaches.nextElement();
                  if ( raf != null )
                  {
                      raf.dispose();
                  }
              }
          }
      }
  }
  
  
  
  1.1                  jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/auxiliary/disk/indexed/IndexedDiskCacheFactory.java
  
  Index: IndexedDiskCacheFactory.java
  ===================================================================
  package org.apache.stratum.jcs.auxiliary.disk.indexed;
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Velocity", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  import org.apache.stratum.jcs.auxiliary.behavior.IAuxiliaryCacheAttributes;
  import org.apache.stratum.jcs.auxiliary.behavior.IAuxiliaryCacheFactory;
  
  import org.apache.stratum.jcs.auxiliary.disk.indexed.behavior.IIndexedDiskCacheAttributes;
  
  import org.apache.stratum.jcs.engine.behavior.ICache;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogSource;
  
  /**
   * @author Aaron Smuts
   * @created January 15, 2002
   * @version 1.0
   */
  
  public class IndexedDiskCacheFactory implements IAuxiliaryCacheFactory
  {
      private final static Log log =
          LogSource.getInstance( IndexedDiskCacheFactory.class );
  
      private static String name;
  
  
      /**
       * Constructor for the DiskCacheFactory object
       */
      public IndexedDiskCacheFactory()
      {
      }
  
  
      /**
       * Description of the Method
       *
       * @return
       * @param iaca
       */
      public ICache createCache( IAuxiliaryCacheAttributes iaca )
      {
          IIndexedDiskCacheAttributes idca = ( IIndexedDiskCacheAttributes ) iaca;
          IndexedDiskCacheManager dcm = IndexedDiskCacheManager.getInstance( idca );
          return dcm.getCache( idca );
      }
  
  
      /**
       * Gets the name attribute of the DiskCacheFactory object
       *
       * @return The name value
       */
      public String getName()
      {
          return this.name;
      }
  
  
      /**
       * Sets the name attribute of the DiskCacheFactory object
       *
       * @param name The new name value
       */
      public void setName( String name )
      {
          this.name = name;
      }
  }
  
  
  
  1.1                  jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/auxiliary/disk/indexed/IndexedDiskCacheAttributes.java
  
  Index: IndexedDiskCacheAttributes.java
  ===================================================================
  package org.apache.stratum.jcs.auxiliary.disk.indexed;
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Velocity", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  import org.apache.stratum.jcs.auxiliary.behavior.IAuxiliaryCacheAttributes;
  
  import org.apache.stratum.jcs.auxiliary.disk.indexed.behavior.IIndexedDiskCacheAttributes;
  
  /**
   * Configuration class for the Indexed Disk Cache
   *
   * @author asmuts
   * @created January 15, 2002
   */
  public class IndexedDiskCacheAttributes implements IIndexedDiskCacheAttributes
  {
  
      private String cacheName;
      private String name;
  
      private String diskPath;
  
  
      /**
       * Constructor for the DiskCacheAttributes object
       */
      public IndexedDiskCacheAttributes()
      {
      }
  
  
      /**
       * Sets the diskPath attribute of the DiskCacheAttributes object
       *
       * @param path The new diskPath value
       */
      public void setDiskPath( String path )
      {
          this.diskPath = path;
      }
  
  
      /**
       * Gets the diskPath attribute of the DiskCacheAttributes object
       *
       * @return The diskPath value
       */
      public String getDiskPath()
      {
          return this.diskPath;
      }
  
  
      /**
       * Sets the cacheName attribute of the DiskCacheAttributes object
       *
       * @param s The new cacheName value
       */
      public void setCacheName( String s )
      {
          this.cacheName = s;
      }
  
  
      /**
       * Gets the cacheName attribute of the DiskCacheAttributes object
       *
       * @return The cacheName value
       */
      public String getCacheName()
      {
          return this.cacheName;
      }
  
  
      /**
       * Gets the name attribute of the DiskCacheAttributes object
       *
       * @return The name value
       */
      public String getName()
      {
          return this.name;
      }
  
  
      /**
       * Sets the name attribute of the DiskCacheAttributes object
       *
       * @param name The new name value
       */
      public void setName( String name )
      {
          this.name = name;
      }
  
  
      /**
       * Description of the Method
       *
       * @return
       */
      public IAuxiliaryCacheAttributes copy()
      {
          try
          {
              return ( IAuxiliaryCacheAttributes ) this.clone();
          }
          catch ( Exception e )
          {
          }
          return ( IAuxiliaryCacheAttributes ) this;
      }
  
  
      /**
       * Description of the Method
       *
       * @return
       */
      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/indexed/IndexedDiskCache.java
  
  Index: IndexedDiskCache.java
  ===================================================================
  package org.apache.stratum.jcs.auxiliary.disk.indexed;
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Velocity", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  import java.io.File;
  import java.io.FileNotFoundException;
  import java.io.IOException;
  import java.io.Serializable;
  
  import java.util.ConcurrentModificationException;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.Set;
  
  import java.util.Map.Entry;
  
  import org.apache.stratum.jcs.auxiliary.disk.indexed.behavior.IIndexedDiskCacheAttributes;
  import org.apache.stratum.jcs.auxiliary.disk.indexed.IndexedDiskCacheNoWaitBuffer;
  import org.apache.stratum.jcs.auxiliary.disk.indexed.PurgatoryElement;
  
  import org.apache.stratum.jcs.engine.Attributes;
  import org.apache.stratum.jcs.engine.CacheElement;
  
  import org.apache.stratum.jcs.engine.behavior.ICache;
  import org.apache.stratum.jcs.engine.behavior.ICacheElement;
  
  import org.apache.stratum.jcs.utils.data.PropertyGroups;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogSource;
  
  /**
   * @author Aaron Smuts
   * @author Hanson Char
   * @author Aaron Smuts
   * @created January 15, 2002
   * @version 1.0
   * @version 1.1 <br>
   *      <br>
   *      Changes in version 1.1:
   *      <ol>
   *        <li> replace synchronization mechanism with read/write lock manager;
   *
   *        <li> replace the use of DiskIO with Disk;
   *        <li> avoid disk write if no change to data value;
   *        <li> reduce disk fragmentation by re-using disk locations when
   *        possible;
   *      </ol>
   *
   * @version 1.2 Made the disk cache attribute driven. Uses common ICache
   *      interface and ICacheAttributes.
   */
  public class IndexedDiskCache implements ICache, Serializable
  {
      private final static Log log =
          LogSource.getInstance( IndexedDiskCache.class );
  
      private static int numCreated = 0;
      private int numInstances = 0;
  
      private final static IndexedDiskLockManager locker = IndexedDiskLockManager.getInstance();
      private String fileName;
      private String cacheName;
      private IndexedDisk dataFile;
      private IndexedDisk keyFile;
      private HashMap keyHash;
  
      /**
       * Description of the Field
       */
      public boolean isAlive = false;
      private File rafDir;
  
      IIndexedDiskCacheAttributes cattr;
  
      // not used
      private String source_id = "org.apache.stratum.jcs.auxiliary.disk.DiskCache";
  
      // disk cache buffer, need to remove key from buffer on update, if its there
      IndexedDiskCacheNoWaitBuffer buffer;
  
  
      /**
       * Gets the sourceId attribute of the DiskCache object
       *
       * @return The sourceId value
       */
      public Serializable getSourceId()
      {
          return this.source_id;
      }
  
  
      // should use this method
      /**
       * Constructor for the DiskCache object
       *
       * @param buffer
       * @param cattr
       */
      public IndexedDiskCache( IndexedDiskCacheNoWaitBuffer buffer, IIndexedDiskCacheAttributes cattr )
      {
          this( cattr.getCacheName(), cattr.getDiskPath() );
          this.cattr = cattr;
          this.buffer = buffer;
      }
  
  
      /**
       * Constructor for the DiskCache object
       *
       * @param cacheName
       */
      protected IndexedDiskCache( String cacheName )
      {
          this( cacheName, null );
      }
  
  
      /**
       * Constructor for the DiskCache object
       *
       * @param cacheName
       * @param rafroot
       */
      protected IndexedDiskCache( String cacheName, String rafroot )
      {
          numInstances++;
          this.fileName = cacheName;
          this.cacheName = cacheName;
  
          //String rafroot = cattr.getDiskPath();
          if ( rafroot == null )
          {
              try
              {
                  PropertyGroups pg = new PropertyGroups( "/cache.properties" );
                  rafroot = pg.getProperty( "diskPath" );
              }
              catch ( Exception e )
              {
                  log.error( e );
              }
          }
          rafDir = new File( rafroot );
          rafDir.mkdirs();
  
          log.info( "rafroot=" + rafroot );
  
          try
          {
              try
              {
                  dataFile = new IndexedDisk( new File( rafDir, fileName + ".data" ) );
                  keyFile = new IndexedDisk( new File( rafDir, fileName + ".key" ) );
                  if ( keyFile.length() > 0 )
                  {
                      loadKeys();
                      if ( keyHash.size() == 0 )
                      {
                          dataFile.reset();
                      }
                  }
                  else
                  {
                      keyHash = new HashMap();
                      if ( dataFile.length() > 0 )
                      {
                          dataFile.reset();
                      }
                  }
                  isAlive = true;
              }
              catch ( FileNotFoundException e )
              {
                  log.error( e );
              }
              catch ( Exception e )
              {
                  log.error( fileName, e );
              }
          }
          catch ( Exception e )
          {
              log.error( e );
  
          }
      }
      // end constructor
  
      /**
       * Description of the Method
       */
      public void loadKeys()
      {
          locker.writeLock();
          try
          {
              keyHash = ( HashMap ) keyFile.readObject( 0 );
              if ( keyHash == null )
              {
                  keyHash = new HashMap();
              }
              if ( log.isDebugEnabled() )
              {
                  log.debug( "LOADKEYS " + fileName + " -- keyHash.size() = " + keyHash.size() );
              }
          }
          catch ( Exception e )
          {
              log.error( fileName, e );
          }
          finally
          {
              locker.done();
              // release read lock.
          }
      }
      // end loadKeys
  
      /**
       * Description of the Method
       */
      public void saveKeys()
      {
          try
          {
              if ( log.isDebugEnabled() )
              {
                  log.debug( "SAVEKEYS " + fileName + " -- keyHash.size() = " + keyHash.size() );
              }
              locker.writeLock();
              try
              {
                  keyFile.reset();
                  if ( keyHash.size() > 0 )
                  {
                      keyFile.writeObject( keyHash, 0 );
                  }
              }
              finally
              {
                  locker.done();
                  // release write lock.
              }
          }
          catch ( Exception e )
          {
              log.error( e );
          }
      }
      // end saveKeys
  
      /**
       * Description of the Method
       *
       * @param key
       * @param value
       * @exception IOException
       */
      public void add( Serializable key, Serializable value )
          throws IOException
      {
          put( key, value );
      }
  
  
      // ignore the multicast field.
      /**
       * Description of the Method
       *
       * @param key
       * @param value
       * @param multicast
       * @exception IOException
       */
      public void put( Serializable key, Serializable value, boolean multicast )
          throws IOException
      {
          put( key, value );
      }
  
  
      /**
       * Description of the Method
       *
       * @param key
       * @param value
       * @exception IOException
       */
      public void put( Serializable key, Serializable value )
          throws IOException
      {
          put( key, value, null );
      }
  
  
      /**
       * Description of the Method
       *
       * @param key
       * @param value
       * @param attr
       * @exception IOException
       */
      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 );
      }
  
  
      /**
       * Description of the Method
       *
       * @param ce
       * @exception IOException
       */
      public void update( ICacheElement ce )
          throws IOException
      {
          log.debug( "update" );
  
          if ( !isAlive )
          {
              return;
          }
  
          if ( ce instanceof PurgatoryElement )
          {
              PurgatoryElement pe = ( PurgatoryElement ) ce;
              ce = pe.ice;
              if ( !pe.isSpoolable )
              {
                  log.debug( "pe is not spoolable" );
  
                  // it has been plucked from purgatory
                  return;
              }
          }
          /*
           * if ( ce instanceof IDiskElement ) {
           * IDiskElement ide = (IDiskElement)ce;
           * if ( !ide.getIsSpoolable() ) {
           * 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 ( log.isDebugEnabled() )
          {
              log.debug( "putting " + ce.getKey() + " on disk, removing from purgatory" );
          }
  
          //System.out.println( "putting " + ce );
  
          IndexedDiskElementDescriptor ded = null;
          try
          {
  
              ded = new IndexedDiskElementDescriptor();
              byte[] data = IndexedDisk.serialize( ce );
              ded.init( dataFile.length(), data );
  
              // make sure this only locks for one particular cache region
              locker.writeLock();
  
              try
              {
                  if ( !isAlive )
                  {
                      return;
                  }
                  // Presume it's an append.
                  //DiskElement re = new DiskElement( cacheName, key, value );
                  //re.init( dataFile.length(), data );
  
                  IndexedDiskElementDescriptor old = ( IndexedDiskElementDescriptor ) keyHash.put( ce.getKey(), ded );
  
                  // Item with the same key already exists in file.
                  // Try to reuse the location if possible.
                  if ( old != null && ded.len <= old.len )
                  {
                      ded.pos = old.pos;
                  }
                  dataFile.write( data, ded.pos );
                  /*
                   * Only need to write if the item with the same key and value
                   * does not already exist in the file.
                   * if (re.equals(old)) {
                   * re.pos = old.pos;
                   * }
                   * else {
                   * Item with the same key but different value already exists in file.
                   * Try to reuse the location if possible.
                   * if (old != null && re.len <= old.len) {
                   * re.pos = old.pos;
                   * }
                   * dataFile.write(data, re.pos);
                   * }
                   */
              }
              finally
              {
                  locker.done();
                  // release write lock.
              }
              if ( log.isDebugEnabled() )
              {
                  log.debug( fileName + " -- put " + ce.getKey() + " on disk at pos " + ded.pos + " size = " + ded.len );
              }
          }
          catch ( ConcurrentModificationException cme )
          {
              // do nothing, this means it has gone back to memory mid serialization
          }
          catch ( Exception e )
          {
              log.error( "cacheName = " + cacheName + ", ce.getKey() = " + ce.getKey(), e );
              //reset();
          }
          return;
      }
  
  
      /**
       * Description of the Method
       *
       * @return
       * @param key
       */
      public Serializable get( Serializable key )
      {
          return get( key, true, true );
      }
  
  
      /**
       * Description of the Method
       *
       * @return
       * @param key
       * @param container
       */
      public Serializable get( Serializable key, boolean container )
      {
          return get( key, true, true );
      }
  
  
      /**
       * Description of the Method
       *
       * @return
       * @param key
       * @param container
       * @param lock
       */
      private Serializable get( Serializable key, boolean container, final boolean lock )
      {
  
          if ( log.isDebugEnabled() )
          {
              log.debug( "getting " + key + " from disk" );
          }
  
          if ( !isAlive )
          {
              return null;
          }
  
          Serializable obj = null;
          if ( lock )
          {
              locker.readLock();
          }
          try
          {
              if ( !isAlive )
              {
                  return null;
              }
              IndexedDiskElementDescriptor ded = ( IndexedDiskElementDescriptor ) keyHash.get( key );
              if ( ded != null )
              {
                  if ( log.isDebugEnabled() )
                  {
                      log.debug( "found " + key + " on disk" );
                  }
  
                  obj = dataFile.readObject( ded.pos );
              }
              //System.out.println( "got element = " + (CacheElement)obj);
          }
          catch ( NullPointerException e )
          {
              log.error( "cacheName = " + cacheName + ", key = " + key, e );
          }
          catch ( Exception e )
          {
              log.error( "cacheName = " + cacheName + ", key = " + key, e );
          }
          finally
          {
              if ( lock )
              {
                  locker.done();
              }
          }
  
          return obj;
      }
  
  
      /**
       * Returns true if the removal was succesful; or false if there is nothing
       * to remove. Current implementation always result in a disk orphan.
       *
       * @return
       * @param key
       */
      public boolean remove( Serializable key )
      {
          locker.writeLock();
          try
          {
  
              if ( key instanceof String && key.toString().endsWith( NAME_COMPONENT_DELIMITER ) )
              {
                  // remove all keys of the same name group.
                  boolean removed = false;
                  for ( Iterator itr = keyHash.entrySet().iterator(); itr.hasNext();  )
                  {
                      Map.Entry entry = ( Map.Entry ) itr.next();
                      Object k = entry.getKey();
                      if ( k instanceof String && k.toString().startsWith( key.toString() ) )
                      {
                          itr.remove();
                          removed = true;
                      }
                  }
                  return removed;
              }
              // remove single item.
              return keyHash.remove( key ) != null;
          }
          catch ( Exception e )
          {
              log.error( e );
              reset();
          }
          finally
          {
              locker.done();
              // release write lock.
          }
          return false;
      }
  
  
      /**
       * Description of the Method
       */
      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
      /**
       * Description of the Method
       */
      public void reset()
      {
          log.debug( "Reseting cache" );
          locker.writeLock();
          try
          {
              try
              {
                  dataFile.close();
                  File file = new File( rafDir, fileName + ".data" );
                  file.delete();
                  keyFile.close();
                  File file2 = new File( rafDir, fileName + ".key" );
                  file2.delete();
              }
              catch ( Exception e )
              {
                  log.error( e );
              }
              try
              {
                  dataFile = new IndexedDisk( new File( rafDir, fileName + ".data" ) );
                  keyFile = new IndexedDisk( new File( rafDir, fileName + ".key" ) );
                  keyHash = new HashMap();
              }
              catch ( IOException e )
              {
                  log.error( "IN RESET", e );
              }
              catch ( Exception e )
              {
                  log.error( "IN RESET", e );
              }
          }
          finally
          {
              locker.done();
              // release write lock.
          }
      }
      // end reset
  
      /**
       * Gets the stats attribute of the DiskCache object
       *
       * @return The stats value
       */
      public String getStats()
      {
          return "fileName = " + fileName + ", numInstances = " + numInstances;
      }
  
  
      // shold be called by cachemanager, since it knows how
      // many are checked out
      /**
       * Description of the Method
       */
      public void dispose()
      {
          if ( !isAlive )
          {
              log.debug( "is not alive and close() was called -- " + fileName );
              return;
          }
          locker.writeLock();
          try
          {
              if ( !isAlive )
              {
                  log.debug( "is not alive and close() was called -- " + fileName );
                  return;
              }
              try
              {
                  optimizeFile();
              }
              catch ( Exception e )
              {
                  log.error( fileName, e );
              }
              try
              {
                  numInstances--;
                  if ( numInstances == 0 )
                  {
                      log.warn( "dispose -- Closing files -- in close -- " + fileName );
                      dataFile.close();
                      dataFile = null;
                      keyFile.close();
                      keyFile = null;
                  }
              }
              catch ( Exception e )
              {
                  log.error( "-- " + fileName, e );
              }
          }
          finally
          {
              isAlive = false;
              locker.done();
              // release write lock;
          }
      }
      // end dispose
  
      /**
       * Note: synchronization currently managed by the only caller method -
       * dispose.
       */
      private void optimizeFile()
      {
          try
          {
              // Migrate from keyHash to keyHshTemp in memory,
              // and from dataFile to dataFileTemp on disk.
              HashMap keyHashTemp = new HashMap();
              IndexedDisk dataFileTemp = new IndexedDisk( new File( rafDir, fileName + "Temp.data" ) );
              if ( log.isDebugEnabled() )
              {
                  log.info( "optomizing file keyHash.size()=" + keyHash.size() );
              }
              Iterator itr = keyHash.keySet().iterator();
              while ( itr.hasNext() )
              {
                  Serializable key = ( Serializable ) itr.next();
  
                  // Must not have a read-lock;  Else results in deadlock.
                  CacheElement tempDe = ( CacheElement ) get( key, true, false );
                  try
                  {
                      IndexedDiskElementDescriptor de = dataFileTemp.appendObject( tempDe );
                      if ( log.isDebugEnabled() )
                      {
                          log.debug( fileName + " -- Put " + key + " on temp disk cache" );
                      }
                      keyHashTemp.put( key, de );
                  }
                  catch ( Exception e )
                  {
                      log.error( fileName + " -- cacheName = "
                           + cacheName + ", key = " + key, e );
                  }
              }
              // end while
              if ( log.isDebugEnabled() )
              {
                  log.debug( fileName + " -- keyHashTemp.size() =  " + keyHashTemp.size()
                       + " / keyHash.size() =  " + keyHash.size() );
              }
              // Make dataFileTemp to become dataFile on disk.
              dataFileTemp.close();
              dataFile.close();
              File oldData = new File( rafDir, fileName + ".data" );
              if ( oldData.exists() )
              {
                  if ( log.isDebugEnabled() )
                  {
                      log.debug( fileName + " -- oldData.length() = " + oldData.length() );
                  }
                  oldData.delete();
              }
              File newData = new File( rafDir, fileName + "Temp.data" );
              File newFileName = new File( rafDir, fileName + ".data" );
              if ( newData.exists() )
              {
                  if ( log.isDebugEnabled() )
                  {
                      log.debug( fileName + " -- newData.length() = " + newData.length() );
                  }
                  newData.renameTo( newFileName );
              }
              keyHash = keyHashTemp;
              keyFile.reset();
              saveKeys();
          }
          catch ( Exception e )
          {
              log.error( fileName, e );
          }
      }
      // end optimizeFile
  
      /**
       * Returns the cache status.
       *
       * @return The status value
       */
      public int getStatus()
      {
          return isAlive ? STATUS_ALIVE : STATUS_DISPOSED;
      }
  
  
      /**
       * Returns the current cache size.
       *
       * @return The size value
       */
      public int getSize()
      {
          return keyHash.size();
      }
  
  
      /**
       * Gets the cacheType attribute of the DiskCache object
       *
       * @return The cacheType value
       */
      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();
              IndexedDiskElementDescriptor ded = ( IndexedDiskElementDescriptor ) e.getValue();
              Serializable val = get( key );
              log.debug( "disk dump> key=" + key + ", val=" + val + ", pos=" + ded.pos );
          }
      }
  
  
      /**
       * Returns cache name, ha
       *
       * @return The cacheName value
       */
      public String getCacheName()
      {
          return cacheName;
      }
  }
  
  
  
  
  1.1                  jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/auxiliary/disk/indexed/IndexedDisk.java
  
  Index: IndexedDisk.java
  ===================================================================
  package org.apache.stratum.jcs.auxiliary.disk.indexed;
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Velocity", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  import java.io.BufferedInputStream;
  import java.io.ByteArrayInputStream;
  import java.io.ByteArrayOutputStream;
  import java.io.File;
  import java.io.FileNotFoundException;
  import java.io.InputStream;
  import java.io.IOException;
  import java.io.ObjectInputStream;
  import java.io.ObjectOutputStream;
  import java.io.OutputStream;
  import java.io.RandomAccessFile;
  import java.io.Serializable;
  
  import org.apache.stratum.jcs.engine.CacheElement;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogSource;
  
  /**
   * Provides thread safe access to the underlying random access file.
   *
   * @author asmuts
   * @created January 15, 2002
   */
  class IndexedDisk
  {
      private final static Log log =
          LogSource.getInstance( IndexedDisk.class );
  
      private final String filepath;
  
      private RandomAccessFile raf;
  
  
      /**
       * Constructor for the Disk object
       *
       * @param file
       * @exception FileNotFoundException
       */
      IndexedDisk( File file )
          throws FileNotFoundException
      {
          this.filepath = file.getAbsolutePath();
          raf = new RandomAccessFile( filepath, "rw" );
      }
  
  
      /**
       * Description of the Method
       *
       * @return
       * @param pos
       */
      Serializable readObject( long pos )
      {
          byte[] data = null;
          boolean corrupted = false;
          try
          {
              synchronized ( this )
              {
                  raf.seek( pos );
                  int datalen = raf.readInt();
                  if ( datalen > raf.length() )
                  {
                      corrupted = true;
                  }
                  else
                  {
                      raf.readFully( data = new byte[datalen] );
                  }
              }
              if ( corrupted )
              {
                  log.debug( "The datFile is corrupted" );
                  //reset();
                  return null;
              }
              ByteArrayInputStream bais = new ByteArrayInputStream( data );
              BufferedInputStream bis = new BufferedInputStream( bais );
              ObjectInputStream ois = new ObjectInputStream( bis );
              try
              {
                  return ( Serializable ) ois.readObject();
              }
              finally
              {
                  ois.close();
              }
          }
          catch ( Exception e )
          {
              log.error( raf, e );
          }
          return null;
      }
  
  
      /**
       * Appends byte array to the Disk.
       *
       * @return
       * @param data
       */
      boolean append( byte[] data )
      {
          try
          {
              synchronized ( this )
              {
                  return write( data, raf.length() );
              }
          }
          catch ( IOException ex )
          {
              ex.printStackTrace();
          }
          return false;
      }
  
  
      /**
       * Writes the given byte array to the Disk at the specified position.
       *
       * @return
       * @param data
       * @param pos
       */
      boolean write( byte[] data, long pos )
      {
          if ( log.isDebugEnabled() )
          {
              log.debug( "write> pos=" + pos );
              log.debug( raf + " -- data.length = " + data.length );
          }
          try
          {
              synchronized ( this )
              {
                  raf.seek( pos );
                  raf.writeInt( data.length );
                  raf.write( data );
              }
              return true;
          }
          catch ( IOException ex )
          {
              ex.printStackTrace();
          }
          return false;
      }
  
  
      /**
       * Description of the Method
       *
       * @return
       * @param obj
       * @param pos
       */
      boolean writeObject( Serializable obj, long pos )
      {
          try
          {
              return write( serialize( obj ), pos );
          }
          catch ( IOException ex )
          {
              ex.printStackTrace();
          }
          return false;
      }
  
  
      /**
       * Description of the Method
       *
       * @return
       * @param obj
       */
      IndexedDiskElementDescriptor appendObject( CacheElement obj )
      {
          long pos = -1;
          boolean success = false;
          try
          {
  
              IndexedDiskElementDescriptor ded = new IndexedDiskElementDescriptor();
              byte[] data = serialize( obj );
  
              synchronized ( this )
              {
                  pos = raf.length();
                  ded.init( pos, data );
                  success = write( data, pos );
              }
              //return  success ? new DiskElement(pos, data) : null;
              return success ? ded : null;
          }
          catch ( IOException ex )
          {
              ex.printStackTrace();
          }
          return null;
      }
  
  
      /**
       * Returns the raf length.
       *
       * @return
       * @exception IOException
       */
      long length()
          throws IOException
      {
          synchronized ( this )
          {
              return raf.length();
          }
      }
  
  
      /**
       * Closes the raf.
       *
       * @exception IOException
       */
      synchronized void close()
          throws IOException
      {
          raf.close();
          return;
      }
  
  
      /**
       * Sets the raf to empty.
       *
       * @exception IOException
       */
      synchronized void reset()
          throws IOException
      {
          raf.close();
          File f = new File( filepath );
          int i = 0;
          for ( ; i < 10 && !f.delete(); i++ )
          {
              try
              {
                  Thread.currentThread().sleep( 1000 );
              }
              catch ( InterruptedException ex )
              {
              }
              log.warn( "Failed to delete " + f.getName() + " " + i );
          }
          if ( i == 10 )
          {
              IllegalStateException ex = new IllegalStateException( "Failed to delete " + f.getName() );
              log.error( ex );
              throw ex;
          }
          raf = new RandomAccessFile( filepath, "rw" );
          return;
      }
  
  
      /**
       * Returns the serialized form of the given object in a byte array.
       *
       * @return
       * @param obj
       * @exception IOException
       */
      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();
      }
  }
  
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>