You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by cz...@apache.org on 2001/11/22 11:02:04 UTC

cvs commit: xml-cocoon2/src/org/apache/cocoon/components/store FilesystemQueue.java FilesystemQueueImpl.java FilesystemStore.java StoreJanitorImpl.java

cziegeler    01/11/22 02:02:04

  Modified:    src/org/apache/cocoon/components/store Tag: cocoon_20_branch
                        FilesystemQueue.java FilesystemQueueImpl.java
                        FilesystemStore.java StoreJanitorImpl.java
  Log:
  Minor cleanup
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.3   +1 -1      xml-cocoon2/src/org/apache/cocoon/components/store/FilesystemQueue.java
  
  Index: FilesystemQueue.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/org/apache/cocoon/components/store/FilesystemQueue.java,v
  retrieving revision 1.1.2.2
  retrieving revision 1.1.2.3
  diff -u -r1.1.2.2 -r1.1.2.3
  --- FilesystemQueue.java	2001/11/21 10:45:16	1.1.2.2
  +++ FilesystemQueue.java	2001/11/22 10:02:03	1.1.2.3
  @@ -17,5 +17,5 @@
    * @author <a href="mailto:g-froehlich@gmx.de">Gerhard Froehlich</a>
    */
   public interface FilesystemQueue extends Component, PriorityQueue {
  -  String ROLE = "org.apache.cocoon.components.store.FilesystemQueue";
  +    String ROLE = "org.apache.cocoon.components.store.FilesystemQueue";
   }
  
  
  
  1.1.2.3   +142 -143  xml-cocoon2/src/org/apache/cocoon/components/store/FilesystemQueueImpl.java
  
  Index: FilesystemQueueImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/org/apache/cocoon/components/store/FilesystemQueueImpl.java,v
  retrieving revision 1.1.2.2
  retrieving revision 1.1.2.3
  diff -u -r1.1.2.2 -r1.1.2.3
  --- FilesystemQueueImpl.java	2001/11/21 10:45:16	1.1.2.2
  +++ FilesystemQueueImpl.java	2001/11/22 10:02:04	1.1.2.3
  @@ -58,7 +58,7 @@
       private String cachedirstr;
       private Store fsstore;
       private Thread fsQueueHandler;
  -    private static boolean doRun = true;
  +    private static boolean doRun = false;
       private ComponentManager manager;
   
       /**
  @@ -71,9 +71,10 @@
           this.workdir = (File)context.get(Constants.CONTEXT_WORK_DIR);
           this.cachedirstr = IOUtils.getContextFilePath(this.workdir.getPath(),
                                                         this.cachedir.getPath());
  -
  -        this.getLogger().debug("Context path="
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            this.getLogger().debug("Context path="
                 + IOUtils.getContextFilePath(this.workdir.getPath(),this.cachedir.getPath()));
  +        }
       }
   
       /**
  @@ -83,7 +84,9 @@
        */
       public void compose(ComponentManager manager) throws ComponentException {
           this.manager = manager;
  -        getLogger().debug("Looking up " + Store.ROLE + "/Filesystem");
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            getLogger().debug("Looking up " + Store.ROLE + "/Filesystem");
  +        }
           this.fsstore = (Store)manager.lookup(Store.ROLE + "/Filesystem");
       }
   
  @@ -97,145 +100,141 @@
           }
       }
   
  -  /**
  -   * Configure the Filesystem Queue:
  -   * <UL>
  -   * <LI>handlerinterval = Interval of the Queue Handler Thread</LI>
  -   * <LI>threadpriority = Priority of the Queue Handler Thread</LI>
  -   * >LI>maxobjects = Defines the max. numbers of Objects in the queue</LI>
  -   * </UL>
  -   */
  -  public void configure(Configuration conf) throws ConfigurationException {
  -    this.getLogger().debug("Configure Filesystem Queue");
  -    Parameters params = Parameters.fromConfiguration(conf);
  -    this.handlerinterval = params.getParameterAsInteger("handlerinterval",10);
  -    this.threadpriority = params.getParameterAsInteger("threadpriority",5);
  -    this.maxobjects = params.getParameterAsInteger("maxobjects",100);
  -
  -    this.getLogger().debug("handlerinterval=" + handlerinterval);
  -    this.getLogger().debug("threadpriority=" + threadpriority);
  -
  -    this.linkedList = new LinkedList();
  -  }
  -
  -  public void start() {
  -    this.fsQueueHandler = new Thread(this);
  -    this.fsQueueHandler.setDaemon(true);
  -    this.fsQueueHandler.setPriority(this.threadpriority);
  -    this.fsQueueHandler.setName("fsQueueHandler");
  -    this.fsQueueHandler.start();
  -  }
  -
  -  public void stop() {
  -    this.doRun = false;
  -  }
  -
  -  public void run() {
  -    while(doRun) {
  -      while(!this.isEmpty()) {
  -        FilesystemQueueObject filesystemQueueObject = (FilesystemQueueObject)this.pop();
  -        try {
  -          this.fsstore.store(this.getFileName(filesystemQueueObject.getKey().toString()),
  +    /**
  +     * Configure the Filesystem Queue:
  +     * <UL>
  +     * <LI>handlerinterval = Interval of the Queue Handler Thread</LI>
  +     * <LI>threadpriority = Priority of the Queue Handler Thread</LI>
  +     * >LI>maxobjects = Defines the max. numbers of Objects in the queue</LI>
  +     * </UL>
  +     */
  +    public void configure(Configuration conf) throws ConfigurationException {
  +        Parameters params = Parameters.fromConfiguration(conf);
  +        this.handlerinterval = params.getParameterAsInteger("handlerinterval",10);
  +        this.threadpriority = params.getParameterAsInteger("threadpriority",5);
  +         this.maxobjects = params.getParameterAsInteger("maxobjects",100);
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            this.getLogger().debug("Configure Filesystem Queue");
  +            this.getLogger().debug("handlerinterval=" + handlerinterval);
  +            this.getLogger().debug("threadpriority=" + threadpriority);
  +        }
  +        this.linkedList = new LinkedList();
  +    }
  +
  +    public void start() {
  +        doRun = true;
  +        this.fsQueueHandler = new Thread(this);
  +        this.fsQueueHandler.setDaemon(true);
  +        this.fsQueueHandler.setPriority(this.threadpriority);
  +        this.fsQueueHandler.setName("fsQueueHandler");
  +        this.fsQueueHandler.start();
  +    }
  +
  +    public void stop() {
  +        doRun = false;
  +    }
  +
  +    public void run() {
  +        while (doRun) {
  +            while(!this.isEmpty()) {
  +                FilesystemQueueObject filesystemQueueObject = (FilesystemQueueObject)this.pop();
  +                try {
  +                    this.fsstore.store(this.getFileName(filesystemQueueObject.getKey().toString()),
                                                 filesystemQueueObject.getObject());
  -        } catch(IOException e) {
  -          this.getLogger().error("Error in fsQueueHandler",e);
  +                } catch(IOException e) {
  +                    this.getLogger().error("Error in fsQueueHandler",e);
  +                }
  +            }
  +            try {
  +                Thread.currentThread().sleep(this.handlerinterval * 1000);
  +            } catch (InterruptedException ignore) {}
  +        }
  +    }
  +
  +    /**
  +     * Clear all elements from queue.
  +     */
  +    public void clear() {
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            this.getLogger().debug("Clearing the FilesystemQueue");
  +        }
  +        ListIterator listIterator = linkedList.listIterator(0);
  +        while(listIterator.hasNext()) {
  +            this.linkedList.remove(listIterator.nextIndex());
  +        }
  +    }
  +
  +    /**
  +     * Test if queue is empty.
  +     *
  +     * @return true if queue is empty else false.
  +     */
  +    public boolean isEmpty() {
  +        return (this.linkedList.size() == 0);
  +    }
  +
  +    /**
  +     * Insert an element into queue.
  +     *
  +     * @param element the element to be inserted
  +     */
  +    public void insert(Comparable element) {
  +        if(this.linkedList.size() < maxobjects) {
  +            if (this.getLogger().isDebugEnabled() == true) {
  +                this.getLogger().debug("Insert Element in FilesystemQueue");
  +            }
  +            this.linkedList.addFirst(element);
  +            this.reportSize();
  +        } else {
  +            this.getLogger().warn("Filesystem Queue full!");
           }
  -      }
  -      try {
  -        Thread.currentThread().sleep(this.handlerinterval * 1000);
  -      } catch (InterruptedException ignore) {}
  -    }
  -    }
  -
  -  /**
  -   * Clear all elements from queue.
  -   */
  -  public void clear() {
  -    this.getLogger().debug("Clearing the FilesystemQueue");
  -    ListIterator listIterator = linkedList.listIterator(0);
  -    while(listIterator.hasNext()) {
  -      this.linkedList.remove(listIterator.nextIndex());
  -    }
  -  }
  -
  -  /**
  -   * Test if queue is empty.
  -   *
  -   * @return true if queue is empty else false.
  -   */
  -  public boolean isEmpty() {
  -    if (this.linkedList.size() > 0) {
  -      return false;
  -    } else {
  -      return true;
  -    }
  -  }
  -
  -  /**
  -   * Insert an element into queue.
  -   *
  -   * @param element the element to be inserted
  -   */
  -  public void insert(Comparable element) {
  -    if(this.linkedList.size() < maxobjects) {
  -      this.getLogger().debug("Insert Element in FilesystemQueue");
  -      this.linkedList.addFirst(element);
  -      this.reportSize();
  -    } else {
  -      this.getLogger().warn("Filesystem Queue full!");
  -    }
  -  }
  -
  -  /**
  -   * Return element on top of heap but don't remove it.
  -   *
  -   * @return the element at top of heap
  -   * @exception NoSuchElementException if isEmpty() == true
  -   */
  -  public Comparable peek() throws NoSuchElementException {
  -    try {
  -      this.getLogger().debug("Peek Element in FilesystemQueue");
  -      return (Comparable)linkedList.getLast();
  -    } catch (NoSuchElementException e) {
  -      this.getLogger().error("Error peeking element from the queue",e);
  -      return null;
  -    }
  -  }
  -
  -  /**
  -   * Return element on top of heap and remove it.
  -   *
  -   * @return the element at top of heap
  -   * @exception NoSuchElementException if isEmpty() == true
  -   */
  -  public Comparable pop() throws NoSuchElementException {
  -    try {
  -      this.getLogger().debug("Pop Element in FilesystemQueue");
  -      return (Comparable)linkedList.removeLast();
  -    } catch (NoSuchElementException e) {
  -      this.getLogger().error("Error popping element from the queue",e);
  -      return null;
  -    }
  -  }
  -
  -  /**
  -   * This method puts together a filename for
  -   * the object, which shall be stored on the
  -   * filesystem.
  -   *
  -   * @param the key of the object
  -   * @return the filename of the key
  -   */
  -  private String getFileName(String key)
  -  {
  -    return new StringBuffer()
  -        .append(this.cachedirstr)
  -        .append(File.separator)
  -        .append(URLEncoder.encode(key.toString()))
  -        .toString();
  -  }
  -
  -  public void reportSize() {
  -    this.getLogger().debug("Size of FilesystemQueue=" + this.linkedList.size());
  -  }
  +    }
  +
  +    /**
  +     * Return element on top of heap but don't remove it.
  +     *
  +     * @return the element at top of heap
  +     * @exception NoSuchElementException if isEmpty() == true
  +     */
  +    public Comparable peek() throws NoSuchElementException {
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            this.getLogger().debug("Peek Element in FilesystemQueue");
  +        }
  +        return (Comparable)linkedList.getLast();
  +    }
  +
  +    /**
  +     * Return element on top of heap and remove it.
  +     *
  +     * @return the element at top of heap
  +     * @exception NoSuchElementException if isEmpty() == true
  +     */
  +    public Comparable pop() throws NoSuchElementException {
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            this.getLogger().debug("Pop Element in FilesystemQueue");
  +        }
  +        return (Comparable)linkedList.removeLast();
  +    }
  +
  +    /**
  +     * This method puts together a filename for
  +     * the object, which shall be stored on the
  +     * filesystem.
  +     *
  +     * @param the key of the object
  +     * @return the filename of the key
  +     */
  +    private String getFileName(String key) {
  +        return new StringBuffer()
  +            .append(this.cachedirstr)
  +            .append(File.separator)
  +            .append(URLEncoder.encode(key.toString()))
  +            .toString();
  +    }
  +
  +    public void reportSize() {
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            this.getLogger().debug("Size of FilesystemQueue=" + this.linkedList.size());
  +        }
  +    }
   }
  
  
  
  1.1.1.1.2.9 +20 -17    xml-cocoon2/src/org/apache/cocoon/components/store/FilesystemStore.java
  
  Index: FilesystemStore.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/org/apache/cocoon/components/store/FilesystemStore.java,v
  retrieving revision 1.1.1.1.2.8
  retrieving revision 1.1.1.1.2.9
  diff -u -r1.1.1.1.2.8 -r1.1.1.1.2.9
  --- FilesystemStore.java	2001/11/21 09:17:27	1.1.1.1.2.8
  +++ FilesystemStore.java	2001/11/22 10:02:04	1.1.1.1.2.9
  @@ -19,25 +19,28 @@
   import java.io.IOException;
   import java.util.Enumeration;
   
  -public class FilesystemStore extends AbstractLoggable implements Contextualizable, Store, ThreadSafe {
  -  /** The directory repository */
  -  protected File directoryFile;
  -  protected volatile String directoryPath;
  +public class FilesystemStore
  +extends AbstractLoggable
  +implements Contextualizable, Store, ThreadSafe {
   
  -  /**
  -   * Sets the repository's location
  -   */
  -  public void setDirectory(String directory) throws IOException {
  -      this.setDirectory(new File(directory));
  -  }
  +    /** The directory repository */
  +    protected File directoryFile;
  +    protected volatile String directoryPath;
   
  -  public void contextualize(Context context) throws ContextException {
  -      try {
  -          setDirectory((File) context.get(Constants.CONTEXT_WORK_DIR));
  -      } catch (Exception e) {
  -          // ignore
  -      }
  -  }
  +    /**
  +     * Sets the repository's location
  +     */
  +    public void setDirectory(String directory) throws IOException {
  +        this.setDirectory(new File(directory));
  +    }
  +
  +    public void contextualize(Context context) throws ContextException {
  +        try {
  +            setDirectory((File) context.get(Constants.CONTEXT_WORK_DIR));
  +        } catch (Exception e) {
  +            // ignore
  +        }
  +    }
   
     /**
      * Sets the repository's location
  
  
  
  1.1.2.7   +256 -227  xml-cocoon2/src/org/apache/cocoon/components/store/StoreJanitorImpl.java
  
  Index: StoreJanitorImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/org/apache/cocoon/components/store/StoreJanitorImpl.java,v
  retrieving revision 1.1.2.6
  retrieving revision 1.1.2.7
  diff -u -r1.1.2.6 -r1.1.2.7
  --- StoreJanitorImpl.java	2001/11/21 10:45:16	1.1.2.6
  +++ StoreJanitorImpl.java	2001/11/22 10:02:04	1.1.2.7
  @@ -19,240 +19,269 @@
   
   /**
    * 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. 
  + * can register to the StoreJanitor. When memory is too low,
  + * the StoreJanitor frees the registered caches until memory is normal.
    *
    * @author <a href="mailto:cs@ffzj0ia9.bank.dresdner.net">Christian Schmitt</a>
    * @author <a href="mailto:g-froehlich@gmx.de">Gerhard Froehlich</a>
    * @author <a href="mailto:proyal@managingpartners.com">Peter Royal</a>
    */
   public class StoreJanitorImpl extends AbstractLoggable implements StoreJanitor,
  -                                                                  Configurable, 
  -                                                                  ThreadSafe, 
  +                                                                  Configurable,
  +                                                                  ThreadSafe,
                                                                     Runnable,
                                                                     Startable {
   
  -  private int freememory = -1;
  -  private int heapsize = -1;
  -  private int cleanupthreadinterval = -1;
  -  private int priority = -1;
  -  private Runtime jvm;
  -  private ArrayList storelist;
  -  private int index = -1;
  -  private static boolean doRun = true;
  -
  -  /** 
  -   * Initialize the StoreJanitorImpl.
  -   * A few options can be used :
  -   * <UL>
  -   *  <LI>freememory = how many bytes shall be always free in the jvm</LI>
  -   *  <LI>heapsize = max. size of jvm memory consumption</LI>
  -   *  <LI>cleanupthreadinterval = how often (sec) shall run the cleanup thread</LI>
  -   *  <LI>threadpriority = priority of the thread (1-10). (Default: 10)</LI>
  -   * </UL>
  -   *
  -   * @param the Configuration of the application
  -   * @exception ConfigurationException
  -   */
  -  public void configure(Configuration conf) throws ConfigurationException {
  -    this.getLogger().debug("Configure StoreJanitorImpl");
  -    this.setJVM(Runtime.getRuntime());
  -
  -    Parameters params = Parameters.fromConfiguration(conf);
  -    this.setFreememory(params.getParameterAsInteger("freememory",1000000));
  -    this.setHeapsize(params.getParameterAsInteger("heapsize",60000000));
  -    this.setCleanupthreadinterval(params.getParameterAsInteger("cleanupthreadinterval",10));
  -    this.setPriority(params.getParameterAsInteger("threadpriority",Thread.currentThread().getPriority()));
  -
  -    if ((this.getFreememory() < 1)) {
  -      throw new ConfigurationException("StoreJanitorImpl freememory parameter has to be greater then 1");
  -    }
  -    if ((this.getHeapsize() < 1)) {
  -       throw new ConfigurationException("StoreJanitorImpl heapsize parameter has to be greater then 1");
  -    }
  -    if ((this.getCleanupthreadinterval() < 1)) {
  -       throw new ConfigurationException("StoreJanitorImpl cleanupthreadinterval parameter has to be greater then 1");
  -    }
  -    if ((this.getPriority() < 1)) {
  -        throw new ConfigurationException("StoreJanitorImpl threadpriority has to be greater then 1");
  -    }
  -
  -    this.setStoreList(new ArrayList());
  -  }
  -
  -  public void start() {
  -    Thread checker = new Thread(this);
  -    this.getLogger().debug("Intializing checker thread");
  -    checker.setPriority(this.getPriority());
  -    checker.setDaemon(true);
  -    checker.setName("checker");
  -    checker.start();
  -  }
  -
  -  public void stop() {
  -    doRun = false;
  -  }
  -
  -  /**
  -   * The "checker" thread checks if memory is running low in the jvm.
  -   */
  -  public void run() {
  -    while (doRun) {
  -      // amount of memory used is greater then heapsize
  -      if (this.memoryLow()) {
  -        this.getLogger().debug("Invoking garbage collection, total memory = "
  -            + this.getJVM().totalMemory() + ", free memory = " 
  -            + this.getJVM().freeMemory());
  -        this.freePhysicalMemory();
  -        this.getLogger().debug("Garbage collection complete, total memory = "
  -            + this.getJVM().totalMemory() + ", free memory = "
  -            + this.getJVM().freeMemory());
  -        synchronized (this) {
  -          while (this.memoryLow() && this.getStoreList().size() > 0) {
  -            this.freeMemory();
  -          }
  -          this.resetIndex();
  -        }
  -      }
  -      try {
  -        Thread.currentThread().sleep(this.cleanupthreadinterval * 1000);
  -      } catch (InterruptedException ignore) {}
  -    }
  -  }
  -
  -  /**
  -   * Method to check if memory is running low in the JVM.
  -   *
  -   * @return true if memory is low
  -   */
  -  private boolean memoryLow() {
  -    this.getLogger().debug("getJVM().totalMemory()=" + this.getJVM().totalMemory());
  -    this.getLogger().debug("getHeapsize()=" + this.getHeapsize());
  -    this.getLogger().debug("getJVM().freeMemory()=" + this.getJVM().freeMemory());
  -    this.getLogger().debug("getFreememory()=" + this.getFreememory());
  -    return this.getJVM().totalMemory() > this.getHeapsize() && this.getJVM().freeMemory() < this.getFreememory();
  -  }
  -
  -  /**
  -   * This method register the stores
  -   *
  -   * @param the store to be registered
  -   */
  -  public void register(Store store) {
  -    this.getLogger().debug("Registering store instance");
  -    this.getStoreList().add(store);
  -    this.getLogger().debug("Size of StoreJanitor now:" + this.getStoreList().size());
  -  }
  -
  -  /**
  -   * This method unregister the stores
  -   *
  -   * @param the store to be unregistered
  -   */
  -  public void unregister(Store store) {
  -    this.getLogger().debug("Unregister store instance");
  -    this.getStoreList().remove(store);
  -    this.getLogger().debug("Size of StoreJanitor now:" + this.getStoreList().size());
  -  }
  -
  -  /**
  -   * Round Robin alghorithm for freeing the registerd caches.
  -   */
  -  private void freeMemory() {
  -    try {
  -      this.getLogger().debug("StoreJanitor freeing memory!");
  -      this.getLogger().debug("StoreList size=" + this.getStoreList().size());
  -      this.getLogger().debug("Index before=" + this.getIndex());
  -      if (this.getIndex() < this.getStoreList().size()) {
  -        if(this.getIndex() == -1) {
  -          this.getLogger().debug("Freeing at index=" + this.getIndex());
  -          ((Store)this.getStoreList().get(0)).free();
  -          this.setIndex(0);
  -        } else {
  -          this.getLogger().debug("Freeing at index=" + this.getIndex());
  -          ((Store)this.getStoreList().get(this.getIndex())).free();
  -          this.setIndex(this.getIndex() + 1);
  -        }
  -      } else {
  -        this.getLogger().debug("Starting from the beginning");
  -        this.resetIndex();
  -        ((Store)this.getStoreList().get(0)).free();
  -        this.setIndex(0);
  -      }
  -      this.freePhysicalMemory();
  -      this.getLogger().debug("Index after=" + this.getIndex());
  -    } catch(Exception e) {
  -      this.getLogger().error("Error in freeMemory()",e);
  -    }
  -  }
  -
  -  /**
  -   * This method forces the garbage collector
  -   */
  -  private void freePhysicalMemory() {
  -    this.getJVM().runFinalization();
  -    this.getJVM().gc();
  -  }
  -
  -  private int getFreememory() {
  -    return freememory;
  -  }
  -
  -  private void setFreememory(int _freememory) {
  -    this.freememory = _freememory;
  -  }
  -
  -  private int getHeapsize() {
  -    return this.heapsize;
  -  }
  -
  -  private void setHeapsize(int _heapsize) {
  -    this.heapsize = _heapsize;
  -  } 
  -
  -  private int getCleanupthreadinterval() {
  -    return this.cleanupthreadinterval;
  -  }
  -
  -  private void setCleanupthreadinterval(int _cleanupthreadinterval) {
  -    this.cleanupthreadinterval = _cleanupthreadinterval;
  -  }
  -
  -  private int getPriority() {
  -    return this.priority;
  -  }
  -
  -  private void setPriority(int _priority) {
  -    this.priority = _priority;
  -  }
  -
  -  private Runtime getJVM() {
  -    return this.jvm;
  -  }
  -
  -  private void setJVM(Runtime _runtime) {
  -    this.jvm = _runtime;
  -  }
  -
  -  private ArrayList getStoreList() {
  -    return this.storelist;
  -  }
  -
  -  private void setStoreList(ArrayList _storelist) {
  -    this.storelist = _storelist;
  -  }
  -
  -  private void setIndex(int _index) {
  -    this.getLogger().debug("Setting index=" + _index);
  -    this.index = _index;
  -  }
  -
  -  private int getIndex() {
  -    return this.index;
  -  }
  -
  -  private void resetIndex() {
  -    this.getLogger().debug("Reseting index");
  -    this.index = -1;
  -  }
  +    private int freememory = -1;
  +    private int heapsize = -1;
  +    private int cleanupthreadinterval = -1;
  +    private int priority = -1;
  +    private Runtime jvm;
  +    private ArrayList storelist;
  +    private int index = -1;
  +    private static boolean doRun = false;
  +
  +    /**
  +     * Initialize the StoreJanitorImpl.
  +     * A few options can be used :
  +     * <UL>
  +     *  <LI>freememory = how many bytes shall be always free in the jvm</LI>
  +     *  <LI>heapsize = max. size of jvm memory consumption</LI>
  +     *  <LI>cleanupthreadinterval = how often (sec) shall run the cleanup thread</LI>
  +     *  <LI>threadpriority = priority of the thread (1-10). (Default: 10)</LI>
  +     * </UL>
  +     *
  +     * @param the Configuration of the application
  +     * @exception ConfigurationException
  +     */
  +    public void configure(Configuration conf) throws ConfigurationException {
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            this.getLogger().debug("Configure StoreJanitorImpl");
  +        }
  +        this.setJVM(Runtime.getRuntime());
  +
  +        Parameters params = Parameters.fromConfiguration(conf);
  +        this.setFreememory(params.getParameterAsInteger("freememory",1000000));
  +        this.setHeapsize(params.getParameterAsInteger("heapsize",60000000));
  +        this.setCleanupthreadinterval(params.getParameterAsInteger("cleanupthreadinterval",10));
  +        this.setPriority(params.getParameterAsInteger("threadpriority",Thread.currentThread().getPriority()));
  +
  +        if ((this.getFreememory() < 1)) {
  +            throw new ConfigurationException("StoreJanitorImpl freememory parameter has to be greater then 1");
  +        }
  +        if ((this.getHeapsize() < 1)) {
  +            throw new ConfigurationException("StoreJanitorImpl heapsize parameter has to be greater then 1");
  +        }
  +        if ((this.getCleanupthreadinterval() < 1)) {
  +            throw new ConfigurationException("StoreJanitorImpl cleanupthreadinterval parameter has to be greater then 1");
  +        }
  +        if ((this.getPriority() < 1)) {
  +            throw new ConfigurationException("StoreJanitorImpl threadpriority has to be greater then 1");
  +        }
  +
  +        this.setStoreList(new ArrayList());
  +    }
  +
  +    public void start() {
  +        doRun = true;
  +        Thread checker = new Thread(this);
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            this.getLogger().debug("Intializing checker thread");
  +        }
  +        checker.setPriority(this.getPriority());
  +        checker.setDaemon(true);
  +        checker.setName("checker");
  +        checker.start();
  +    }
  +
  +    public void stop() {
  +        doRun = false;
  +    }
  +
  +    /**
  +     * The "checker" thread checks if memory is running low in the jvm.
  +     */
  +    public void run() {
  +        while (doRun) {
  +            // amount of memory used is greater then heapsize
  +            if (this.memoryLow()) {
  +                if (this.getLogger().isDebugEnabled() == true) {
  +                    this.getLogger().debug("Invoking garbage collection, total memory = "
  +                            + this.getJVM().totalMemory() + ", free memory = "
  +                            + this.getJVM().freeMemory());
  +                }
  +                this.freePhysicalMemory();
  +                if (this.getLogger().isDebugEnabled() == true) {
  +                    this.getLogger().debug("Garbage collection complete, total memory = "
  +                        + this.getJVM().totalMemory() + ", free memory = "
  +                        + this.getJVM().freeMemory());
  +                }
  +                synchronized (this) {
  +                    while (this.memoryLow() && this.getStoreList().size() > 0) {
  +                        this.freeMemory();
  +                    }
  +                    this.resetIndex();
  +                }
  +            }
  +            try {
  +                Thread.currentThread().sleep(this.cleanupthreadinterval * 1000);
  +            } catch (InterruptedException ignore) {}
  +        }
  +    }
  +
  +    /**
  +     * Method to check if memory is running low in the JVM.
  +     *
  +     * @return true if memory is low
  +     */
  +    private boolean memoryLow() {
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            this.getLogger().debug("getJVM().totalMemory()=" + this.getJVM().totalMemory());
  +            this.getLogger().debug("getHeapsize()=" + this.getHeapsize());
  +            this.getLogger().debug("getJVM().freeMemory()=" + this.getJVM().freeMemory());
  +            this.getLogger().debug("getFreememory()=" + this.getFreememory());
  +        }
  +        return this.getJVM().totalMemory() > this.getHeapsize() && this.getJVM().freeMemory() < this.getFreememory();
  +    }
  +
  +    /**
  +     * This method register the stores
  +     *
  +     * @param the store to be registered
  +     */
  +    public void register(Store store) {
  +        this.getStoreList().add(store);
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            this.getLogger().debug("Registering store instance");
  +            this.getLogger().debug("Size of StoreJanitor now:" + this.getStoreList().size());
  +        }
  +    }
  +
  +    /**
  +     * This method unregister the stores
  +     *
  +     * @param the store to be unregistered
  +     */
  +    public void unregister(Store store) {
  +        this.getStoreList().remove(store);
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            this.getLogger().debug("Unregister store instance");
  +            this.getLogger().debug("Size of StoreJanitor now:" + this.getStoreList().size());
  +        }
  +    }
  +
  +    /**
  +     * Round Robin alghorithm for freeing the registerd caches.
  +     */
  +    private void freeMemory() {
  +        try {
  +            if (this.getLogger().isDebugEnabled() == true) {
  +                this.getLogger().debug("StoreJanitor freeing memory!");
  +                this.getLogger().debug("StoreList size=" + this.getStoreList().size());
  +                this.getLogger().debug("Index before=" + this.getIndex());
  +            }
  +            if (this.getIndex() < this.getStoreList().size()) {
  +                if(this.getIndex() == -1) {
  +                    if (this.getLogger().isDebugEnabled() == true) {
  +                        this.getLogger().debug("Freeing at index=" + this.getIndex());
  +                    }
  +                    ((Store)this.getStoreList().get(0)).free();
  +                    this.setIndex(0);
  +                } else {
  +                    if (this.getLogger().isDebugEnabled() == true) {
  +                        this.getLogger().debug("Freeing at index=" + this.getIndex());
  +                    }
  +                    ((Store)this.getStoreList().get(this.getIndex())).free();
  +                    this.setIndex(this.getIndex() + 1);
  +                }
  +            } else {
  +                if (this.getLogger().isDebugEnabled() == true) {
  +                    this.getLogger().debug("Starting from the beginning");
  +                }
  +                this.resetIndex();
  +                ((Store)this.getStoreList().get(0)).free();
  +                this.setIndex(0);
  +            }
  +            this.freePhysicalMemory();
  +            if (this.getLogger().isDebugEnabled() == true) {
  +                this.getLogger().debug("Index after=" + this.getIndex());
  +            }
  +        } catch(Exception e) {
  +            this.getLogger().error("Error in freeMemory()",e);
  +        }
  +    }
  +
  +    /**
  +     * This method forces the garbage collector
  +     */
  +    private void freePhysicalMemory() {
  +        this.getJVM().runFinalization();
  +        this.getJVM().gc();
  +    }
  +
  +    private int getFreememory() {
  +        return freememory;
  +    }
  +
  +    private void setFreememory(int _freememory) {
  +        this.freememory = _freememory;
  +    }
  +
  +    private int getHeapsize() {
  +        return this.heapsize;
  +    }
  +
  +    private void setHeapsize(int _heapsize) {
  +        this.heapsize = _heapsize;
  +    }
  +
  +    private int getCleanupthreadinterval() {
  +        return this.cleanupthreadinterval;
  +    }
  +
  +    private void setCleanupthreadinterval(int _cleanupthreadinterval) {
  +        this.cleanupthreadinterval = _cleanupthreadinterval;
  +    }
  +
  +    private int getPriority() {
  +        return this.priority;
  +    }
  +
  +    private void setPriority(int _priority) {
  +        this.priority = _priority;
  +    }
  +
  +    private Runtime getJVM() {
  +        return this.jvm;
  +    }
  +
  +    private void setJVM(Runtime _runtime) {
  +        this.jvm = _runtime;
  +    }
  +
  +    private ArrayList getStoreList() {
  +        return this.storelist;
  +    }
  +
  +    private void setStoreList(ArrayList _storelist) {
  +        this.storelist = _storelist;
  +    }
  +
  +    private void setIndex(int _index) {
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            this.getLogger().debug("Setting index=" + _index);
  +        }
  +        this.index = _index;
  +    }
  +
  +    private int getIndex() {
  +        return this.index;
  +    }
  +
  +    private void resetIndex() {
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            this.getLogger().debug("Reseting index");
  +        }
  +        this.index = -1;
  +    }
   }
  
  
  

----------------------------------------------------------------------
In case of troubles, e-mail:     webmaster@xml.apache.org
To unsubscribe, e-mail:          cocoon-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: cocoon-cvs-help@xml.apache.org