cziegeler 01/11/21 02:45:40 Modified: src/org/apache/cocoon/components/store FilesystemQueue.java FilesystemQueueImpl.java MRUMemoryStore.java StoreJanitorImpl.java Log: Applied patch from Gerhard Froehlich [[EMAIL PROTECTED]] and corrected component handling Revision Changes Path 1.2 +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 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- FilesystemQueue.java 2001/10/23 11:55:19 1.1 +++ FilesystemQueue.java 2001/11/21 10:45:40 1.2 @@ -18,4 +18,4 @@ */ public interface FilesystemQueue extends Component, PriorityQueue { String ROLE = "org.apache.cocoon.components.store.FilesystemQueue"; -} \ No newline at end of file +} 1.2 +64 -68 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 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- FilesystemQueueImpl.java 2001/10/23 11:55:19 1.1 +++ FilesystemQueueImpl.java 2001/11/21 10:45:40 1.2 @@ -7,44 +7,28 @@ *****************************************************************************/ package org.apache.cocoon.components.store; +import org.apache.avalon.framework.activity.Disposable; +import org.apache.avalon.framework.activity.Startable; import org.apache.avalon.framework.component.ComponentException; - import org.apache.avalon.framework.component.ComponentManager; - import org.apache.avalon.framework.component.Composable; - import org.apache.avalon.framework.configuration.Configurable; - import org.apache.avalon.framework.configuration.Configuration; - import org.apache.avalon.framework.configuration.ConfigurationException; - import org.apache.avalon.framework.context.Context; - import org.apache.avalon.framework.context.ContextException; - import org.apache.avalon.framework.context.Contextualizable; - import org.apache.avalon.framework.logger.AbstractLoggable; - import org.apache.avalon.framework.parameters.Parameters; - import org.apache.avalon.framework.thread.ThreadSafe; - import org.apache.cocoon.Constants; - import org.apache.cocoon.util.IOUtils; import java.io.File; - import java.io.IOException; - import java.net.URLEncoder; - import java.util.LinkedList; - import java.util.ListIterator; - import java.util.NoSuchElementException; /** @@ -54,58 +38,64 @@ * * @author <a href="mailto:[EMAIL PROTECTED]">Gerhard Froehlich</a> */ -public class FilesystemQueueImpl extends AbstractLoggable implements FilesystemQueue, - Configurable, - Contextualizable, - Runnable, - ThreadSafe, - Composable { - - private int handlerinterval; - private int threadpriority; - private int maxobjects; - private LinkedList linkedList; - private File cachedir; - private File workdir; - private String cachedirstr; - private Store fsstore; - private Thread fsQueueHandler; - - /** - * Get the context - * - * @param the Context of the application - */ - public void contextualize(Context context) throws ContextException { - this.cachedirstr = new String(); - - try { - this.cachedir = (File)context.get(Constants.CONTEXT_CACHE_DIR); - this.workdir = (File)context.get(Constants.CONTEXT_WORK_DIR); - this.cachedirstr = IOUtils.getContextFilePath(this.workdir.getPath(), - this.cachedir.getPath()); +public final class FilesystemQueueImpl +extends AbstractLoggable +implements FilesystemQueue, + Configurable, + Contextualizable, + Runnable, + ThreadSafe, + Composable, + Disposable, + Startable { + + private int handlerinterval; + private int threadpriority; + private int maxobjects; + private LinkedList linkedList; + private File cachedir; + private File workdir; + private String cachedirstr; + private Store fsstore; + private Thread fsQueueHandler; + private static boolean doRun = true; + private ComponentManager manager; + + /** + * Get the context + * + * @param the Context of the application + */ + public void contextualize(Context context) throws ContextException { + this.cachedir = (File)context.get(Constants.CONTEXT_CACHE_DIR); + this.workdir = (File)context.get(Constants.CONTEXT_WORK_DIR); + this.cachedirstr = IOUtils.getContextFilePath(this.workdir.getPath(), + this.cachedir.getPath()); - this.getLogger().debug("Context path=" + this.getLogger().debug("Context path=" + IOUtils.getContextFilePath(this.workdir.getPath(),this.cachedir.getPath())); + } - } catch (Exception e) { - this.getLogger().error("Error in contextualize()",e); + /** + * Get components of the ComponentManager + * + * @param the ComponentManager + */ + public void compose(ComponentManager manager) throws ComponentException { + this.manager = manager; + getLogger().debug("Looking up " + Store.ROLE + "/Filesystem"); + this.fsstore = (Store)manager.lookup(Store.ROLE + "/Filesystem"); } - } - /** - * Get components of the ComponentManager - * - * @param the ComponentManager - */ - public void compose(ComponentManager manager) throws ComponentException { - try { - getLogger().debug("Looking up " + Store.ROLE + "/Filesystem"); - this.fsstore = (Store)manager.lookup(Store.ROLE + "/Filesystem"); - } catch(ComponentException e) { - getLogger().error("Error in compose()!", e); + /** + * Dispose the component + */ + public void dispose() { + if (this.manager != null) { + this.manager.release(this.fsstore); + this.fsstore = null; + } } - } /** * Configure the Filesystem Queue: @@ -126,7 +116,9 @@ 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); @@ -134,12 +126,16 @@ this.fsQueueHandler.start(); } + public void stop() { + this.doRun = false; + } + public void run() { - while(true) { + while(doRun) { while(!this.isEmpty()) { FilesystemQueueObject filesystemQueueObject = (FilesystemQueueObject)this.pop(); try { - this.fsstore.store(this.getFileName(filesystemQueueObject.getKey().toString()), + this.fsstore.store(this.getFileName(filesystemQueueObject.getKey().toString()), filesystemQueueObject.getObject()); } catch(IOException e) { this.getLogger().error("Error in fsQueueHandler",e); @@ -148,9 +144,9 @@ try { Thread.currentThread().sleep(this.handlerinterval * 1000); } catch (InterruptedException ignore) {} + } } - } - + /** * Clear all elements from queue. */ 1.23 +270 -285 xml-cocoon2/src/org/apache/cocoon/components/store/MRUMemoryStore.java Index: MRUMemoryStore.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/org/apache/cocoon/components/store/MRUMemoryStore.java,v retrieving revision 1.22 retrieving revision 1.23 diff -u -r1.22 -r1.23 --- MRUMemoryStore.java 2001/10/23 11:55:19 1.22 +++ MRUMemoryStore.java 2001/11/21 10:45:40 1.23 @@ -8,47 +8,29 @@ package org.apache.cocoon.components.store; import org.apache.avalon.excalibur.collections.SynchronizedPriorityQueue; - +import org.apache.avalon.framework.activity.Disposable; +import org.apache.avalon.excalibur.collections.SynchronizedPriorityQueue; import org.apache.avalon.framework.component.ComponentException; - import org.apache.avalon.framework.component.ComponentManager; - import org.apache.avalon.framework.component.Composable; - import org.apache.avalon.framework.configuration.Configurable; - import org.apache.avalon.framework.configuration.Configuration; - import org.apache.avalon.framework.configuration.ConfigurationException; - import org.apache.avalon.framework.context.Context; - import org.apache.avalon.framework.context.ContextException; - import org.apache.avalon.framework.context.Contextualizable; - import org.apache.avalon.framework.logger.AbstractLoggable; - import org.apache.avalon.framework.parameters.Parameters; - import org.apache.avalon.framework.thread.ThreadSafe; - import org.apache.cocoon.Constants; - import org.apache.cocoon.util.ClassUtils; - import org.apache.cocoon.util.IOUtils; import java.io.File; - import java.io.IOException; - import java.net.URLEncoder; - import java.util.Enumeration; - -import java.util.HashMap; - +import java.util.Hashtable; import java.util.LinkedList; /** @@ -62,283 +44,286 @@ * @author <a href="mailto:[EMAIL PROTECTED]">Gerhard Froehlich</a> * @author <a href="mailto:[EMAIL PROTECTED]">Davanum Srinivas</a> */ - -public class MRUMemoryStore extends AbstractLoggable implements Store, - Configurable, - ThreadSafe, - Composable, - Contextualizable { - - - private int maxobjects; - private boolean filesystem; - private HashMap cache; - private LinkedList mrulist; - private File cachefile; - private Store fsstore; - private StoreJanitor storejanitor; - private File cachedir; - private File workdir; - private String cachedirstr; - private FilesystemQueue filesystemQueue; - protected ComponentManager manager; - - /** - * Get components of the ComponentManager - * - * @param the ComponentManager - */ - public void compose(ComponentManager manager) throws ComponentException { - try { - this.manager = manager; - getLogger().debug("Looking up " + Store.ROLE + "/Filesystem"); - this.fsstore = (Store)manager.lookup(Store.ROLE + "/Filesystem"); - getLogger().debug("Looking up " + StoreJanitor.ROLE); - this.storejanitor = (StoreJanitor)manager.lookup(StoreJanitor.ROLE); - getLogger().debug("Looking up " + FilesystemQueue.ROLE); - this.filesystemQueue = (FilesystemQueue)manager.lookup(FilesystemQueue.ROLE); - } catch(ComponentException e) { - getLogger().error("Error in compose()!", e); - } - } - - /** - * Get the context - * - * @param the Context of the application - */ - public void contextualize(Context context) throws ContextException { - this.cachedirstr = new String(); - - try { +public final class MRUMemoryStore +extends AbstractLoggable +implements Store, + Configurable, + ThreadSafe, + Composable, + Disposable, + Contextualizable { + + private int maxobjects; + private boolean filesystem; + private Hashtable cache; + private LinkedList mrulist; + private File cachefile; + private Store fsstore; + private StoreJanitor storejanitor; + private File cachedir; + private File workdir; + private String cachedirstr; + private FilesystemQueue filesystemQueue; + private ComponentManager manager; + + /** + * Get components of the ComponentManager + * + * @param the ComponentManager + */ + public void compose(ComponentManager manager) throws ComponentException { + this.manager = manager; + getLogger().debug("Looking up " + Store.ROLE + "/Filesystem"); + this.fsstore = (Store)manager.lookup(Store.ROLE + "/Filesystem"); + getLogger().debug("Looking up " + StoreJanitor.ROLE); + this.storejanitor = (StoreJanitor)manager.lookup(StoreJanitor.ROLE); + getLogger().debug("Looking up " + FilesystemQueue.ROLE); + this.filesystemQueue = (FilesystemQueue)manager.lookup(FilesystemQueue.ROLE); + } + + /** + * Get the context + * + * @param the Context of the application + */ + public void contextualize(Context context) throws ContextException { this.cachedir = (File)context.get(Constants.CONTEXT_CACHE_DIR); this.workdir = (File)context.get(Constants.CONTEXT_WORK_DIR); this.cachedirstr = IOUtils.getContextFilePath(this.workdir.getPath(), - this.cachedir.getPath()); + this.cachedir.getPath()); + if (this.getLogger().isDebugEnabled() == true) { + this.getLogger().debug("cachedir=" + this.cachedir); + this.getLogger().debug("workdir=" + this.workdir); + this.getLogger().debug("cachedirstr=" + this.cachedirstr); + this.getLogger().debug("Context path=" + + IOUtils.getContextFilePath(this.workdir.getPath(),this.cachedir.getPath())); + } + } - + /** + * Initialize the MRUMemoryStore. + * A few options can be used : + * <UL> + * <LI>maxobjects = how many objects will be stored in memory (Default: 10 objects)</LI> + * <LI>filesystem = use filesystem storage to keep object persistent (Default: false)</LI> + * </UL> + * + * @param the Configuration of the application + * @exception ConfigurationException + */ + public void configure(Configuration conf) throws ConfigurationException { + Parameters params = Parameters.fromConfiguration(conf); + this.maxobjects = params.getParameterAsInteger("maxobjects",100); + this.filesystem = params.getParameterAsBoolean("filesystem",false); + if ((this.maxobjects < 1)) { + throw new ConfigurationException("MRUMemoryStore maxobjects must be at least 1 milli second!"); + } - this.getLogger().debug("cachedir=" + this.cachedir); - this.getLogger().debug("workdir=" + this.workdir); - this.getLogger().debug("cachedirstr=" + this.cachedirstr); - this.getLogger().debug("Context path=" - + IOUtils.getContextFilePath(this.workdir.getPath(),this.cachedir.getPath())); + this.cache = new Hashtable((int)(this.maxobjects * 1.2)); + this.mrulist = new LinkedList(); + this.storejanitor.register(this); + } + + /** + * Dispose the component + */ + public void dispose() { + if (this.manager != null) { + this.manager.release(this.storejanitor); + this.storejanitor = null; + this.manager.release(this.filesystemQueue); + this.filesystemQueue = null; + this.manager.release(this.fsstore); + this.fsstore = null; + } + } - } catch (Exception e) { - getLogger().error("Error in contextualize()",e); + /** + * 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 for the object to store + * @param the object to store + */ + 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 of the object to be stored + * @param the object to be stored + */ + public void hold(Object key, Object value) { + getLogger().debug("Holding object in memory. key: " + key); + getLogger().debug("Holding object in memory. value: " + value); + + /** ...first test if the max. objects in cache is reached... */ + while (this.mrulist.size() >= this.maxobjects) { + /** ...ok, heapsize is reached, remove the last element... */ + this.free(); + } + + /** put the object on the filesystem */ + if(this.filesystem) { + if(this.checkSerializable(value) && + !this.fsstore.containsKey(getFileName(key.toString()))) { + this.getLogger().debug("Storing object on fs"); + try { + this.filesystemQueue.insert(new FilesystemQueueObject(key,value)); + } catch(Exception e) { + this.getLogger().error("Error storing Object on fs",e); + } + } + } + /** ..put the new object in the cache, on the top of course ... */ + this.cache.put(key, value); + this.mrulist.remove(key); + this.mrulist.addFirst(key); + this.getLogger().debug("Cache size=" + cache.size()); } - } - /** - * Initialize the MRUMemoryStore. - * A few options can be used : - * <UL> - * <LI>maxobjects = how many objects will be stored in memory (Default: 10 objects)</LI> - * <LI>filesystem = use filesystem storage to keep object persistent (Default: false)</LI> - * </UL> - * - * @param the Configuration of the application - * @exception ConfigurationException - */ - public void configure(Configuration conf) throws ConfigurationException { - Parameters params = Parameters.fromConfiguration(conf); - this.maxobjects = params.getParameterAsInteger("maxobjects",100); - this.filesystem = params.getParameterAsBoolean("filesystem",false); - if ((this.maxobjects < 1)) { - throw new ConfigurationException("MRUMemoryStore maxobjects must be at least 1 milli second!"); - } - - this.cache = new HashMap((int)(this.maxobjects * 1.2)); - this.mrulist = new LinkedList(); - - this.storejanitor.register(this); - } - - /** - * 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 for the object to store - * @param the object to store - */ - 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 of the object to be stored - * @param the object to be stored - */ - public void hold(Object key, Object value) { - getLogger().debug("Holding object in memory. key: " + key); - getLogger().debug("Holding object in memory. value: " + value); - - /** ...first test if the max. objects in cache is reached... */ - while (this.mrulist.size() >= this.maxobjects) { - /** ...ok, heapsize is reached, remove the last element... */ - this.free(); - } - - /** put the object on the filesystem */ - if(this.filesystem) { - if(this.checkSerializable(value) && - !this.fsstore.containsKey(getFileName(key.toString()))) { - this.getLogger().debug("Storing object on fs"); - try { - this.filesystemQueue.insert(new FilesystemQueueObject(key,value)); - } catch(Exception e) { - this.getLogger().error("Error storing Object on fs",e); - } - } - } - /** ..put the new object in the cache, on the top of course ... */ - this.cache.put(key, value); - this.mrulist.remove(key); - this.mrulist.addFirst(key); - this.getLogger().debug("Cache size=" + cache.size()); - } - - /** - * Get the object associated to the given unique key. - * - * @param the key of the requested object - * @return the requested object - */ - public Object get(Object key) { - this.getLogger().debug("Getting object from memory. Key: " + key); - - Object tmpobject = this.cache.get(key); - if ( tmpobject != null ) { - /** put the accessed key on top of the linked list */ - this.mrulist.remove(key); - this.mrulist.addFirst(key); - return tmpobject; - } - - this.getLogger().debug("Object not found in memory"); - /** try to fetch from filesystem */ - if(this.filesystem) { - tmpobject = this.fsstore.get(getFileName(key.toString())); - if (tmpobject == null) { - this.getLogger().debug( "Object was NOT found on fs. Looked for: " + /** + * Get the object associated to the given unique key. + * + * @param the key of the requested object + * @return the requested object + */ + public Object get(Object key) { + this.getLogger().debug("Getting object from memory. Key: " + key); + + Object tmpobject = this.cache.get(key); + if ( tmpobject != null ) { + /** put the accessed key on top of the linked list */ + this.mrulist.remove(key); + this.mrulist.addFirst(key); + return tmpobject; + } + + this.getLogger().debug("Object not found in memory"); + /** try to fetch from filesystem */ + if(this.filesystem) { + tmpobject = this.fsstore.get(getFileName(key.toString())); + if (tmpobject == null) { + this.getLogger().debug( "Object was NOT found on fs. Looked for: " + getFileName(key.toString())); + return null; + } else { + this.getLogger().debug("Object was found on fs"); + try { + tmpobject = IOUtils.deserializeObject((File)tmpobject); + if(!this.cache.containsKey(key)) { + this.hold(key,tmpobject); + } + return tmpobject; + } catch (ClassNotFoundException ce) { + this.getLogger().error("Error in get()!", ce); + return null; + } catch (IOException ioe) { + this.getLogger().error("Error in get()!", ioe); + return null; + } + } + } + return null; + } + + /** + * Remove the object associated to the given key. + * + * @param the key of to be removed object + */ + public void remove(Object key) { + this.getLogger().debug("Removing object from store"); + this.cache.remove(key); + this.mrulist.remove(key); + if(this.filesystem && key != null) { + this.fsstore.remove(getFileName(key.toString())); + } + } + + /** + * Indicates if the given key is associated to a contained object. + * + * @param the key of the object + * @return true if the key exists + */ + public boolean containsKey(Object key) { + if(filesystem) { + return (this.cache.containsKey(key) || this.fsstore.containsKey(key)); + } else { + return this.cache.containsKey(key); + } + } + + /** + * Returns the list of used keys as an Enumeration. + * + * @return the enumeration of the cache + */ + public Enumeration keys() { + /* Not yet implemented */ return null; - } else { - this.getLogger().debug("Object was found on fs"); + } + + /** + * Frees some of the fast memory used by this store. + * It removes the last element in the store. + */ + public void free() { try { - tmpobject = IOUtils.deserializeObject((File)tmpobject); - if(!this.cache.containsKey(key)) { - this.hold(key,tmpobject); - } - return tmpobject; - } catch (ClassNotFoundException ce) { - this.getLogger().error("Error in get()!", ce); - return null; - } catch (IOException ioe) { - this.getLogger().error("Error in get()!", ioe); - return null; - } - } - } - return null; - } - - /** - * Remove the object associated to the given key. - * - * @param the key of to be removed object - */ - public void remove(Object key) { - this.getLogger().debug("Removing object from store"); - this.cache.remove(key); - this.mrulist.remove(key); - if(this.filesystem && key != null) { - this.fsstore.remove(getFileName(key.toString())); - } - } - - /** - * Indicates if the given key is associated to a contained object. - * - * @param the key of the object - * @return true if the key exists - */ - public boolean containsKey(Object key) { - synchronized(this.cache) { - return this.cache.containsKey(key); - } - } - - /** - * Returns the list of used keys as an Enumeration. - * - * @return the enumeration of the cache - */ - public Enumeration keys() { - /* Not yet implemented */ - return null; - } - - /** - * Frees some of the fast memory used by this store. - * It removes the last element in the store. - */ - public void free() { - try { - if(this.cache.size() > 0) { - this.getLogger().debug("Freeing cache"); - this.cache.remove(this.mrulist.getLast()); - this.mrulist.removeLast(); - this.getLogger().debug("Cache size=" + cache.size()); - } - } catch (Exception e) { - this.getLogger().error("Error in free()", e); - } - } - - /** - * This method checks if an object is seriazable. - * FIXME: In the moment only CachedEventObject or - * CachedStreamObject are stored. - * - * @param the object to be checked - * @return true if the object is storeable - */ - private boolean checkSerializable(Object object) { - try { - this.getLogger().debug("Object=" + object); - if((object.getClass().getName().equals("org.apache.cocoon.caching.CachedEventObject")) - || (object.getClass().getName().equals("org.apache.cocoon.caching.CachedStreamObject")) - || (ClassUtils.implementsInterface(object.getClass().getName(),"org.apache.cocoon.caching.CacheValidity"))) { - return true; - } else { - return false; - } - } catch (Exception e) { - this.getLogger().error("Error in checkSerializable()!", e); - return false; - } - } - - /** - * 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() + if(this.cache.size() > 0) { + this.getLogger().debug("Freeing cache"); + this.cache.remove(this.mrulist.getLast()); + this.mrulist.removeLast(); + this.getLogger().debug("Cache size=" + cache.size()); + } + } catch (Exception e) { + this.getLogger().error("Error in free()", e); + } + } + + /** + * This method checks if an object is seriazable. + * FIXME: In the moment only CachedEventObject or + * CachedStreamObject are stored. + * + * @param the object to be checked + * @return true if the object is storeable + */ + private boolean checkSerializable(Object object) { + try { + this.getLogger().debug("Object=" + object); + if((object.getClass().getName().equals("org.apache.cocoon.caching.CachedEventObject")) + || (object.getClass().getName().equals("org.apache.cocoon.caching.CachedStreamObject")) + || (ClassUtils.implementsInterface(object.getClass().getName(),"org.apache.cocoon.caching.CacheValidity"))) { + return true; + } else { + return false; + } + } catch (Exception e) { + this.getLogger().error("Error in checkSerializable()!", e); + return false; + } + } + + /** + * 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(); - } + } } 1.6 +12 -4 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.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- StoreJanitorImpl.java 2001/10/11 07:28:19 1.5 +++ StoreJanitorImpl.java 2001/11/21 10:45:40 1.6 @@ -7,6 +7,7 @@ *****************************************************************************/ package org.apache.cocoon.components.store; +import org.apache.avalon.framework.activity.Startable; import org.apache.avalon.framework.configuration.Configurable; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; @@ -27,8 +28,9 @@ */ public class StoreJanitorImpl extends AbstractLoggable implements StoreJanitor, Configurable, - ThreadSafe, - Runnable { + ThreadSafe, + Runnable, + Startable { private int freememory = -1; private int heapsize = -1; @@ -37,8 +39,8 @@ private Runtime jvm; private ArrayList storelist; private int index = -1; + private static boolean doRun = true; - /** * Initialize the StoreJanitorImpl. * A few options can be used : @@ -76,7 +78,9 @@ } this.setStoreList(new ArrayList()); + } + public void start() { Thread checker = new Thread(this); this.getLogger().debug("Intializing checker thread"); checker.setPriority(this.getPriority()); @@ -85,11 +89,15 @@ checker.start(); } + public void stop() { + doRun = false; + } + /** * The "checker" thread checks if memory is running low in the jvm. */ public void run() { - while (true) { + while (doRun) { // amount of memory used is greater then heapsize if (this.memoryLow()) { this.getLogger().debug("Invoking garbage collection, total memory = "
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]