diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index a6170cd61a6..0c5df66ac2a 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -55,6 +55,9 @@ Improvements module into core and is now the default analyzer in IndexWriterConfig (Robert Muir, Mike McCandless) +* LUCENE-7345: RAMDirectory now enforces write-once files as well + (Robert Muir, Mike McCandless) + Optimizations * LUCENE-7330: Speed up conjunction queries. (Adrien Grand) diff --git a/lucene/core/src/java/org/apache/lucene/store/RAMDirectory.java b/lucene/core/src/java/org/apache/lucene/store/RAMDirectory.java index a4bc2eab36e..54375e66c03 100644 --- a/lucene/core/src/java/org/apache/lucene/store/RAMDirectory.java +++ b/lucene/core/src/java/org/apache/lucene/store/RAMDirectory.java @@ -19,6 +19,7 @@ package org.apache.lucene.store; import java.io.FileNotFoundException; import java.io.IOException; +import java.nio.file.FileAlreadyExistsException; import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; @@ -177,12 +178,9 @@ public class RAMDirectory extends BaseDirectory implements Accountable { public IndexOutput createOutput(String name, IOContext context) throws IOException { ensureOpen(); RAMFile file = newRAMFile(); - RAMFile existing = fileMap.remove(name); - if (existing != null) { - sizeInBytes.addAndGet(-existing.sizeInBytes); - existing.directory = null; + if (fileMap.putIfAbsent(name, file) != null) { + throw new FileAlreadyExistsException(name); } - fileMap.put(name, file); return new RAMOutputStream(name, file, true); } @@ -222,7 +220,12 @@ public class RAMDirectory extends BaseDirectory implements Accountable { if (file == null) { throw new FileNotFoundException(source); } - fileMap.put(dest, file); + if (fileMap.putIfAbsent(dest, file) != null) { + throw new FileAlreadyExistsException(dest); + } + if (!fileMap.remove(source, file)) { + throw new IllegalStateException("file was unexpectedly replaced: " + source); + } fileMap.remove(source); } diff --git a/lucene/test-framework/src/java/org/apache/lucene/store/MockDirectoryWrapper.java b/lucene/test-framework/src/java/org/apache/lucene/store/MockDirectoryWrapper.java index 209ee80005e..193d877b076 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/store/MockDirectoryWrapper.java +++ b/lucene/test-framework/src/java/org/apache/lucene/store/MockDirectoryWrapper.java @@ -636,22 +636,6 @@ public class MockDirectoryWrapper extends BaseDirectoryWrapper { unSyncedFiles.add(name); createdFiles.add(name); - if (in instanceof RAMDirectory) { - RAMDirectory ramdir = (RAMDirectory) in; - RAMFile file = new RAMFile(ramdir); - RAMFile existing = ramdir.fileMap.get(name); - - // Enforce write once: - if (existing!=null && !name.equals("segments.gen")) { - throw new IOException("file " + name + " already exists"); - } else { - if (existing!=null) { - ramdir.sizeInBytes.getAndAdd(-existing.sizeInBytes); - existing.directory = null; - } - ramdir.fileMap.put(name, file); - } - } //System.out.println(Thread.currentThread().getName() + ": MDW: create " + name); IndexOutput delegateOutput = in.createOutput(name, LuceneTestCase.newIOContext(randomState, context)); final IndexOutput io = new MockIndexOutputWrapper(this, delegateOutput, name);