001: /*
002: Copyright (C) 2004 David Bucciarelli (davibu@interfree.it)
003:
004: This program is free software; you can redistribute it and/or
005: modify it under the terms of the GNU General Public License
006: as published by the Free Software Foundation; either version 2
007: of the License, or (at your option) any later version.
008:
009: This program is distributed in the hope that it will be useful,
010: but WITHOUT ANY WARRANTY; without even the implied warranty of
011: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: GNU General Public License for more details.
013:
014: You should have received a copy of the GNU General Public License
015: along with this program; if not, write to the Free Software
016: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: */
018:
019: package org.homedns.dade.jcgrid.vfs;
020:
021: import java.io.*;
022: import java.util.*;
023: import java.security.*;
024:
025: import org.apache.log4j.*;
026:
027: import org.homedns.dade.jcgrid.message.*;
028: import org.homedns.dade.jcgrid.util.*;
029:
030: public class vfsSessionPool {
031: private final static String className = vfsSessionPool.class
032: .getName();
033: private static Logger log = Logger.getLogger(className);
034: private static Logger logDetail = Logger.getLogger("DETAIL."
035: + className);
036:
037: private String path;
038: private Hashtable sessionList;
039: private long size;
040: private long maxSize;
041:
042: public vfsSessionPool(String dir, long s) {
043: if (log.isDebugEnabled())
044: log.debug("Start vfsSessionPool(" + dir + "," + s + ")");
045:
046: path = dir;
047:
048: // Check if the directory exists
049:
050: File pathDir = new File(path);
051: if (!pathDir.exists()) {
052: // I fit doesn't exist create the directory
053: pathDir.mkdirs();
054: }
055:
056: sessionList = null;
057: maxSize = s;
058:
059: if (log.isDebugEnabled())
060: log.debug("End vfsSessionPool()");
061: }
062:
063: //--------------------------------------------------------------------------
064:
065: // Very simple but it works
066: private boolean garbageCollect() throws IOException {
067: if (log.isDebugEnabled())
068: log.debug("Start garbageCollect()");
069:
070: boolean res = false;
071: synchronized (sessionList) {
072: for (Iterator i = sessionList.keySet().iterator(); i
073: .hasNext();) {
074: String name = (String) i.next();
075: vfsSession s = (vfsSession) sessionList.get(name);
076:
077: if (!s.getInUse()) {
078: // Remove this session
079:
080: log.warn("VFS removing unused session: " + name);
081:
082: size -= s.getSize();
083: s.delete();
084: sessionList.remove(name);
085: String dir = path + File.separator + name;
086: File f = new File(dir);
087: f.delete();
088:
089: res = true;
090: break;
091: }
092: }
093: }
094:
095: if (log.isDebugEnabled())
096: log.debug("End garbageCollect(" + res + ")");
097:
098: return res;
099: }
100:
101: public void syncVFSSession(String name,
102: GridMessageChannel clientChannel, vfsSession clientSession)
103: throws Exception {
104: if (log.isDebugEnabled())
105: log.debug("Start syncVFSSession(" + name + ","
106: + clientChannel + "," + clientSession + ")");
107:
108: if (log.isDebugEnabled())
109: log.debug(" Cache size: " + size / (1024 * 1024) + "/"
110: + maxSize / (1024 * 1024) + "MB");
111:
112: // Reject session that will never fit in the cache
113:
114: if (maxSize < clientSession.getSize())
115: throw new Exception("Cache too small: " + maxSize + "<"
116: + clientSession.getSize());
117:
118: // Check if there is enough space in the cache for the new
119: // session (worst case: all file are new)
120:
121: if (maxSize < size + clientSession.getSize()) {
122: // Try to make some free space
123:
124: while (this .garbageCollect()) {
125: if (log.isDebugEnabled())
126: log.debug(" Cache size: " + size);
127:
128: if (maxSize > size + clientSession.getSize())
129: break;
130: }
131:
132: if (maxSize < size + clientSession.getSize())
133: throw new Exception("Not enough cache free space: "
134: + maxSize + "<" + size + "+"
135: + clientSession.getSize());
136: }
137:
138: if (log.isDebugEnabled())
139: log.debug(" Cache size: " + size / (1024 * 1024) + "/"
140: + maxSize / (1024 * 1024) + "MB");
141:
142: vfsSession cacheSession = this .lockVFSSession(name);
143: if (cacheSession == null)
144: cacheSession = this .newVFSSession(name);
145:
146: // Looks for file to delete
147:
148: Vector toDelete = cacheSession.notIncludedNodes(clientSession);
149: for (Iterator i = toDelete.iterator(); i.hasNext();) {
150: String nodeName = (String) i.next();
151: String fileName = path + File.separator + name + nodeName;
152: log.warn("VFS deleting: " + fileName);
153:
154: synchronized (sessionList) {
155: size -= cacheSession.getNode(nodeName).getSize();
156: }
157: cacheSession.removeNode(nodeName);
158: }
159:
160: // Looks for empty directories
161:
162: cacheSession.deleteEmptyDirectories();
163:
164: // Looks for new files
165:
166: Vector toUpdate = clientSession.notIncludedNodes(cacheSession);
167: for (Iterator i = toUpdate.iterator(); i.hasNext();) {
168: String nodeName = (String) i.next();
169: String fileName = path + File.separator + name + nodeName;
170: log.warn("VFS updating: " + fileName);
171:
172: // Request file
173:
174: clientChannel.send(new GridMessageVFSSessionFileRequest(
175: nodeName));
176:
177: // Receive file
178:
179: GridMessageVFSSessionFileResult gmf = (GridMessageVFSSessionFileResult) clientChannel
180: .recv();
181:
182: // Create the directories
183:
184: File f = new File(fileName);
185: String fparent = f.getParent();
186: if (fparent != null) {
187: f = new File(fparent);
188: f.mkdirs();
189: }
190:
191: // Write file
192:
193: FileOutputStream fos = new FileOutputStream(new File(
194: fileName));
195: fos.write(gmf.getData());
196: fos.close();
197:
198: // Update session
199:
200: cacheSession.addNode(nodeName);
201: synchronized (sessionList) {
202: size += cacheSession.getNode(nodeName).getSize();
203: }
204: }
205:
206: log.warn("VFS session cache size: " + size / (1024 * 1024)
207: + "/" + maxSize / (1024 * 1024) + "MB");
208:
209: if (log.isDebugEnabled())
210: log.debug("End syncVFSSession()");
211: }
212:
213: public void start() throws Exception {
214: if (log.isDebugEnabled())
215: log.debug("Start start()");
216:
217: sessionList = new Hashtable();
218:
219: log.warn("VFS session pool on path: " + path);
220: File f = new File(path);
221: String[] l = f.list();
222:
223: for (int i = 0; i < l.length; i++) {
224: String p = f.getAbsolutePath() + File.separator + l[i];
225: log.warn("VFS session pool scanning: " + p);
226:
227: File s = new File(p);
228: if (s.isDirectory()) {
229: vfsSession vfss = new vfsSession(p);
230: vfss.start();
231:
232: String name = l[i];
233: sessionList.put(name, vfss);
234: size += vfss.getSize();
235: } else
236: log.warn(" VFS " + l[i] + " is not a directory");
237: }
238:
239: if (log.isDebugEnabled())
240: log.debug("End start()");
241: }
242:
243: public vfsSession newVFSSession(String name) throws Exception {
244: if (log.isDebugEnabled())
245: log.debug("Start newVFSSesssion(" + name + ")");
246:
247: String dir = path + File.separator + name;
248: File f = new File(dir);
249: f.mkdir();
250:
251: vfsSession s = new vfsSession(dir);
252: s.start();
253: s.setInUse(true);
254:
255: synchronized (sessionList) {
256: sessionList.put(name, s);
257: size += s.getSize();
258: }
259:
260: if (log.isDebugEnabled())
261: log.debug("End newVFSSesssion(" + s + ")");
262:
263: return s;
264: }
265:
266: //----------------------------- Lock & Unlock ------------------------------
267:
268: public vfsSession lockVFSSession(String name) {
269: if (log.isDebugEnabled())
270: log.debug("Start lockVFSSession(" + name + ")");
271:
272: vfsSession s;
273: synchronized (sessionList) {
274: s = (vfsSession) sessionList.get(name);
275: if (s != null)
276: s.setInUse(true);
277: }
278:
279: if (log.isDebugEnabled())
280: log.debug("End lockVFSSession(" + s + ")");
281:
282: return s;
283: }
284:
285: public void unlockVFSSession(String name) {
286: if (log.isDebugEnabled())
287: log.debug("Start unlockVFSSession(" + name + ")");
288:
289: synchronized (sessionList) {
290: vfsSession s = (vfsSession) sessionList.get(name);
291: if (s != null)
292: s.setInUse(false);
293: }
294:
295: if (log.isDebugEnabled())
296: log.debug("End unlockVFSSession()");
297: }
298:
299: //------------------------------- Get & Set --------------------------------
300:
301: public vfsSession getVFSSession(String name) {
302: if (log.isDebugEnabled())
303: log.debug("Start getVFSSession(" + name + ")");
304:
305: vfsSession s = (vfsSession) sessionList.get(name);
306:
307: if (log.isDebugEnabled())
308: log.debug("End getVFSSession(" + s + ")");
309:
310: return s;
311: }
312:
313: public String getPath() {
314: if (logDetail.isDebugEnabled())
315: logDetail.debug("Start getPath()");
316: if (logDetail.isDebugEnabled())
317: logDetail.debug("End getPath(" + path + ")");
318:
319: return path;
320: }
321:
322: public long getSize() {
323: if (logDetail.isDebugEnabled())
324: logDetail.debug("Start getSize()");
325: if (logDetail.isDebugEnabled())
326: logDetail.debug("End getSize(" + size + ")");
327:
328: return size;
329: }
330:
331: public long getMaxSize() {
332: if (logDetail.isDebugEnabled())
333: logDetail.debug("Start getMaxSize()");
334: if (logDetail.isDebugEnabled())
335: logDetail.debug("End getMaxSize(" + maxSize + ")");
336:
337: return maxSize;
338: }
339:
340: public void setMaxSize(long s) {
341: if (logDetail.isDebugEnabled())
342: logDetail.debug("Start setMaxSize()");
343:
344: maxSize = s;
345:
346: if (logDetail.isDebugEnabled())
347: logDetail.debug("End setMaxSize()");
348: }
349: }
|