# HG changeset patch # User robcast # Date 1297201784 -3600 # Node ID 16a16ca5f651a66fcfafeb2ef9b52a55b1de4ed7 # Parent 485b85f6e0972c24c7c9ad82acd1137c338ab5e2 use concurrent put methods in DocuDirDache. move synchronized to readdir in DocuDirectory. diff -r 485b85f6e097 -r 16a16ca5f651 servlet/src/digilib/io/DocuDirCache.java --- a/servlet/src/digilib/io/DocuDirCache.java Mon Feb 07 11:02:23 2011 +0100 +++ b/servlet/src/digilib/io/DocuDirCache.java Tue Feb 08 22:49:44 2011 +0100 @@ -23,11 +23,10 @@ package digilib.io; import java.io.File; -import java.util.HashMap; import java.util.LinkedList; import java.util.List; -import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import org.apache.log4j.Logger; @@ -43,7 +42,7 @@ Logger logger = Logger.getLogger(this.getClass()); /** HashMap of directories */ - Map map = new ConcurrentHashMap(); + ConcurrentMap map = new ConcurrentHashMap(); /** names of base directories */ String[] baseDirNames = null; @@ -98,38 +97,49 @@ /** * Add a DocuDirectory to the cache. + * Always returns the correct Object from the cache, + * either newdir one or another one. * * @param newdir + * @return dir */ - public void put(DocuDirectory newdir) { + public DocuDirectory put(DocuDirectory newdir) { String s = newdir.getDirName(); logger.debug("DocuDirCache.put for "+s+" in "+this); - if (map.containsKey(s)) { + DocuDirectory olddir = map.putIfAbsent(s, newdir); + if (olddir != null) { logger.warn("Duplicate key in DocuDirCache.put -- ignoring!"); - } else { - map.put(s, newdir); - numFiles += newdir.size(); + return olddir; } + numFiles += newdir.size(); + return newdir; } /** * Add a directory to the cache and check its parents. - * + * Always returns the correct Object from the cache, + * either newDir one or another one. + * * @param newDir + * @return dir */ - public void putDir(DocuDirectory newDir) { - put(newDir); - String parent = FileOps.parent(newDir.getDirName()); - if (parent != "") { - // check the parent in the cache - DocuDirectory pd = map.get(parent); - if (pd == null) { - // the parent is unknown - pd = new DocuDirectory(parent, this); - putDir(pd); + public DocuDirectory putDir(DocuDirectory newDir) { + DocuDirectory dd = put(newDir); + if (dd.getParent() == null) { + // no parent link yet + String parent = FileOps.parent(newDir.getDirName()); + if (parent != "") { + // check the parent in the cache + DocuDirectory pd = map.get(parent); + if (pd == null) { + // the parent is unknown + pd = new DocuDirectory(parent, this); + pd = putDir(pd); + } + newDir.setParent(pd); } - newDir.setParent(pd); } + return dd; } /** @@ -181,8 +191,6 @@ int n = in - 1; // first, assume fn is a directory and look in the cache dd = map.get(fn); - // logger.debug("fn: " + fn); - // logger.debug("dd: " + dd); if (dd == null) { // cache miss misses++; @@ -195,7 +203,7 @@ dd = new DocuDirectory(fn, this); if (dd.isValid()) { // add to the cache - putDir(dd); + dd = putDir(dd); } } else { /* @@ -213,7 +221,7 @@ if (dd.isValid()) { // add to the cache // logger.debug(dd + " is valid"); - putDir(dd); + dd = putDir(dd); } else { // invalid path return null; @@ -224,17 +232,14 @@ } // get the file's index n = dd.indexOf(f.getName(), fc); - // logger.debug(f.getName() + ", index is " + n + ", fc = " + fc); } } else { // cache hit hits++; } dd.refresh(); - // logger.debug(dd + " refreshed"); if (dd.isValid()) { try { - // logger.debug(dd + " is valid"); return dd.get(n, fc); } catch (IndexOutOfBoundsException e) { // logger.debug(fn + " not found in directory"); @@ -265,7 +270,7 @@ dd = new DocuDirectory(fn, this); if (dd.isValid()) { // add to the cache - putDir(dd); + dd = putDir(dd); } } else { // maybe it's a file @@ -277,7 +282,7 @@ dd = new DocuDirectory(f.getParent(), this); if (dd.isValid()) { // add to the cache - putDir(dd); + dd = putDir(dd); } else { // invalid path return null; diff -r 485b85f6e097 -r 16a16ca5f651 servlet/src/digilib/io/DocuDirectory.java --- a/servlet/src/digilib/io/DocuDirectory.java Mon Feb 07 11:02:23 2011 +0100 +++ b/servlet/src/digilib/io/DocuDirectory.java Tue Feb 08 22:49:44 2011 +0100 @@ -85,15 +85,6 @@ public DocuDirectory(String path, DocuDirCache cache) { this.dirName = path; this.cache = cache; - initDir(); - checkDir(); - } - - /** - * Sets and checks the dir object. - * - */ - protected void initDir() { String baseDirName = cache.getBaseDirNames()[0]; // clear directory list FileClass[] fcs = FileClass.values(); @@ -102,10 +93,10 @@ for (@SuppressWarnings("unused") FileClass fc: fcs) { list.add(null); } - isValid = false; dirMTime = 0; // the first directory has to exist - dir = new File(baseDirName, dirName); + dir = new File(baseDirName, path); + isValid = dir.isDirectory(); } /** @@ -155,35 +146,23 @@ } /** - * Checks if the directory exists on the filesystem. - * - * Sets isValid. - * - * @return - */ - public boolean checkDir() { - if (dir == null) { - initDir(); - } - isValid = dir.isDirectory(); - return isValid; - } - - /** * Read the filesystem directory and fill this object. * * Clears the List and (re)reads all files. * * @return boolean the directory exists */ - public boolean readDir() { + public synchronized boolean readDir() { // check directory first - checkDir(); if (!isValid) { return false; } + // re-check modification time because the thread may have slept + if (dir.lastModified() <= dirMTime) { + return true; + } // read all filenames - logger.debug("reading directory " + dir.getPath()); + logger.debug("reading directory "+this+" = "+dir.getPath()); File[] allFiles = null; /* * using ReadableFileFilter is safer (we won't get directories with file