KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > vfs > cache > LRUFilesCache


1 /*
2  * Copyright 2002-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.vfs.cache;
17
18 import org.apache.commons.collections.map.AbstractLinkedMap;
19 import org.apache.commons.collections.map.LRUMap;
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22 import org.apache.commons.vfs.FileName;
23 import org.apache.commons.vfs.FileObject;
24 import org.apache.commons.vfs.FileSystem;
25 import org.apache.commons.vfs.FileSystemException;
26 import org.apache.commons.vfs.VfsLog;
27 import org.apache.commons.vfs.provider.AbstractFileObject;
28 import org.apache.commons.vfs.util.Messages;
29
30 import java.util.HashMap JavaDoc;
31 import java.util.Map JavaDoc;
32
33 /**
34  * This implementation caches every file using {@link LRUMap}.<br>
35  * The default constructor uses a LRU size of 100 per filesystem.
36  *
37  * @author <a HREF="mailto:imario@apache.org">Mario Ivankovits</a>
38  */

39 public class LRUFilesCache extends AbstractFilesCache
40 {
41     /**
42      * The logger to use.
43      */

44     private Log log = LogFactory.getLog(LRUFilesCache.class);
45
46     private final Map filesystemCache = new HashMap JavaDoc(10);
47     private final int lruSize;
48
49     private class MyLRUMap extends LRUMap
50     {
51         final FileSystem filesystem;
52
53         public MyLRUMap(final FileSystem filesystem, int size)
54         {
55             super(size, true);
56             this.filesystem = filesystem;
57         }
58
59         protected boolean removeLRU(final AbstractLinkedMap.LinkEntry linkEntry)
60         {
61             synchronized (LRUFilesCache.this)
62             {
63                 AbstractFileObject file = (AbstractFileObject) linkEntry.getValue();
64                 // System.err.println(">>> " + size() + " check removeLRU:" + linkEntry.getKey().toString());
65

66                 if (file.isAttached() || file.isContentOpen())
67                 {
68                     // do not allow open or attached files to be removed
69
// System.err.println(">>> " + size() + " VETO removeLRU:" + linkEntry.getKey().toString() + " (" + file.isAttached() + "/" + file.isContentOpen() + ")");
70
return false;
71                 }
72
73                 // System.err.println(">>> " + size() + " removeLRU:" + linkEntry.getKey().toString());
74
if (super.removeLRU(linkEntry))
75                 {
76                     try
77                     {
78                         // force detach
79
file.close();
80                     }
81                     catch (FileSystemException e)
82                     {
83                         VfsLog.warn(getLogger(), log, Messages.getString("vfs.impl/LRUFilesCache-remove-ex.warn"), e);
84                     }
85
86                     Map files = (Map) filesystemCache.get(filesystem);
87                     if (files.size() < 1)
88                     {
89                         filesystemCache.remove(filesystem);
90                     }
91
92                     return true;
93                 }
94
95                 return false;
96             }
97         }
98     }
99
100     /**
101      * Default constructor. Uses a LRU size of 100 per filesystem.
102      */

103     public LRUFilesCache()
104     {
105         this(100);
106     }
107
108     /**
109      * Set the desired LRU size.
110      *
111      * @param lruSize the LRU size
112      */

113     public LRUFilesCache(int lruSize)
114     {
115         this.lruSize = lruSize;
116     }
117
118     public void putFile(final FileObject file)
119     {
120         synchronized (this)
121         {
122             Map files = getOrCreateFilesystemCache(file.getFileSystem());
123
124             // System.err.println(">>> " + files.size() + " put:" + file.toString());
125

126             files.put(file.getName(), file);
127         }
128     }
129
130     public FileObject getFile(final FileSystem filesystem, final FileName name)
131     {
132         synchronized (this)
133         {
134             Map files = getOrCreateFilesystemCache(filesystem);
135
136             // FileObject fo = (FileObject) files.get(name);
137
// System.err.println(">>> " + files.size() + " get:" + name.toString() + " " + fo);
138

139             return (FileObject) files.get(name);
140         }
141     }
142
143     public void clear(final FileSystem filesystem)
144     {
145         synchronized (this)
146         {
147             // System.err.println(">>> clear fs " + filesystem);
148

149             Map files = getOrCreateFilesystemCache(filesystem);
150             files.clear();
151
152             filesystemCache.remove(filesystem);
153         }
154     }
155
156     protected Map getOrCreateFilesystemCache(final FileSystem filesystem)
157     {
158         Map files = (Map) filesystemCache.get(filesystem);
159         if (files == null)
160         {
161             // System.err.println(">>> create fs " + filesystem);
162

163             files = new MyLRUMap(filesystem, lruSize);
164             filesystemCache.put(filesystem, files);
165         }
166
167         return files;
168     }
169
170     public void close()
171     {
172         super.close();
173
174         synchronized (this)
175         {
176             // System.err.println(">>> clear all");
177

178             filesystemCache.clear();
179         }
180     }
181
182     public void removeFile(final FileSystem filesystem, final FileName name)
183     {
184         synchronized (this)
185         {
186             Map files = getOrCreateFilesystemCache(filesystem);
187
188             // System.err.println(">>> " + files.size() + " remove:" + name.toString());
189

190             files.remove(name);
191
192             if (files.size() < 1)
193             {
194                 filesystemCache.remove(filesystem);
195             }
196         }
197     }
198
199     public void touchFile(final FileObject file)
200     {
201         // this moves the file back on top
202
getFile(file.getFileSystem(), file.getName());
203     }
204 }
205
Popular Tags