Author: imario
Date: Sun Nov  6 10:48:29 2005
New Revision: 331133

URL: http://svn.apache.org/viewcvs?rev=331133&view=rev
Log:
try to avoid locking as pointed out by Faron Dutton

Modified:
    
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/cache/SoftRefFilesCache.java

Modified: 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/cache/SoftRefFilesCache.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/cache/SoftRefFilesCache.java?rev=331133&r1=331132&r2=331133&view=diff
==============================================================================
--- 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/cache/SoftRefFilesCache.java
 (original)
+++ 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/cache/SoftRefFilesCache.java
 Sun Nov  6 10:48:29 2005
@@ -1,20 +1,28 @@
 /*
  * Copyright 2002-2005 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
- *
+ * 
+ * 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.
+ * 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.commons.vfs.cache;
 
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.commons.vfs.FileName;
@@ -24,244 +32,268 @@
 import org.apache.commons.vfs.impl.DefaultFileSystemManager;
 import org.apache.commons.vfs.util.Messages;
 
-import java.lang.ref.Reference;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.SoftReference;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.TreeMap;
-
 /**
- * This implementation caches every file as long as it is strongly reachable 
by the java vm.
- * As soon as the vm needs memory - every softly reachable file will be 
discarded.
- *
+ * This implementation caches every file as long as it is strongly reachable by
+ * the java vm. As soon as the vm needs memory - every softly reachable file
+ * will be discarded.
+ * 
  * @author <a href="mailto:[EMAIL PROTECTED]">Mario Ivankovits</a>
- * @version $Revision$ $Date$
+ * @version $Revision$ $Date: 2005-09-30 09:02:41 +0200 (Fr, 30 Sep
+ *          2005) $
  * @see SoftReference
  */
 public class SoftRefFilesCache extends AbstractFilesCache
 {
-    /**
-     * The logger to use.
-     */
-    private Log log = LogFactory.getLog(SoftRefFilesCache.class);
-
-    private final Map filesystemCache = new HashMap();
-    private final Map refReverseMap = new HashMap(100);
-    private final ReferenceQueue refqueue = new ReferenceQueue();
-
-    private SoftRefReleaseThread softRefReleaseThread = null;
-
-    /**
-     * This thread will listen on the ReferenceQueue and remove the entry in 
the
-     * filescache as soon as the vm removes the reference
-     */
-    private class SoftRefReleaseThread extends Thread
-    {
-        private boolean requestEnd = false;
-
-        private SoftRefReleaseThread()
-        {
-            setName(SoftRefReleaseThread.class.getName());
-            setDaemon(true);
-        }
-
-        public void run()
-        {
-            loop: while (!requestEnd && 
!Thread.currentThread().isInterrupted())
-            {
-                try
-                {
-                    Reference ref = refqueue.remove(1000);
-                    if (ref == null)
-                    {
-                        continue;
-                    }
-
-                    synchronized (SoftRefFilesCache.this)
-                    {
-                        FileSystemAndNameKey key = (FileSystemAndNameKey) 
refReverseMap.get(ref);
-
-                        if (key != null)
-                        {
-                            removeFile(key);
-                        }
-                    }
-                }
-                catch (InterruptedException e)
-                {
-                    if (!requestEnd)
-                    {
-                        VfsLog.warn(getLogger(), log, 
Messages.getString("vfs.impl/SoftRefReleaseThread-interrupt.info"));
-                    }
-                    break loop;
-                }
-            }
-        }
-    }
-
-    public SoftRefFilesCache()
-    {
-    }
-
-    private void startThread()
-    {
-        if (softRefReleaseThread != null)
-        {
-            throw new 
IllegalStateException(Messages.getString("vfs.impl/SoftRefReleaseThread-already-running.warn"));
-        }
-
-        softRefReleaseThread = new SoftRefReleaseThread();
-        softRefReleaseThread.start();
-    }
-
-    private void endThread()
-    {
-        if (softRefReleaseThread != null)
-        {
-            softRefReleaseThread.requestEnd = true;
-            softRefReleaseThread.interrupt();
-            softRefReleaseThread = null;
-        }
-    }
-
-    public void putFile(final FileObject file)
-    {
-        if (log.isDebugEnabled())
-        {
-            log.debug("putFile: " + file.getName());
-        }
-        synchronized (this)
-        {
-            Map files = getOrCreateFilesystemCache(file.getFileSystem());
-
-            Reference ref = new SoftReference(file, refqueue);
-            FileSystemAndNameKey key = new 
FileSystemAndNameKey(file.getFileSystem(), file.getName());
-            files.put(file.getName(), ref);
-            refReverseMap.put(ref, key);
-        }
-    }
-
-    public FileObject getFile(final FileSystem filesystem, final FileName name)
-    {
-        synchronized (this)
-        {
-            Map files = getOrCreateFilesystemCache(filesystem);
-
-            SoftReference ref = (SoftReference) files.get(name);
-            if (ref == null)
-            {
-                return null;
-            }
-
-            FileObject fo = (FileObject) ref.get();
-            if (fo == null)
-            {
-                removeFile(filesystem, name);
-            }
-            return fo;
-        }
-    }
-
-    public void clear(FileSystem filesystem)
-    {
-        synchronized (this)
-        {
-            Map files = getOrCreateFilesystemCache(filesystem);
-
-            Iterator iterKeys = refReverseMap.values().iterator();
-            while (iterKeys.hasNext())
-            {
-                FileSystemAndNameKey key = (FileSystemAndNameKey) 
iterKeys.next();
-                if (key.getFileSystem() == filesystem)
-                {
-                    iterKeys.remove();
-                    files.remove(key.getFileName());
-                }
-            }
-
-            if (files.size() < 1)
-            {
-                filesystemClose(filesystem);
-            }
-        }
-    }
-
-    private void filesystemClose(FileSystem filesystem)
-    {
-        if (log.isDebugEnabled())
-        {
-            log.debug("close fs: " + filesystem.getRootName());
-        }
-        filesystemCache.remove(filesystem);
-        if (filesystemCache.size() < 1)
-        {
-            endThread();
-        }
-        ((DefaultFileSystemManager) 
getContext().getFileSystemManager()).closeFileSystem(filesystem);
-    }
-
-    public void close()
-    {
-        super.close();
-
-        synchronized (this)
-        {
-            endThread();
-
-            // files.clear();
-            filesystemCache.clear();
-            refReverseMap.clear();
-        }
-    }
-
-    public void removeFile(FileSystem filesystem, FileName name)
-    {
-        removeFile(new FileSystemAndNameKey(filesystem, name));
-    }
-
-    public void touchFile(FileObject file)
-    {
-    }
-
-    private void removeFile(final FileSystemAndNameKey key)
-    {
-        if (log.isDebugEnabled())
-        {
-            log.debug("removeFile: " + key.getFileName());
-        }
-        synchronized (this)
-        {
-            Map files = getOrCreateFilesystemCache(key.getFileSystem());
-
-            Object ref = files.remove(key.getFileName());
-            if (ref != null)
-            {
-                refReverseMap.remove(ref);
-            }
-
-            if (files.size() < 1)
-            {
-                filesystemClose(key.getFileSystem());
-            }
-        }
-    }
-
-    protected Map getOrCreateFilesystemCache(final FileSystem filesystem)
-    {
-        if (filesystemCache.size() < 1)
-        {
-            startThread();
-        }
-
-        Map files = (Map) filesystemCache.get(filesystem);
-        if (files == null)
-        {
-            files = new TreeMap();
-            filesystemCache.put(filesystem, files);
-        }
-
-        return files;
-    }
+       /**
+        * The logger to use.
+        */
+       private Log log = LogFactory.getLog(SoftRefFilesCache.class);
+
+       private final Map filesystemCache = new HashMap();
+       private final Map refReverseMap = new HashMap(100);
+       private final ReferenceQueue refqueue = new ReferenceQueue();
+
+       private SoftRefReleaseThread softRefReleaseThread = null;
+
+       /**
+        * This thread will listen on the ReferenceQueue and remove the entry 
in the
+        * filescache as soon as the vm removes the reference
+        */
+       private class SoftRefReleaseThread extends Thread
+       {
+               private boolean requestEnd = false;
+
+               private SoftRefReleaseThread()
+               {
+                       setName(SoftRefReleaseThread.class.getName());
+                       setDaemon(true);
+               }
+
+               public void run()
+               {
+                       loop: while (!requestEnd && 
!Thread.currentThread().isInterrupted())
+                       {
+                               try
+                               {
+                                       Reference ref = refqueue.remove(1000);
+                                       if (ref == null)
+                                       {
+                                               continue;
+                                       }
+
+                                       FileSystem fsToRemove = null;
+
+                                       FileSystemAndNameKey key = 
(FileSystemAndNameKey) refReverseMap
+                                                       .get(ref);
+
+                                       if (key != null)
+                                       {
+                                               if (removeFile(key))
+                                               {
+                                                       fsToRemove = 
key.getFileSystem();
+                                               }
+                                       }
+
+                                       if (fsToRemove != null)
+                                       {
+                                               filesystemClose(fsToRemove);
+                                       }
+                               }
+                               catch (InterruptedException e)
+                               {
+                                       if (!requestEnd)
+                                       {
+                                               VfsLog
+                                                               .warn(
+                                                                               
getLogger(),
+                                                                               
log,
+                                                                               
Messages
+                                                                               
                .getString("vfs.impl/SoftRefReleaseThread-interrupt.info"));
+                                       }
+                                       break loop;
+                               }
+                       }
+               }
+       }
+
+       public SoftRefFilesCache()
+       {
+       }
+
+       private void startThread()
+       {
+               if (softRefReleaseThread != null)
+               {
+                       throw new IllegalStateException(
+                                       Messages
+                                                       
.getString("vfs.impl/SoftRefReleaseThread-already-running.warn"));
+               }
+
+               softRefReleaseThread = new SoftRefReleaseThread();
+               softRefReleaseThread.start();
+       }
+
+       private void endThread()
+       {
+               if (softRefReleaseThread != null)
+               {
+                       softRefReleaseThread.requestEnd = true;
+                       softRefReleaseThread.interrupt();
+                       softRefReleaseThread = null;
+               }
+       }
+
+       public void putFile(final FileObject file)
+       {
+               if (log.isDebugEnabled())
+               {
+                       log.debug("putFile: " + file.getName());
+               }
+
+               Map files = getOrCreateFilesystemCache(file.getFileSystem());
+
+               Reference ref = new SoftReference(file, refqueue);
+               FileSystemAndNameKey key = new FileSystemAndNameKey(file
+                               .getFileSystem(), file.getName());
+
+               synchronized (files)
+               {
+                       files.put(file.getName(), ref);
+                       refReverseMap.put(ref, key);
+               }
+       }
+
+       public FileObject getFile(final FileSystem filesystem, final FileName 
name)
+       {
+               Map files = getOrCreateFilesystemCache(filesystem);
+
+               synchronized (files)
+               {
+                       SoftReference ref = (SoftReference) files.get(name);
+                       if (ref == null)
+                       {
+                               return null;
+                       }
+
+                       FileObject fo = (FileObject) ref.get();
+                       if (fo == null)
+                       {
+                               removeFile(filesystem, name);
+                       }
+                       return fo;
+               }
+       }
+
+       public void clear(FileSystem filesystem)
+       {
+               Map files = getOrCreateFilesystemCache(filesystem);
+
+               synchronized (files)
+               {
+                       Iterator iterKeys = refReverseMap.values().iterator();
+                       while (iterKeys.hasNext())
+                       {
+                               FileSystemAndNameKey key = 
(FileSystemAndNameKey) iterKeys
+                                               .next();
+                               if (key.getFileSystem() == filesystem)
+                               {
+                                       iterKeys.remove();
+                                       files.remove(key.getFileName());
+                               }
+                       }
+               }
+
+               if (files.size() < 1)
+               {
+                       filesystemClose(filesystem);
+               }
+       }
+
+       private void filesystemClose(FileSystem filesystem)
+       {
+               if (log.isDebugEnabled())
+               {
+                       log.debug("close fs: " + filesystem.getRootName());
+               }
+               synchronized (filesystemCache)
+               {
+                       filesystemCache.remove(filesystem);
+                       if (filesystemCache.size() < 1)
+                       {
+                               endThread();
+                       }
+               }
+               ((DefaultFileSystemManager) getContext().getFileSystemManager())
+                               .closeFileSystem(filesystem);
+       }
+
+       public void close()
+       {
+               super.close();
+
+               synchronized (this)
+               {
+                       endThread();
+
+                       // files.clear();
+                       synchronized (filesystemCache)
+                       {
+                               filesystemCache.clear();
+                       }
+                       refReverseMap.clear();
+               }
+       }
+
+       public void removeFile(FileSystem filesystem, FileName name)
+       {
+               if (removeFile(new FileSystemAndNameKey(filesystem, name)))
+               {
+                       filesystemClose(filesystem);
+               }
+       }
+
+       public void touchFile(FileObject file)
+       {
+       }
+
+       private boolean removeFile(final FileSystemAndNameKey key)
+       {
+               if (log.isDebugEnabled())
+               {
+                       log.debug("removeFile: " + key.getFileName());
+               }
+
+               Map files = getOrCreateFilesystemCache(key.getFileSystem());
+
+               synchronized (files)
+               {
+                       Object ref = files.remove(key.getFileName());
+                       if (ref != null)
+                       {
+                               refReverseMap.remove(ref);
+                       }
+
+                       return files.size() < 1;
+               }
+       }
+
+       protected Map getOrCreateFilesystemCache(final FileSystem filesystem)
+       {
+               synchronized (filesystemCache)
+               {
+                       if (filesystemCache.size() < 1)
+                       {
+                               startThread();
+                       }
+
+                       Map files = (Map) filesystemCache.get(filesystem);
+                       if (files == null)
+                       {
+                               files = new TreeMap();
+                               filesystemCache.put(filesystem, files);
+                       }
+
+                       return files;
+               }
+       }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to