LUCENE-1640: fix MockRAMDir's internal synchronization (used only by unit tests)

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@776053 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2009-05-18 19:07:32 +00:00
parent 571a058767
commit af71c1829d
2 changed files with 39 additions and 54 deletions

View File

@ -54,7 +54,7 @@ public class MockRAMDirectory extends RAMDirectory {
// like super is called, then our members are initialized: // like super is called, then our members are initialized:
Map openFiles; Map openFiles;
private void init() { private synchronized void init() {
if (openFiles == null) if (openFiles == null)
openFiles = new HashMap(); openFiles = new HashMap();
if (createdFiles == null) if (createdFiles == null)
@ -96,11 +96,9 @@ public class MockRAMDirectory extends RAMDirectory {
/** Simulates a crash of OS or machine by overwriting /** Simulates a crash of OS or machine by overwriting
* unsycned files. */ * unsycned files. */
public void crash() throws IOException { public synchronized void crash() throws IOException {
synchronized(this) { crashed = true;
crashed = true; openFiles = new HashMap();
openFiles = new HashMap();
}
Iterator it = unSyncedFiles.iterator(); Iterator it = unSyncedFiles.iterator();
unSyncedFiles = new HashSet(); unSyncedFiles = new HashSet();
int count = 0; int count = 0;
@ -195,64 +193,53 @@ public class MockRAMDirectory extends RAMDirectory {
if (unSyncedFiles.contains(name)) if (unSyncedFiles.contains(name))
unSyncedFiles.remove(name); unSyncedFiles.remove(name);
if (!forced) { if (!forced) {
synchronized(openFiles) { if (noDeleteOpenFile && openFiles.containsKey(name)) {
if (noDeleteOpenFile && openFiles.containsKey(name)) { throw new IOException("MockRAMDirectory: file \"" + name + "\" is still open: cannot delete");
throw new IOException("MockRAMDirectory: file \"" + name + "\" is still open: cannot delete");
}
} }
} }
super.deleteFile(name); super.deleteFile(name);
} }
public IndexOutput createOutput(String name) throws IOException { public synchronized IndexOutput createOutput(String name) throws IOException {
if (crashed) if (crashed)
throw new IOException("cannot createOutput after crash"); throw new IOException("cannot createOutput after crash");
init(); init();
synchronized(openFiles) { if (preventDoubleWrite && createdFiles.contains(name) && !name.equals("segments.gen"))
if (preventDoubleWrite && createdFiles.contains(name) && !name.equals("segments.gen")) throw new IOException("file \"" + name + "\" was already written to");
throw new IOException("file \"" + name + "\" was already written to"); if (noDeleteOpenFile && openFiles.containsKey(name))
if (noDeleteOpenFile && openFiles.containsKey(name)) throw new IOException("MockRAMDirectory: file \"" + name + "\" is still open: cannot overwrite");
throw new IOException("MockRAMDirectory: file \"" + name + "\" is still open: cannot overwrite");
}
RAMFile file = new RAMFile(this); RAMFile file = new RAMFile(this);
synchronized (this) { if (crashed)
if (crashed) throw new IOException("cannot createOutput after crash");
throw new IOException("cannot createOutput after crash"); unSyncedFiles.add(name);
unSyncedFiles.add(name); createdFiles.add(name);
createdFiles.add(name); RAMFile existing = (RAMFile)fileMap.get(name);
RAMFile existing = (RAMFile)fileMap.get(name); // Enforce write once:
// Enforce write once: if (existing!=null && !name.equals("segments.gen"))
if (existing!=null && !name.equals("segments.gen")) throw new IOException("file " + name + " already exists");
throw new IOException("file " + name + " already exists"); else {
else { if (existing!=null) {
if (existing!=null) { sizeInBytes -= existing.sizeInBytes;
sizeInBytes -= existing.sizeInBytes; existing.directory = null;
existing.directory = null;
}
fileMap.put(name, file);
} }
fileMap.put(name, file);
} }
return new MockRAMOutputStream(this, file, name); return new MockRAMOutputStream(this, file, name);
} }
public IndexInput openInput(String name) throws IOException { public synchronized IndexInput openInput(String name) throws IOException {
RAMFile file; RAMFile file = (RAMFile)fileMap.get(name);
synchronized (this) {
file = (RAMFile)fileMap.get(name);
}
if (file == null) if (file == null)
throw new FileNotFoundException(name); throw new FileNotFoundException(name);
else { else {
synchronized(openFiles) { if (openFiles.containsKey(name)) {
if (openFiles.containsKey(name)) { Integer v = (Integer) openFiles.get(name);
Integer v = (Integer) openFiles.get(name); v = new Integer(v.intValue()+1);
v = new Integer(v.intValue()+1); openFiles.put(name, v);
openFiles.put(name, v); } else {
} else { openFiles.put(name, new Integer(1));
openFiles.put(name, new Integer(1));
}
} }
} }
return new MockRAMInputStream(this, name, file); return new MockRAMInputStream(this, name, file);
@ -281,16 +268,14 @@ public class MockRAMDirectory extends RAMDirectory {
return size; return size;
} }
public void close() { public synchronized void close() {
if (openFiles == null) { if (openFiles == null) {
openFiles = new HashMap(); openFiles = new HashMap();
} }
synchronized(openFiles) { if (noDeleteOpenFile && openFiles.size() > 0) {
if (noDeleteOpenFile && openFiles.size() > 0) { // RuntimeException instead of IOException because
// RuntimeException instead of IOException because // super() does not throw IOException currently:
// super() does not throw IOException currently: throw new RuntimeException("MockRAMDirectory: cannot close: there are still open files: " + openFiles);
throw new RuntimeException("MockRAMDirectory: cannot close: there are still open files: " + openFiles);
}
} }
} }

View File

@ -43,7 +43,7 @@ public class MockRAMInputStream extends RAMInputStream {
// remove the conditional check so we also track that // remove the conditional check so we also track that
// all clones get closed: // all clones get closed:
if (!isClone) { if (!isClone) {
synchronized(dir.openFiles) { synchronized(dir) {
Integer v = (Integer) dir.openFiles.get(name); Integer v = (Integer) dir.openFiles.get(name);
// Could be null when MockRAMDirectory.crash() was called // Could be null when MockRAMDirectory.crash() was called
if (v != null) { if (v != null) {