changeset 1697:fc8e4f893db1

Better synchronization in getDirectory() and new getFile(). getDirectory() now only synchronizes when a new directory object is created. getFile() now uses getDirectory(). Other small cleanups.
author Robert Casties <casties@mpiwg-berlin.mpg.de>
date Sun, 16 Dec 2018 18:49:16 +0100
parents 43d48324dceb
children 7e4396e467de
files common/src/main/java/digilib/image/ImageLoaderDocuImage.java common/src/main/java/digilib/io/BaseDirDocuDirectory.java common/src/main/java/digilib/io/DocuDirCache.java common/src/main/java/digilib/io/ImageFileSet.java
diffstat 4 files changed, 84 insertions(+), 105 deletions(-) [+]
line wrap: on
line diff
--- a/common/src/main/java/digilib/image/ImageLoaderDocuImage.java	Sun Dec 16 15:08:01 2018 +0100
+++ b/common/src/main/java/digilib/image/ImageLoaderDocuImage.java	Sun Dec 16 18:49:16 2018 +0100
@@ -366,7 +366,7 @@
     public ImageReader getReader(ImageInput input) throws IOException {
         logger.debug("get ImageReader for " + input);
         if (reuseReader && reader != null) {
-            logger.debug("reuseing ImageReader");
+            logger.debug("reusing ImageReader");
             return reader;
         }
         ImageInputStream istream = null;
--- a/common/src/main/java/digilib/io/BaseDirDocuDirectory.java	Sun Dec 16 15:08:01 2018 +0100
+++ b/common/src/main/java/digilib/io/BaseDirDocuDirectory.java	Sun Dec 16 18:49:16 2018 +0100
@@ -76,8 +76,11 @@
         meta = MetaFactory.getDirMetaInstance();
     }
 
+    /* (non-Javadoc)
+     * @see digilib.io.DocuDirectory#readDir()
+     */
     @Override
-	public boolean readDir() {
+	public synchronized boolean readDir() {
 		// check directory first
 		if (!isValid) {
 			return false;
@@ -134,7 +137,7 @@
 			}
 			/*
 			 * we sort the ArrayList (the list of files) for binarySearch to work
-			 * (DocuDirent's natural sort order is by filename)
+			 * (DocuDirents sort by filename)
 			 */
 			Collections.sort(dl);
 		}
--- a/common/src/main/java/digilib/io/DocuDirCache.java	Sun Dec 16 15:08:01 2018 +0100
+++ b/common/src/main/java/digilib/io/DocuDirCache.java	Sun Dec 16 18:49:16 2018 +0100
@@ -158,123 +158,107 @@
 	 * Returns the DocuDirent with the pathname <code>fn</code> and the index
 	 * <code>in</code>.
 	 * 
-	 * If <code>fn</code> is a file then the corresponding DocuDirent is
-	 * returned and the index is ignored.
+	 * If <code>fn</code> represents a file then the corresponding DocuDirent is
+	 * returned and the number is ignored.
 	 * 
 	 * @param fn
 	 *            digilib pathname
-	 * @param in
-	 *            file index
+	 * @param pn
+	 *            file number
 	 * @return
 	 */
-	public synchronized DocuDirent getFile(String fn, int in) {
+	public DocuDirent getFile(String fn, int pn) {
 		DocuDirectory dd;
-		// file number is 1-based, vector index is 0-based
-		int n = in - 1;
-		// first, assume fn is a directory and look in the cache
-		dd = map.get(fn);
-		if (dd == null) {
-			// cache miss
-			misses.incrementAndGet();
-			/*
-			 * try fn as a directory
-			 */
-			dd = DocuDirectoryFactory.getDocuDirectoryInstance(fn, fileClass);
-			if (dd.isValid()) {
-			    // add to the cache
-			    dd = putDir(dd);
-				// check/read contents
-			    dd.refresh();
-			} else {
-				/*
-				 * maybe it's a file
-				 */
-				// get the parent directory string (like we store it in the cache)
-				String d = FileOps.parent(fn);
-				// try it in the cache
-                // logger.debug(fn + " is a file in dir " + d);
-				dd = map.get(d);
-				if (dd == null) {
-					// try to read from disk
-					dd = DocuDirectoryFactory.getDocuDirectoryInstance(d, fileClass);
-					if (dd.isValid()) {
-						// add to the cache
-						dd = putDir(dd);
-						// check/read contents
-					    dd.refresh();
-					} else {
-						// invalid path
-						return null;
-					}
-				} else {
-					// it was not a real cache miss
-					misses.decrementAndGet();
-				}
-				// get the file's index
+		// file number is 1-based, index is 0-based
+		int n = pn - 1;
+		// get the directory (or the file's parent directory)
+		dd = getDirectory(fn);
+		if (dd != null) {
+			dd.refresh();
+			if (!dd.getDirName().equals(fn)) {
+				// fn was not a directory name, try as a file name
 				n = dd.indexOf(FileOps.filename(fn));
 			}
-		} else {
-			// cache hit
-			hits.incrementAndGet();
-		}
-		dd.refresh();
-		if (dd.isValid()) {
-			try {
-				return dd.get(n);
-			} catch (IndexOutOfBoundsException e) {
-                // logger.debug(fn + " not found in directory");
+			if (dd.isValid()) {
+				try {
+					return dd.get(n);
+				} catch (IndexOutOfBoundsException e) {
+	                // logger.debug(fn + " not found in directory");
+				}
 			}
 		}
 		return null;
+		
 	}
-
+	
 	/**
 	 * Returns the DocuDirectory indicated by the pathname <code>fn</code>.
 	 * 
-	 * If <code>fn</code> is a file then its parent directory is returned.
+	 * If <code>fn</code> represents a file then its parent directory is returned.
 	 * 
 	 * @param fn
 	 *            digilib pathname
 	 * @return
 	 */
-	public synchronized DocuDirectory getDirectory(String fn) {
+	public DocuDirectory getDirectory(String fn) {
 		DocuDirectory dd;
 		// first, assume fn is a directory and look in the cache
 		dd = map.get(fn);
-		if (dd == null) {
-			// cache miss
-			misses.incrementAndGet();
-			// see if it's a directory
-			dd = DocuDirectoryFactory.getDocuDirectoryInstance(fn, fileClass);
+		if (dd != null) {
+			// cache hit
+			hits.incrementAndGet();
+			dd.refresh();
 			if (dd.isValid()) {
-			    // add to the cache
-			    dd = putDir(dd);
-                dd.refresh();
+				return dd;
 			} else {
-				// try the parent directory in the cache
-				String pn = FileOps.parent(fn);
-                dd = map.get(pn);
-				if (dd == null) {
-					// try to read from disk
-					dd = DocuDirectoryFactory.getDocuDirectoryInstance(pn, fileClass);
+				return null;
+			}
+		} else {
+			// make sure that only one thread creates the new directory
+			synchronized (this) {
+				// look again because the thread may have slept
+				dd = map.get(fn);
+				if (dd != null) {
+					// cache hit
+					hits.incrementAndGet();
+					dd.refresh();
 					if (dd.isValid()) {
-						// add to the cache
-						dd = putDir(dd);
-		                dd.refresh();
+						return dd;
 					} else {
-						// invalid path
 						return null;
 					}
+				}
+				// cache miss
+				misses.incrementAndGet();
+				// see if it's a directory
+				dd = DocuDirectoryFactory.getDocuDirectoryInstance(fn, fileClass);
+				if (dd.isValid()) {
+					// add to the cache
+					dd.refresh();
+					dd = putDir(dd);
 				} else {
-					// not a real cache miss then
-					misses.decrementAndGet();
+					// try the parent directory in the cache
+					String pn = FileOps.parent(fn);
+					dd = map.get(pn);
+					if (dd != null) {
+						// not a real cache miss then
+						misses.decrementAndGet();
+						dd.refresh();
+					} else {
+						// try to read from disk
+						dd = DocuDirectoryFactory.getDocuDirectoryInstance(pn, fileClass);
+						if (dd.isValid()) {
+							// add to the cache
+							dd.refresh();
+							dd = putDir(dd);
+						} else {
+							// invalid path
+							return null;
+						}
+					}
 				}
 			}
-		} else {
-			// cache hit
-			hits.incrementAndGet();
 		}
-		dd.refresh();
 		if (dd.isValid()) {
 			return dd;
 		}
--- a/common/src/main/java/digilib/io/ImageFileSet.java	Sun Dec 16 15:08:01 2018 +0100
+++ b/common/src/main/java/digilib/io/ImageFileSet.java	Sun Dec 16 18:49:16 2018 +0100
@@ -125,7 +125,7 @@
      * @param hints
      *  
      */
-    void fill(Directory[] dirs, File fl) {
+    protected synchronized void fill(Directory[] dirs, File fl) {
     	String fn = fl.getName();
     	String baseFn = FileOps.basename(fn);
     	// add the first ImageFile to the ImageSet
@@ -151,14 +151,12 @@
     					&& (FileOps.basename(dirFiles[fileIdx]).equals(baseFn))) {
     				// idx ok
     			} else if ((fileIdx > 0)
-    					&& (FileOps.basename(dirFiles[fileIdx - 1])
-    							.equals(baseFn))) {
+						&& (FileOps.basename(dirFiles[fileIdx - 1]).equals(baseFn))) {
     				// idx-1 ok
     				fileIdx = fileIdx - 1;
     			} else if ((fileIdx+1 < dirFiles.length)
-    					&& (FileOps.basename(dirFiles[fileIdx + 1])
-    							.equals(baseFn))) {
-    				// idx+1 ok
+						&& (FileOps.basename(dirFiles[fileIdx + 1]).equals(baseFn))) {
+	   				// idx+1 ok
     				fileIdx = fileIdx + 1;
     			} else {
     				// basename doesn't match
@@ -211,10 +209,8 @@
         if (fileMeta.containsKey("original-dpi-x")
                 && fileMeta.containsKey("original-dpi-y")) {
             try {
-                dpix = Float.parseFloat((String) fileMeta
-                        .get("original-dpi-x"));
-                dpiy = Float.parseFloat((String) fileMeta
-                        .get("original-dpi-y"));
+				dpix = Float.parseFloat((String) fileMeta.get("original-dpi-x"));
+				dpiy = Float.parseFloat((String) fileMeta.get("original-dpi-y"));
             } catch (NumberFormatException e) {
             }
             if ((dpix != 0) && (dpiy != 0)) {
@@ -229,14 +225,10 @@
                 && fileMeta.containsKey("original-pixel-x")
                 && fileMeta.containsKey("original-pixel-y")) {
             try {
-                sizex = Float.parseFloat((String) fileMeta
-                        .get("original-size-x"));
-                sizey = Float.parseFloat((String) fileMeta
-                        .get("original-size-y"));
-                pixx = Float.parseFloat((String) fileMeta
-                        .get("original-pixel-x"));
-                pixy = Float.parseFloat((String) fileMeta
-                        .get("original-pixel-y"));
+				sizex = Float.parseFloat((String) fileMeta.get("original-size-x"));
+				sizey = Float.parseFloat((String) fileMeta.get("original-size-y"));
+				pixx = Float.parseFloat((String) fileMeta.get("original-pixel-x"));
+				pixy = Float.parseFloat((String) fileMeta.get("original-pixel-y"));
             } catch (NumberFormatException e) {
             }
             if ((sizex != 0) && (sizey != 0) && (pixx != 0) && (pixy != 0)) {