Mercurial > hg > digilib-old
diff servlet/src/digilib/io/DocuDirCache.java @ 339:6d2032b6121d gen2_1
new directory and cache work
author | robcast |
---|---|
date | Wed, 17 Nov 2004 18:17:34 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/io/DocuDirCache.java Wed Nov 17 18:17:34 2004 +0100 @@ -0,0 +1,240 @@ +/* + * DocuDirCache.java + * + * Digital Image Library servlet components + * + * Copyright (C) 2003 Robert Casties (robcast@mail.berlios.de) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * Please read license.txt for the full details. A copy of the GPL may be found + * at http://www.gnu.org/copyleft/lgpl.html + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + * + * Created on 03.03.2003 + */ + +package digilib.io; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import org.apache.log4j.Logger; + +/** + * Cache of digilib directories. + * + * @author casties + */ +public class DocuDirCache { + + /** general logger for this class */ + protected static Logger logger = Logger.getLogger(DocuDirCache.class); + + /** Map of directories */ + Map map = null; + + /** number of files in the whole cache (approximate) */ + long numFiles = 0; + + /** number of cache hits */ + long hits = 0; + + /** number of cache misses */ + long misses = 0; + + /** the root directory element */ + public DigiDirectory rootDir = null; + + /** + * Default constructor. + */ + public DocuDirCache() { + map = new HashMap(); + // add root directory + rootDir = new DigiDirectory(FileOps.getBaseDirs()[0], "", null); + map.put("", rootDir); + } + + /** + * The number of directories in the cache. + * + * @return + */ + public int size() { + return (map != null) ? map.size() : 0; + } + + /** + * Add a DocuDirectory to the cache. + * + * @param newdir + */ + public void put(DigiDirectory newdir) { + String s = newdir.getDLPath(); + Object oldkey = map.put(s, newdir); + if (oldkey != null) { + logger.warn("Duplicate key in DocuDirCache.put -- overwritten!"); + } + numFiles += newdir.getSize(); + } + + /** + * Add a directory to the cache and check its parents. + * + * @param newDir + */ + public synchronized void putDir(DigiDirectory newDir) { + put(newDir); + } + + /** + * Returns a DigiDirectory from the cache. + * + * @param path + * @return + */ + public DigiDirectory get(String path) { + return (DigiDirectory) map.get(path); + } + + /** + * Returns the DigiDirectory indicated by the pathname <code>fn</code>. + * + * If <code>fn</code> is a file then its parent directory is returned. + * + * @param fn + * digilib pathname + * @return + */ + public DigiDirectory getDirectory(String pn) { + /* + * first, assume pn is a directory and look in the cache + */ + DigiDirectory dd = (DigiDirectory) map.get(pn); + if (dd != null) { + // cache hit + hits++; + return dd; + } else { + /* + * maybe it's a file? try the parent directory + */ + String dn = FileOps.dlParent(pn); + // try it in the cache + dd = (DigiDirectory) map.get(dn); + if (dd != null) { + // cache hit + hits++; + return dd; + } else { + // cache miss + misses++; + /* + * try to read from disk + */ + File f = FileOps.getRealFile(pn); + /* + * is it a directory? + */ + if (f.isDirectory()) { + dd = new DigiDirectory(f, pn, null); + // add to the cache + putDir(dd); + return dd; + } else { + /* + * then maybe a file? try the parent as a directory + */ + File d = FileOps.getRealFile(dn); + if (d.isDirectory()) { + dd = new DigiDirectory(d, dn, null); + // add to the cache + putDir(dd); + return dd; + } + } + } + } + /* + * otherwise it's crap + */ + return null; + } + + /** + * Returns the DigiDirent with the pathname <code>fn</code> and the index + * <code>in</code> and the class <code>fc</code>. + * + * If <code>fn</code> is a file then the corresponding DocuDirent is + * returned and the index is ignored. + * + * @param pn + * digilib pathname + * @param in + * file index + * @param fc + * file class + * @return + */ + public DigiDirent getFile(String pn, int in, int fc) { + // file number is 1-based, vector index is 0-based + int n = in - 1; + // get the (parent) directory + DigiDirectory dd = getDirectory(pn); + if (dd != null) { + // get the directory's name + String dn = dd.getDLPath(); + if (dn.equals(pn)) { + // return the file at the index + return dd.get(n, fc); + } else { + // then the last part must be the filename + String fn = FileOps.dlName(pn); + return dd.get(fn); + } + } + return null; + } + + /** + * @return long + */ + public long getNumFiles() { + return numFiles; + } + + /** + * @return long + */ + public long getHits() { + return hits; + } + + /** + * @return long + */ + public long getMisses() { + return misses; + } + + /** + * @return Returns the rootDir. + */ + public DigiDirectory getRootDir() { + return rootDir; + } + /** + * @param rootDir The rootDir to set. + */ + public void setRootDir(DigiDirectory rootDir) { + this.rootDir = rootDir; + } +}