You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by fr...@apache.org on 2002/01/12 17:55:43 UTC

cvs commit: jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore StoreJanitorImpl.java StoreJanitor.java Store.java MRUMemoryStore.java JispStringKey.java JispFilesystemStore.java

froehlich    02/01/12 08:55:43

  Added:       simplestore/src/java/org/apache/commons/simplestore
                        StoreJanitorImpl.java StoreJanitor.java Store.java
                        MRUMemoryStore.java JispStringKey.java
                        JispFilesystemStore.java
  Log:
  inital commit of the simplestore components
  
  Revision  Changes    Path
  1.1                  jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/StoreJanitorImpl.java
  
  Index: StoreJanitorImpl.java
  ===================================================================
  /*****************************************************************************
   * Copyright (C) The Apache Software Foundation. All rights reserved.        *
   * ------------------------------------------------------------------------- *
   * This software is published under the terms of the Apache Software License *
   * version 1.1, a copy of which has been included  with this distribution in *
   * the LICENSE file.                                                         *
   *****************************************************************************/
  
  package org.apache.commons.simplestore;
  
  import java.util.ArrayList;
  import java.util.Iterator;
  
  /**
   * This class is a implentation of a StoreJanitor. Store classes
   * can register to the StoreJanitor. When memory is too low,
   * the StoreJanitor frees the registered caches until memory is normal.
   *
   * @author <a href="mailto:g-froehlich@gmx.de">Gerhard Froehlich</a>
   */
  public class StoreJanitorImpl 
  implements StoreJanitor,
             Runnable {
  
      private int mFreeMemory = -1;
      private int mHeapSize = -1;
      private int mThreadInterval = -1;
      private int mThreadPriority = -1;
      private Runtime mJVM;
      private ArrayList mStoreList;
      private int mIndex = -1;
      private static boolean mDoRun = false;
  
      /**
       * Initialize the StoreJanitorImpl.
       *
       * @param the Configuration of the application
       * @exception ConfigurationException
       */
      public void initialize() {
          this.mJVM = Runtime.getRuntime();
          this.mStoreList = new ArrayList();
      }
  
      public void start() {
          mDoRun = true;
          Thread checker = new Thread(this);
          checker.setPriority(this.getThreadPriority());
          checker.setDaemon(true);
          checker.setName("checker");
          checker.start();
      }
  
      public void stop() {
          mDoRun = false;
      }
  
      /**
       * The "checker" thread checks if memory is running low in the jvm.
       */
      public void run() {
          while (mDoRun) {
              // amount of memory used is greater then heapsize
              if (this.memoryLow()) {
                  this.freePhysicalMemory();
                  synchronized (this) {
                      while (this.memoryLow() && this.mStoreList.size() > 0) {
                          this.freeMemory();
                      }
                      this.resetIndex();
                  }
              }
              try {
                  Thread.currentThread().sleep(this.mThreadInterval * 1000);
              } catch (InterruptedException ignore) {}
          }
      }
  
      /**
       * Method to check if memory is running low in the JVM.
       *
       * @return true if memory is low
       */
      private boolean memoryLow() {
          return this.mJVM.totalMemory() > this.getHeapsize() && this.mJVM.freeMemory() < this.getFreememory();
      }
  
      /**
       * This method register the stores
       *
       * @param the store to be registered
       */
      public void register(Store store) {
          this.mStoreList.add(store);
      }
  
      /**
       * This method unregister the stores
       *
       * @param the store to be unregistered
       */
      public void unregister(Store store) {
          this.mStoreList.remove(store);
      }
  
      /**
       * This method return a java.util.Iterator of every registered stores
       *
       * @return a java.util.Iterator
       */
      public Iterator iterator() {
          return this.mStoreList.iterator();
       }
       
      /**
       * Round Robin alghorithm for freeing the registerd caches.
       */
      private void freeMemory() {
          try {
              if (this.mIndex < this.mStoreList.size()) {
                  if(this.mIndex == -1) {
                      ((Store)this.mStoreList.get(0)).free();
                      this.mIndex = 0;
                  } else {
                      ((Store)this.mStoreList.get(this.mIndex)).free();
                      this.mIndex = this.mIndex + 1;
                  }
              } else {
                  this.resetIndex();
                  ((Store)this.mStoreList.get(0)).free();
                  this.mIndex = 0;
              }
              this.freePhysicalMemory();
          } catch(Exception e) {
              e.printStackTrace();
          }
      }
  
      /**
       * This method forces the garbage collector
       */
      private void freePhysicalMemory() {
          this.mJVM.runFinalization();
          this.mJVM.gc();
      }
  
      public int getFreememory() {
          return mFreeMemory;
      }
  
      public void setFreeMemory(int _freememory) {
          this.mFreeMemory = _freememory;
      }
  
      public int getHeapsize() {
          return this.mHeapSize;
      }
  
      public void setHeapsize(int _heapsize) {
          this.mHeapSize = _heapsize;
      }
  
      public int getThreadInterval() {
          return this.mThreadInterval;
      }
  
      public void setThreadInterval(int _cleanupthreadinterval) {
          this.mThreadInterval = _cleanupthreadinterval;
      }
  
      public int getThreadPriority() {
          return this.mThreadPriority;
      }
  
      public void setThreadPriority(int _priority) {
          this.mThreadPriority = _priority;
      }
  
      private void resetIndex() {
          this.mIndex = -1;
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/StoreJanitor.java
  
  Index: StoreJanitor.java
  ===================================================================
  /*****************************************************************************
   * Copyright (C) The Apache Software Foundation. All rights reserved.        *
   * ------------------------------------------------------------------------- *
   * This software is published under the terms of the Apache Software License *
   * version 1.1, a copy of which has been included  with this distribution in *
   * the LICENSE file.                                                         *
   *****************************************************************************/
  package org.apache.commons.simplestore;
  
  import java.util.Iterator;
  
  /**
   * Interface for the StoreJanitors
   *
   * @author <a href="mailto:g-froehlich@gmx.de">Gerhard Froehlich</a>
   */
  public interface StoreJanitor {
  
      /** register method for the stores */
      void register(Store store);
  
      /** unregister method for the stores */
      void unregister(Store store);
      
      /** get an iterator to list registered stores */
      Iterator iterator();
  }
  
  
  
  1.1                  jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/Store.java
  
  Index: Store.java
  ===================================================================
  /*****************************************************************************
   * Copyright (C) The Apache Software Foundation. All rights reserved.        *
   * ------------------------------------------------------------------------- *
   * This software is published under the terms of the Apache Software License *
   * version 1.1, a copy of which has been included  with this distribution in *
   * the LICENSE file.                                                         *
   *****************************************************************************/
  package org.apache.commons.simplestore;
  
  import java.io.IOException;
  import java.util.Enumeration;
  
  /**
   * Interface for the Store implementations
   *
   * @author <a href="mailto:g-froehlich@gmx.de">Gerhard Froehlich</a>
   */
  public interface Store {
  
      /**
       * Get the object associated to the given unique key.
       */
      Object get(Object key);
  
      /**
       * Store the given object in a persistent state. It is up to the
       * caller to ensure that the key has a persistent state across
       * different JVM executions.
       */
      void store(Object key, Object value) throws IOException;
  
      /**
       * Holds the given object in a volatile state. This means
       * the object store will discard held objects if the
       * virtual machine is restarted or some error happens.
       */
      void hold(Object key, Object value) throws IOException;
  
      void free();
  
      /**
       * Remove the object associated to the given key.
       */
      void remove(Object key);
  
      /**
       * Indicates if the given key is associated to a contained object.
       */
      boolean containsKey(Object key);
  
      /**
       * Returns the list of used keys as an Enumeration of Objects.
       */
      Enumeration keys();
  }
  
  
  
  1.1                  jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/MRUMemoryStore.java
  
  Index: MRUMemoryStore.java
  ===================================================================
  /*****************************************************************************
   * Copyright (C) The Apache Software Foundation. All rights reserved.        *
   * ------------------------------------------------------------------------- *
   * This software is published under the terms of the Apache Software License *
   * version 1.1, a copy of which has been included  with this distribution in *
   * the LICENSE file.                                                         *
   *****************************************************************************/
  
  package org.apache.commons.simplestore;
  
  import java.util.Enumeration;
  import java.util.Hashtable;
  import java.util.LinkedList;
  
  /**
   *  This class provides a cache algorithm for the requested documents. It
   *  combines a HashMap and a LinkedList to create a so called MRU (Most Recently
   *  Used) cache.
   *
   * @author     <a href="mailto:g-froehlich@gmx.de">Gerhard Froehlich</a>
   */
  public final class MRUMemoryStore
  implements Store {
  
      private int mMaxObjects = 100;
      private Hashtable mCache;
      private LinkedList mMRUList;
      private StoreJanitor mStorejanitor;
  
      public void setMaxObjects(int maxobjects) {
          this.mMaxObjects = maxobjects;
      }
  
      public int getMaxObjects() {
          return this.mMaxObjects;
      }
  
      public void initialize() {
          this.mCache = new Hashtable((int) (this.getMaxObjects() * 1.2));
          this.mMRUList = new LinkedList();
      }
  
      /**
       *  Get the object associated to the given unique key.
       *
       * @param the Key Object
       * @return the Object associated with Key Object
       */
      public Object get(Object key) {
          Object tmpobject = this.mCache.get(key);
          if (tmpobject != null) {
              this.mMRUList.remove(key);
              this.mMRUList.addFirst(key);
              return tmpobject;
          }
          return null;
      }
    
  
      /**
       *  Store the given object in a persistent state. It is up to the caller to
       *  ensure that the key has a persistent state across different JVM
       *  executions.
       *
       * @param the Key Object
       * @param the Value Object
       */
      public void store(Object key, Object value) {
          this.hold(key,value);
      }
  
      /**
       *  This method holds the requested object in a HashMap combined with a
       *  LinkedList to create the MRU. It also stores objects onto the filesystem
       *  if configured.
       *
       * @param the Key Object
       * @param the Value Object
       */
      public void hold(Object key, Object value) {
          while (this.mMRUList.size() >= this.mMaxObjects) {
              this.free();
          }
          this.mCache.put(key, value);
          this.mMRUList.remove(key);
          this.mMRUList.addFirst(key);
      }
  
      /**
       *  Remove the object associated to the given key.
       *
       * @param the Key object
       */
      public void remove(Object key) {
          this.mCache.remove(key);
          this.mMRUList.remove(key);
      }
  
      /**
       *  Indicates if the given key is associated to a contained object.
       *
       * @param the Key Object
       * @return true if Key exists and false if not
       */
      public boolean containsKey(Object key) {
          return this.mCache.containsKey(key);
      }
  
      /**
       *  Returns the list of used keys as an Enumeration.
       *
       * @return    the enumeration of the cache
       */
      public Enumeration keys() {
          return this.mCache.keys();
      }
  
      /**
       *  Frees some of the fast memory used by this store. It removes the last
       *  element in the store.
       */
      public void free() {
          try {
              if (this.mCache.size() > 0) {
                  this.mCache.remove(this.mMRUList.getLast());
                  this.mMRUList.removeLast();
              }
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/JispStringKey.java
  
  Index: JispStringKey.java
  ===================================================================
  /*****************************************************************************
   * Copyright (C) The Apache Software Foundation. All rights reserved.        *
   * ------------------------------------------------------------------------- *
   * This software is published under the terms of the Apache Software License *
   * version 1.1, a copy of which has been included  with this distribution in *
   * the LICENSE file.                                                         *
   *****************************************************************************/
  
  package org.apache.commons.simplestore;
  
  import com.coyotegulch.jisp.KeyObject;
  import java.io.IOException;
  import java.io.ObjectInput;
  import java.io.ObjectOutput;
  
  /**
   *  Wrapper class to make our cache Key compatible with the Jisp KeyObject NOTE:
   *  This Wrapper is only for String Keys.
   *
   * @author Gerhard Froehlich <a href="mailto:g-froehlich@gmx.de">
   *      g-froehlich@gmx.de</a>
   */
  
  final class JispStringKey extends KeyObject {
      final static long serialVersionUID = -6894793231339165076L;
      private String mKey;
  
      /**
       *  Constructor for the JispStringKey object
       */
      public JispStringKey() {
          mKey = new String("");
      }
  
      /**
       *  Constructor for the JispStringKey object
       *
       * @param  the Value of the Key as String
       */
      public JispStringKey(String keyValue) {
          mKey = keyValue;
      }
  
      /**
       * Compares two String Keys
       *
       * @param  the KeyObject to be compared
       * @return 0 if equal, 1 if greater, -1 if less
       */
  
      public int compareTo(KeyObject key) {
          if (key instanceof JispStringKey) {
              int comp = mKey.trim().compareTo(((JispStringKey) key).mKey.trim());
              if (comp == 0) {
                  return KEY_EQUAL;
              } else {
                  if (comp < 0) {
                      return KEY_LESS;
                  } else {
                      return KEY_MORE;
                  }
              }
          } else {
              return KEY_ERROR;
          }
      }
  
      /**
       *  Composes a null Kewy
       *
       * @return a null Key 
       */
      public KeyObject makeNullKey() {
          return new JispStringKey();
      }
  
      /**
       * The object implements the writeExternal method to save its contents 
       * by calling the methods of DataOutput for its primitive values or 
       * calling the writeObject method of ObjectOutput for objects, strings, 
       * and arrays.
       *
       * @param   out - the stream to write the object to
       * @exception IOException
       */
      public void writeExternal(ObjectOutput out)
          throws IOException {
          String outKey;
          outKey = new String(mKey);
          out.writeUTF(outKey);
      }
  
      /**
       * The object implements the readExternal method to restore its contents 
       * by calling the methods of DataInput for primitive types and readObject 
       * for objects, strings and arrays. The readExternal method must read the 
       * values in the same sequence and with the same types as were written by writeExternal.
       * 
       * @param in - the stream to read data from in order to restore the object
       * @exception  IOException
       * @exception  ClassNotFoundException
       */
  
      public void readExternal(ObjectInput in)
          throws IOException, ClassNotFoundException {
          mKey = in.readUTF();
      }
  
      /**
       *  Overrides the toString() method
       *
       * @return the Key as String
       */
      public String toString() {
          return mKey;
      }
  }
  
  
  
  
  
  
  1.1                  jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/JispFilesystemStore.java
  
  Index: JispFilesystemStore.java
  ===================================================================
  /**
   *  Copyright (C) The Apache Software Foundation. All rights reserved. *
   *  ------------------------------------------------------------------------- *
   *  This software is published under the terms of the Apache Software License *
   *  version 1.1, a copy of which has been included with this distribution in *
   *  the LICENSE file. *
   */
  
  package org.apache.commons.simplestore;
  
  import com.coyotegulch.jisp.BTreeIndex;
  import com.coyotegulch.jisp.IndexedObjectDatabase;
  import com.coyotegulch.jisp.KeyNotFound;
  
  import java.io.File;
  import java.io.IOException;
  import java.io.Serializable;
  import java.util.Enumeration;
  
  /**
   * This store is based on the Jisp library 
   * (http://www.coyotegulch.com/jisp/index.html). This store uses B-Tree indexes
   *  to access variable-length serialized data stored in files.
   *
   * @author Gerhard Froehlich 
   *  <a href="mailto:g-froehlich@gmx.de">Gerhard Froehlich</a>
   */
  
  public final class JispFilesystemStore
  implements Store {
  
      /**
       *  The directory repository
       */
      protected File mDirectoryFile;
      protected volatile String mDirectoryPath;
  
      /**
       *  The database
       */
      private String mDatabaseName = "default.dat";
      private String mIndexName = "default.idx";;
      private int mOrder = 101;
      private IndexedObjectDatabase mDatabase;
      private BTreeIndex mIndex;
  
  
      public void setDatabaseName(String name) {
          this.mDatabaseName = name;
      }
  
      public String getDatabaseName() {
          return this.mDatabaseName;
      }
  
      public void setIndexfileName(String name) {
          this.mIndexName = name;
      }
  
      public String getIndexfileName() {
          return this.mIndexName;
      }
  
      public void setOrder(int order) {
          this.mOrder = order;
      }
  
      public int getOrder() {
          return this.mOrder;
      }
  
      /**
       *  Sets the repository's location
       *
       * @param  the new directory value
       * @exception  IOException
       */
      public void setDirectory(final String directory)
          throws IOException {
          this.setDirectory(new File(directory));
      }
  
      /**
       *  Sets the repository's location
       *
       * @param  the new directory value
       * @exception  IOException
       */
      public void setDirectory(final File directory)
          throws IOException {
          this.mDirectoryFile = directory;
  
          this.mDirectoryPath =  this.mDirectoryFile.getCanonicalPath();
          this.mDirectoryPath += File.separator;
  
          if (!this.mDirectoryFile.exists()) {
              /* Create it new */
              if (!this.mDirectoryFile.mkdir()) {
                  throw new IOException(
                          "Error creating store directory '" 
                          + this.mDirectoryPath + "': ");
              }
          }
  
          /* Is given file actually a directory? */
          if (!this.mDirectoryFile.isDirectory()) {
              throw new IOException("'" + this.mDirectoryPath 
                                    + "' is not a directory");
          }
  
          /* Is directory readable and writable? */
          if (!(this.mDirectoryFile.canRead()
                && this.mDirectoryFile.canWrite())) {
              throw new IOException(
                      "Directory '" + this.mDirectoryPath 
                      + "' is not readable/writable"
                      );
          }
      }
  
  
      /**
       *  Returns the repository's full pathname
       *
       * @return the directory as String
       */
      public String getDirectoryPath() {
          return this.mDirectoryPath;
      }
  
      /**
       *  Returns a Object from the store associated with the Key Object
       *
       * @param the Key object
       * @return the Object associated with Key Object
       */
      public Object get(Object key) {
          Object readObj = null;
  
          try {
              readObj = mDatabase.read(new JispStringKey(key.toString()), mIndex);
          } catch (Exception e) {
              e.printStackTrace();
          }
          return readObj;
      }
  
      /**
       *  Initialize the Component
       */
      public void initialize() {
          try {
              File myFile = new File(this.getDirectoryPath() + mDatabaseName);
              if (myFile.exists()) {
                  mDatabase = new IndexedObjectDatabase(getDirectoryPath() 
                                  + mDatabaseName, false);
                  mIndex = new BTreeIndex(this.getDirectoryPath() + mIndexName);
                  mDatabase.attachIndex(mIndex);
              } else {
                  mDatabase = new IndexedObjectDatabase(getDirectoryPath() 
                              + mDatabaseName, false);
                  mIndex = new BTreeIndex(this.getDirectoryPath() + mIndexName,
                          mOrder, new JispStringKey(), false);
                  mDatabase.attachIndex(mIndex);
              }
          } catch (KeyNotFound ignore) {
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  
      /**
       *  Store the given Object in the indexed data file.
       *
       * @param  the Key Object
       * @param  the Value Object 
       * @exception  IOException
       */
      public void store(Object key, Object value)
          throws IOException {
          if (value instanceof Serializable) {
              try {
                  JispStringKey[] keyArray = new JispStringKey[1];
                  keyArray[0] = new JispStringKey(key.toString());
                  mDatabase.write(keyArray, (Serializable) value);
              } catch (Exception e) {
                  e.printStackTrace();
              }
          } else {
              throw new IOException("Object not Serializable");
          }
      }
  
      /**
       *  Holds the given Object in the indexed data file.
       *
       * @param  the Key Object
       * @param  the Value Object 
       * @exception  IOException
       */
      public void hold(Object key, Object value)
          throws IOException {
          this.store(key, value);
      }
  
      /**
       *  Frees some values of the data file
       */
      public void free() { 
         //TODO: implementation
      }
  
      /**
       *  Removes a value from the data file with the given key.
       *
       * @param the Key Object
       */
      public void remove(Object key) {
          try {
              JispStringKey[] keyArray = new JispStringKey[1];
              keyArray[0] = new JispStringKey(key.toString());
              mDatabase.remove(keyArray);
          } catch (KeyNotFound ignore) {
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  
      /**
       *  Test if the the index file contains the given key
       *
       * @param the Key Object
       * @return true if Key exists and false if not
       */
      public boolean containsKey(Object key) {
          long res = -1;
  
          try {
              res = mIndex.findKey(new JispStringKey(key.toString()));
          } catch (KeyNotFound ignore) {
          } catch (Exception e) {
              e.printStackTrace();
          }
  
          if (res > 0) {
              return true;
          } else {
              return false;
          }
      }
  
      /**
       *  Returns a Enumeration of all Keys in the indexed file
       *
       * @return  Enumeration Object with all existing keys
       */
      public Enumeration keys() {
          //TODO: Implementation
          return null;
      }
  }
  
  
  
  
  
  

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