You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jcs-dev@jakarta.apache.org by hc...@apache.org on 2005/01/24 11:29:45 UTC

cvs commit: jakarta-turbine-jcs/sandbox/yajcache/src/org/apache/jcs/yajcache/file CacheFileContent.java CacheFileContentType.java CacheFileDAO.java CacheFileUtils.java

hchar       2005/01/24 02:29:45

  Added:       sandbox/yajcache/src/org/apache/jcs/yajcache/file
                        CacheFileContent.java CacheFileContentType.java
                        CacheFileDAO.java CacheFileUtils.java
  Log:
  cache file system
  
  Revision  Changes    Path
  1.1                  jakarta-turbine-jcs/sandbox/yajcache/src/org/apache/jcs/yajcache/file/CacheFileContent.java
  
  Index: CacheFileContent.java
  ===================================================================
  
  /*
   * Copyright 2001-2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License")
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.jcs.yajcache.file;
  
  import java.io.IOException;
  import java.io.RandomAccessFile;
  import java.util.Arrays;
  
  import org.apache.jcs.yajcache.annotate.*;
  
  /**
   * Cache File Content which represents the file persistence format 
   * of a cache item.
   *
   *<pre>
   * File format:
   * <FileContentType>    : byte
   * <ByteArrayLength>    : int
   * <ByteArrayHashCode>  : int
   * <ByteArray>          : byte[]
   *</pre>
   *
   * @author Hanson Char
   */
  @CopyRightApache
  class CacheFileContent {
      /**
       * Minimum File Length =
       * contentType (1 byte) + contentLength (4 bytes) + contentHashCode (4 bytes)
       */
      static final int MIN_FILE_LENGTH = 1 + 4 + 4;
      private byte contentType;
      private int contentLength;
      private int contentHashCode;
      
      private byte[] content;
      
      private CacheFileContent() {}
      
      /**
       * Constructs an instance of CacheFileContent from the given content type
       * and content.
       */
      private CacheFileContent(
              @NonNullable CacheFileContentType contentType,
              @NonNullable byte[] content) 
      {
          this.contentType = contentType.toByte();
          this.content = content;
          this.contentLength = this.content.length;
          this.contentHashCode = Arrays.hashCode(this.content);
      }
      /**
       * Write the current cache file content to the given random access file.
       */
      void write(@NonNullable RandomAccessFile raf) throws IOException {
          // File content type.
          raf.writeByte(this.contentType);
          // Byte array length.
          raf.writeInt(this.contentLength);
          // Byte array hashcode.
          raf.writeInt(this.contentHashCode);
          // Byte array.
          raf.write(this.content);
      }
  
      @NonNullable public byte[] getContent() {
          return content;
      }
  
      public void setContent(byte[] content) {
          this.content = content == null ? new byte[0] : content;
      }
  
      public byte getContentType() {
          return contentType;
      }
  
      public void setContentType(byte contentType) {
          this.contentType = contentType;
      }
  
      public int getContentLength() {
          return contentLength;
      }
  
      void setContentLength(int contentLength) {
          this.contentLength = contentLength;
      }
  
      public int getContentHashCode() {
          return contentHashCode;
      }
      
      void setContentHashCode(int contentHashCode) {
          this.contentHashCode = contentHashCode;
      }
      /**
       * Returns true iff the current hash code is consistent with 
       * the content.
       */
      public boolean isValid() {
          int hash = Arrays.hashCode(this.content);
          return hash == this.contentHashCode;
      }
      /**
       * Returns an instance of CacheFileContent from the given content type
       * and content.
       */
      @NonNullable
      static CacheFileContent getInstance(
              @NonNullable CacheFileContentType contentType, 
              @NonNullable byte[] content) 
          throws IOException 
      {
          return new CacheFileContent(contentType, content);
      }
      /**
       * Returns an instance of CacheFileContent from the given random access file;
       */
      @NonNullable
      static CacheFileContent getInstance(@NonNullable RandomAccessFile raf) 
          throws IOException
      {
          CacheFileContent cfc = new CacheFileContent();
          cfc.setContentType(raf.readByte());
          final int len = raf.readInt();
          cfc.setContentLength(len);
          cfc.setContentHashCode(raf.readInt());
          byte[] ba = new byte[len];
          // Byte array.
          raf.readFully(ba);
          cfc.setContent(ba);
          return cfc;
      }
  }
  
  
  
  1.1                  jakarta-turbine-jcs/sandbox/yajcache/src/org/apache/jcs/yajcache/file/CacheFileContentType.java
  
  Index: CacheFileContentType.java
  ===================================================================
  
  /*
   * Copyright 2001-2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License")
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.jcs.yajcache.file;
  
  import org.apache.jcs.yajcache.annotate.*;
  
  /**
   * Cache File Content Type.  A cache file represents the file persistence
   * format of a cache item.
   * Currently the content of a cache item can be persisted into an array of
   * bytes via either Java Serialization, or the XMLEncoder.
   *
   * @author Hanson Char
   */
  @CopyRightApache
  public enum CacheFileContentType {
      JAVA_SERIALIZATION,
      XML_ENCODER;
  
      /** Returns a single byte representing the content type. */
      public byte toByte() {
          switch(this) {
              case JAVA_SERIALIZATION:
                  return 0;
              case XML_ENCODER:
                  return 1;
              default:
                  throw new IllegalStateException("Should never happen");
          }
      }
      /** 
       * Returns the corresponding CacheFileContentType enum instance 
       * from the given byte value. 
       */
      @NonNullable 
      public static CacheFileContentType fromByte(byte b) {
          switch(b) {
              case 0:
                  return JAVA_SERIALIZATION;
              case 1:
                  return XML_ENCODER;
              default:
                  throw new IllegalArgumentException("Unsupported b="+b);
          }
      }
  }
  
  
  
  1.1                  jakarta-turbine-jcs/sandbox/yajcache/src/org/apache/jcs/yajcache/file/CacheFileDAO.java
  
  Index: CacheFileDAO.java
  ===================================================================
  
  /*
   * Copyright 2001-2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License")
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.jcs.yajcache.file;
  
  import java.io.File;
  import java.io.IOException;
  import java.io.RandomAccessFile;
  import java.util.Arrays;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.apache.jcs.yajcache.annotate.*;
  import org.apache.commons.lang.builder.*;
  
  
  /**
   * Cache File Data Access Object.
   *
   * @author Hanson Char
   */
  @CopyRightApache
  public enum CacheFileDAO {
      inst;
  
      private volatile int countWriteIOException;
      private volatile int countWriteCloseException;
      private volatile int countReadIOException;
      private volatile int countReadCloseException;
      private volatile int countCorruptMinLength;
      private volatile int countCorruptLength;
      private volatile int countCorruptInvalid;
      
      private Log log = LogFactory.getLog(this.getClass());
      
      /**
       * Writes the specified cache item into the file system.
       *
       * @return true if successful; false otherwise.
       */
      public boolean writeCacheItem(
              String cacheName, CacheFileContentType type, String key, byte[] val)
      {
          File file = CacheFileUtils.inst.getCacheFile(cacheName, key);
          RandomAccessFile raf = null;
          try {
              file.delete();
              file.createNewFile();
              raf = new RandomAccessFile(file, "rw");
              CacheFileContent.getInstance(type, val).write(raf);
              return true;
          } catch(IOException ex) {
              countWriteIOException++;
              log.error("", ex);
          } finally {
              if (raf != null) {
                  try {
                      raf.close();
                  } catch(Exception ex) {
                      countWriteCloseException++;
                      log.error("", ex);
                  }
              }
          }
          return false;
      }
      /**
       * Reads the byte array of a specified cache item from the file system.
       * 
       * @return the byte array of a specified cache item from the file system;
       * or null if it can't.
       */
      public byte[] readCacheItem(String cacheName, String key) {
          File file = CacheFileUtils.inst.getCacheFile(cacheName, key);
          
          if (!file.exists())
              return null;
          final long fileSize = file.length();
          
          if (fileSize <= CacheFileContent.MIN_FILE_LENGTH) {
              countCorruptMinLength++;
              log.warn("Corrupted file which failed the minimum length condition for cacheName=" 
                      + cacheName + " key=" + key);
              return null;
          }
          RandomAccessFile raf = null;
          try {
              raf = new RandomAccessFile(file, "r");
              CacheFileContent cfc = CacheFileContent.getInstance(raf);
              
              if (cfc.isValid()) {
                  final int contentLength = (int)fileSize - CacheFileContent.MIN_FILE_LENGTH;
                  
                  if (contentLength != cfc.getContentLength()) {
                      countCorruptLength++;
                      log.warn("Corrupted file with unexpected content length for cacheName=" 
                              + cacheName + " key=" + key);
                      return null;
                  }
              }
              else
              {
                  countCorruptInvalid++;
                  log.warn("Corrupted file for cacheName=" + cacheName 
                          + " key=" + key);
                  return null;
              }
              return cfc.getContent();
          } catch(IOException ex) {
              countReadIOException++;
              log.warn("", ex);
          } finally {
              if (raf != null) {
                  try {
                      raf.close();
                  } catch(Exception ex) {
                      countReadCloseException++;
                      log.error("", ex);
                  }
              }
          }
          return null;
      }
      /**
       * Removes the specified cache item from the file system.
       *
       * @return true if successful; false otherwise.
       */
      public boolean removeCacheItem(String cacheName, String key)
      {
          File file = CacheFileUtils.inst.getCacheFile(cacheName, key);
          return file.delete();
      }
  
      @Override 
      public String toString() {
          return ToStringBuilder.reflectionToString(this);
      }
  }
  
  
  
  1.1                  jakarta-turbine-jcs/sandbox/yajcache/src/org/apache/jcs/yajcache/file/CacheFileUtils.java
  
  Index: CacheFileUtils.java
  ===================================================================
  
  /*
   * Copyright 2001-2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License")
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.jcs.yajcache.file;
  
  import java.io.File;
  import org.apache.jcs.yajcache.config.YajCacheConfig;
  import org.apache.jcs.yajcache.annotate.*;
  
  /**
   * Cache File Utilities.
   *
   * @author Hanson Char
   */
  @CopyRightApache
  public enum CacheFileUtils {
      inst;
      
      /** 
       * Creates the directory for the specified cache, 
       * including any necessary but nonexistent parent directories.
       * Note that if this operation fails it may have succeeded in 
       * creating some of the necessary parent directories.
       *
       * @return true if succesfull; false otherwise.
       */
      boolean mkCacheDirs(@NonNullable String cacheName) {
          File dir = this.getCacheDir(cacheName);
          return dir.mkdirs();
      }
      /**
       * Removes the file directory for the specified cache,
       * including all files under the directory.
       */
      boolean rmCacheDir(@NonNullable String cacheName) {
          File dir = this.getCacheDir(cacheName);
          
          if (!dir.exists())
              return true;
          for (File f : dir.listFiles()) {
              f.delete();
          }
          return dir.delete();
      }
      /**
       * Returns the file directory for the specified cache.
       */
      @NonNullable File getCacheDir(@NonNullable String cacheName) {
          return new File(YajCacheConfig.inst.getCacheDir(), cacheName);
      }
      /**
       * Returns the cache file for the specified cache item.
       */
      @NonNullable File getCacheFile(
              @NonNullable String cacheName,
              @NonNullable String key) 
      {
          File dir = this.getCacheDir(cacheName);
          return new File(dir, key);
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: turbine-jcs-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: turbine-jcs-dev-help@jakarta.apache.org