You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by us...@apache.org on 2014/11/09 14:08:18 UTC

svn commit: r1637674 [1/2] - in /lucene/dev/branches/branch_5x: ./ lucene/ lucene/backward-codecs/src/java/org/apache/lucene/codecs/lucene40/ lucene/codecs/ lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/ lucene/core/ lucene/core/src/java/o...

Author: uschindler
Date: Sun Nov  9 13:08:16 2014
New Revision: 1637674

URL: http://svn.apache.org/r1637674
Log:
Merged revision(s) 1637665 from lucene/dev/trunk:
LUCENE-5953: Restructure Directory and LockFactory APIs

Removed:
    lucene/dev/branches/branch_5x/lucene/test-framework/src/java/org/apache/lucene/store/MockLockFactoryWrapper.java
Modified:
    lucene/dev/branches/branch_5x/   (props changed)
    lucene/dev/branches/branch_5x/lucene/   (props changed)
    lucene/dev/branches/branch_5x/lucene/CHANGES.txt   (contents, props changed)
    lucene/dev/branches/branch_5x/lucene/MIGRATE.txt
    lucene/dev/branches/branch_5x/lucene/backward-codecs/src/java/org/apache/lucene/codecs/lucene40/Lucene40CompoundReader.java
    lucene/dev/branches/branch_5x/lucene/codecs/   (props changed)
    lucene/dev/branches/branch_5x/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextCompoundFormat.java
    lucene/dev/branches/branch_5x/lucene/core/   (props changed)
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50CompoundReader.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/BaseDirectory.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/Directory.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/FSDirectory.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/FSLockFactory.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/FileSwitchDirectory.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/FilterDirectory.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/LockFactory.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/LockStressTest.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/MMapDirectory.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/NIOFSDirectory.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/NativeFSLockFactory.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/NoLockFactory.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/RAMDirectory.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/SimpleFSDirectory.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/SimpleFSLockFactory.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/SingleInstanceLockFactory.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/VerifyingLockFactory.java
    lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/util/CommandLineUtil.java
    lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestCrash.java
    lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestCrashCausesCorruptIndex.java
    lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestDoc.java
    lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestFieldsReader.java
    lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java
    lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/store/TestBufferedIndexInput.java
    lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/store/TestDirectory.java
    lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/store/TestLockFactory.java
    lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/store/TestMockDirectoryWrapper.java
    lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/store/TestMultiMMap.java
    lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/store/TestWindowsMMap.java
    lucene/dev/branches/branch_5x/lucene/misc/   (props changed)
    lucene/dev/branches/branch_5x/lucene/misc/src/java/org/apache/lucene/store/NativeUnixDirectory.java
    lucene/dev/branches/branch_5x/lucene/misc/src/java/org/apache/lucene/store/RAFDirectory.java
    lucene/dev/branches/branch_5x/lucene/misc/src/java/org/apache/lucene/store/WindowsDirectory.java
    lucene/dev/branches/branch_5x/lucene/test-framework/   (props changed)
    lucene/dev/branches/branch_5x/lucene/test-framework/src/java/org/apache/lucene/index/BaseCompoundFormatTestCase.java
    lucene/dev/branches/branch_5x/lucene/test-framework/src/java/org/apache/lucene/store/MockDirectoryWrapper.java
    lucene/dev/branches/branch_5x/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java
    lucene/dev/branches/branch_5x/lucene/test-framework/src/java/org/apache/lucene/util/TestUtil.java
    lucene/dev/branches/branch_5x/solr/   (props changed)
    lucene/dev/branches/branch_5x/solr/contrib/   (props changed)
    lucene/dev/branches/branch_5x/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/TreeMergeOutputFormat.java
    lucene/dev/branches/branch_5x/solr/core/   (props changed)
    lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/CachingDirectoryFactory.java
    lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/DirectoryFactory.java
    lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/HdfsDirectoryFactory.java
    lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/MMapDirectoryFactory.java
    lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/RAMDirectoryFactory.java
    lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/StandardDirectoryFactory.java
    lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/SnapShooter.java
    lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/store/blockcache/BlockDirectory.java
    lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/store/hdfs/HdfsDirectory.java
    lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLockFactory.java
    lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/core/SolrCoreCheckLockOnStartupTest.java
    lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/store/hdfs/HdfsDirectoryTest.java
    lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/store/hdfs/HdfsLockFactoryTest.java
    lucene/dev/branches/branch_5x/solr/test-framework/   (props changed)
    lucene/dev/branches/branch_5x/solr/test-framework/src/java/org/apache/solr/core/MockDirectoryFactory.java

Modified: lucene/dev/branches/branch_5x/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/CHANGES.txt?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/CHANGES.txt (original)
+++ lucene/dev/branches/branch_5x/lucene/CHANGES.txt Sun Nov  9 13:08:16 2014
@@ -157,6 +157,13 @@ API Changes
 * LUCENE-6021: FixedBitSet.nextSetBit now returns DocIdSetIterator.NO_MORE_DOCS
   instead of -1 when there are no more bits which are set. (Adrien Grand)
 
+* LUCENE-5953: Directory and LockFactory APIs were restructured: Locking is
+  now under the responsibility of the Directory implementation. LockFactory is
+  only used by subclasses of BaseDirectory to delegate locking to an impl
+  class. LockFactories are now singletons and are responsible to create a Lock
+  instance based on a Directory implementation passed to the factory method.
+  See MIGRATE.txt for more details.  (Uwe Schindler, Robert Muir)
+
 Bug Fixes
 
 * LUCENE-5650: Enforce read-only access to any path outside the temporary

Modified: lucene/dev/branches/branch_5x/lucene/MIGRATE.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/MIGRATE.txt?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/MIGRATE.txt (original)
+++ lucene/dev/branches/branch_5x/lucene/MIGRATE.txt Sun Nov  9 13:08:16 2014
@@ -1,5 +1,50 @@
 # Apache Lucene Migration Guide
 
+## Disk I/O API completely changed to Java-7-NIO.2
+
+All directory APIs were changed to make use of the new Java 7 NIO.2 API.
+It is no longer possible to pass java.io.File or string-based directory
+names to FSDirectory classes. FSDirectory classes now require
+java.nio.file.Path instances. This allows to place index directories also
+on "virtual file systems" like ZIP or TAR files. To migrate existing code
+use java.io.File#toPath().
+
+In addition, please make sure that custom directory implementations throw
+the new Exceptions, because Lucene cannot understand the old legacy
+Exceptions like java.io.FileNotFoundException instead of
+java.nio.file.NoSuchFileException.
+
+## Directory and LockFactory APIs restructured (LUCENE-5953)
+
+Locking is now under the responsibility of the Directory implementation.
+LockFactory is only used by subclasses of BaseDirectory to delegate locking
+to an impl class. LockFactories are responsible to create a Lock on behalf
+of a BaseDirectory subclass.
+
+The following changes in existing code need to be done:
+
+- LockFactory implementations are singletons now and have no state. They only
+  need to implement one method: makeLock(Directory dir, String name).
+  The passed directory can be used to determine the corect file system path
+  for the lock file or similar, so it knows where to create the lock.
+  In addition, the factory may check with instanceof, if the lock factory
+  can be used with the type of directory at all.
+- It was never really supported to place lock files outside of the index
+  directory and this functionality was removed. If you still rely on this,
+  you can use the following trick: Use FileSwitchDirectory and delegate
+  the file extension ".lock" to another Directory instance pointing to
+  another path. FileSwitchDirectory also delegates lock files based on
+  the extension.
+- If you wrap another directory using FilterDirectory, you cannot make use
+  of LockFactories anymore, because only BaseDirectory knows about them.
+  To wrap locking, you must hook into FilterDirectory.makeLock(String name)
+  and wrap the Lock instance returned, as needed. See MockDirectoryWrapper
+  in lucene-test-framework for an example.
+- It is no longer allowed to pass "null" as LockFactory to FSDirectory
+  implementations. You have to explicitely pass the platform default to the
+  directory (currently always NativeFSLockFactory.INSTANCE, but subject to
+  change!). To get the platform default, call FSLockFactory.getDefault().
+
 ## Removed Reader from Tokenizer constructor (LUCENE-5388)
 
 The constructor of Tokenizer no longer takes Reader, as this was a leftover

Modified: lucene/dev/branches/branch_5x/lucene/backward-codecs/src/java/org/apache/lucene/codecs/lucene40/Lucene40CompoundReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/backward-codecs/src/java/org/apache/lucene/codecs/lucene40/Lucene40CompoundReader.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/backward-codecs/src/java/org/apache/lucene/codecs/lucene40/Lucene40CompoundReader.java (original)
+++ lucene/dev/branches/branch_5x/lucene/backward-codecs/src/java/org/apache/lucene/codecs/lucene40/Lucene40CompoundReader.java Sun Nov  9 13:08:16 2014
@@ -20,7 +20,6 @@ package org.apache.lucene.codecs.lucene4
 import org.apache.lucene.codecs.CodecUtil;
 import org.apache.lucene.index.CorruptIndexException;
 import org.apache.lucene.index.IndexFileNames;
-import org.apache.lucene.store.BaseDirectory;
 import org.apache.lucene.store.BufferedIndexInput;
 import org.apache.lucene.store.ChecksumIndexInput;
 import org.apache.lucene.store.Directory;
@@ -42,7 +41,7 @@ import java.io.IOException;
  * @deprecated only for reading 4.x segments
  */
 @Deprecated
-final class Lucene40CompoundReader extends BaseDirectory {
+final class Lucene40CompoundReader extends Directory {
   
   // TODO: would be great to move this read-write stuff out of here into test.
 
@@ -61,6 +60,7 @@ final class Lucene40CompoundReader exten
   private final Lucene40CompoundWriter writer;
   private final IndexInput handle;
   private int version;
+  private boolean isOpen;
   
   /**
    * Create a new CompoundFileDirectory.
@@ -240,11 +240,6 @@ final class Lucene40CompoundReader exten
   }
   
   @Override
-  public void clearLock(String name) throws IOException {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
   public String toString() {
     return "CompoundFileDirectory(file=\"" + fileName + "\" in dir=" + directory + ")";
   }

Modified: lucene/dev/branches/branch_5x/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextCompoundFormat.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextCompoundFormat.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextCompoundFormat.java (original)
+++ lucene/dev/branches/branch_5x/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextCompoundFormat.java Sun Nov  9 13:08:16 2014
@@ -32,7 +32,6 @@ import org.apache.lucene.index.CorruptIn
 import org.apache.lucene.index.MergeState.CheckAbort;
 import org.apache.lucene.index.IndexFileNames;
 import org.apache.lucene.index.SegmentInfo;
-import org.apache.lucene.store.BaseDirectory;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.IOContext;
 import org.apache.lucene.store.IndexInput;
@@ -103,7 +102,7 @@ public class SimpleTextCompoundFormat ex
       endOffsets[i] = Long.parseLong(stripPrefix(scratch, TABLEEND));
     }
     
-    return new BaseDirectory() {
+    return new Directory() {
       
       private int getIndex(String name) throws IOException {
         int index = Arrays.binarySearch(fileNames, name);
@@ -135,7 +134,6 @@ public class SimpleTextCompoundFormat ex
       
       @Override
       public void close() throws IOException {
-        isOpen = false;
         in.close();
       }
       
@@ -155,9 +153,6 @@ public class SimpleTextCompoundFormat ex
       
       @Override
       public Lock makeLock(String name) { throw new UnsupportedOperationException(); }
-      
-      @Override
-      public void clearLock(String name) { throw new UnsupportedOperationException(); }
     };
   }
 

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50CompoundReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50CompoundReader.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50CompoundReader.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50CompoundReader.java Sun Nov  9 13:08:16 2014
@@ -21,7 +21,6 @@ import org.apache.lucene.codecs.CodecUti
 import org.apache.lucene.index.CorruptIndexException;
 import org.apache.lucene.index.IndexFileNames;
 import org.apache.lucene.index.SegmentInfo;
-import org.apache.lucene.store.BaseDirectory;
 import org.apache.lucene.store.ChecksumIndexInput;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.IOContext;
@@ -43,7 +42,7 @@ import java.io.IOException;
  * Directory methods that would normally modify data throw an exception.
  * @lucene.experimental
  */
-final class Lucene50CompoundReader extends BaseDirectory {
+final class Lucene50CompoundReader extends Directory {
   
   /** Offset/Length for a slice inside of a compound file */
   public static final class FileEntry {
@@ -84,7 +83,6 @@ final class Lucene50CompoundReader exten
         IOUtils.closeWhileHandlingException(handle);
       }
     }
-    this.isOpen = true;
   }
 
   /** Helper method that reads CFS entries from an input stream */
@@ -119,7 +117,6 @@ final class Lucene50CompoundReader exten
   
   @Override
   public void close() throws IOException {
-    isOpen = false;
     IOUtils.close(handle);
   }
   
@@ -187,11 +184,6 @@ final class Lucene50CompoundReader exten
   }
 
   @Override
-  public void clearLock(String name) throws IOException {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
   public String toString() {
     return "CompoundFileDirectory(segment=\"" + segmentName + "\" in dir=" + directory + ")";
   }

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/BaseDirectory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/BaseDirectory.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/BaseDirectory.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/BaseDirectory.java Sun Nov  9 13:08:16 2014
@@ -17,10 +17,9 @@ package org.apache.lucene.store;
  * limitations under the License.
  */
 
-import java.io.IOException;
 
 /**
- * Base implementation for a concrete {@link Directory}.
+ * Base implementation for a concrete {@link Directory} that uses a {@link LockFactory} for locking.
  * @lucene.experimental
  */
 public abstract class BaseDirectory extends Directory {
@@ -29,35 +28,20 @@ public abstract class BaseDirectory exte
 
   /** Holds the LockFactory instance (implements locking for
    * this Directory instance). */
-  protected LockFactory lockFactory;
+  protected final LockFactory lockFactory;
 
   /** Sole constructor. */
-  protected BaseDirectory() {
+  protected BaseDirectory(LockFactory lockFactory) {
     super();
-  }
-
-  @Override
-  public Lock makeLock(String name) {
-      return lockFactory.makeLock(name);
-  }
-
-  @Override
-  public void clearLock(String name) throws IOException {
-    if (lockFactory != null) {
-      lockFactory.clearLock(name);
+    if (lockFactory == null) {
+      throw new NullPointerException("LockFactory cannot be null, use an explicit instance!");
     }
-  }
-
-  @Override
-  public void setLockFactory(LockFactory lockFactory) throws IOException {
-    assert lockFactory != null;
     this.lockFactory = lockFactory;
-    lockFactory.setLockPrefix(this.getLockID());
   }
 
   @Override
-  public LockFactory getLockFactory() {
-    return this.lockFactory;
+  public final Lock makeLock(String name) {
+    return lockFactory.makeLock(this, name);
   }
 
   @Override
@@ -66,4 +50,9 @@ public abstract class BaseDirectory exte
       throw new AlreadyClosedException("this Directory is closed");
   }
 
+  @Override
+  public String toString() {
+    return super.toString()  + " lockFactory=" + lockFactory;
+  }
+  
 }

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/Directory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/Directory.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/Directory.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/Directory.java Sun Nov  9 13:08:16 2014
@@ -37,8 +37,7 @@ import org.apache.lucene.util.IOUtils;
  * </ul>
  *
  * Directory locking is implemented by an instance of {@link
- * LockFactory}, and can be changed for each Directory
- * instance using {@link #setLockFactory}.
+ * LockFactory}.
  *
  */
 public abstract class Directory implements Closeable {
@@ -116,53 +115,14 @@ public abstract class Directory implemen
    */
   public abstract Lock makeLock(String name);
 
-  /**
-   * Attempt to clear (forcefully unlock and remove) the
-   * specified lock.  Only call this at a time when you are
-   * certain this lock is no longer in use.
-   * @param name name of the lock to be cleared.
-   */
-  public abstract void clearLock(String name) throws IOException;
-
   /** Closes the store. */
   @Override
   public abstract void close()
        throws IOException;
 
-  /**
-   * Set the LockFactory that this Directory instance should
-   * use for its locking implementation.  Each * instance of
-   * LockFactory should only be used for one directory (ie,
-   * do not share a single instance across multiple
-   * Directories).
-   *
-   * @param lockFactory instance of {@link LockFactory}.
-   */
-  public abstract void setLockFactory(LockFactory lockFactory) throws IOException;
-
-  /**
-   * Get the LockFactory that this Directory instance is
-   * using for its locking implementation.  Note that this
-   * may be null for Directory implementations that provide
-   * their own locking implementation.
-   */
-  public abstract LockFactory getLockFactory();
-
-  /**
-   * Return a string identifier that uniquely differentiates
-   * this Directory instance from other Directory instances.
-   * This ID should be the same if two Directory instances
-   * (even in different JVMs and/or on different machines)
-   * are considered "the same index".  This is how locking
-   * "scopes" to the right index.
-   */
-  public String getLockID() {
-    return this.toString();
-  }
-
   @Override
   public String toString() {
-    return getClass().getSimpleName() + '@' + Integer.toHexString(hashCode()) + " lockFactory=" + getLockFactory();
+    return getClass().getSimpleName() + '@' + Integer.toHexString(hashCode());
   }
 
   /**

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/FSDirectory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/FSDirectory.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/FSDirectory.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/FSDirectory.java Sun Nov  9 13:08:16 2014
@@ -125,15 +125,9 @@ public abstract class FSDirectory extend
    * @throws IOException if there is a low-level I/O error
    */
   protected FSDirectory(Path path, LockFactory lockFactory) throws IOException {
-    // new ctors use always NativeFSLockFactory as default:
-    if (lockFactory == null) {
-      lockFactory = new NativeFSLockFactory();
-    }
-    
+    super(lockFactory);
     Files.createDirectories(path);  // create directory, if it doesnt exist
     directory = path.toRealPath();
-
-    setLockFactory(lockFactory);
   }
 
   /** Creates an FSDirectory instance, trying to pick the
@@ -157,7 +151,7 @@ public abstract class FSDirectory extend
    *
    * <p>See <a href="#subclasses">above</a> */
   public static FSDirectory open(Path path) throws IOException {
-    return open(path, null);
+    return open(path, FSLockFactory.getDefault());
   }
 
   /** Just like {@link #open(Path)}, but allows you to
@@ -172,26 +166,6 @@ public abstract class FSDirectory extend
     }
   }
 
-  @Override
-  public void setLockFactory(LockFactory lockFactory) throws IOException {
-    super.setLockFactory(lockFactory);
-
-    // for filesystem based LockFactory, delete the lockPrefix, if the locks are placed
-    // in index dir. If no index dir is given, set ourselves
-    if (lockFactory instanceof FSLockFactory) {
-      final FSLockFactory lf = (FSLockFactory) lockFactory;
-      final Path dir = lf.getLockDir();
-      // if the lock factory has no lockDir set, use the this directory as lockDir
-      if (dir == null) {
-        lf.setLockDir(directory);
-        lf.setLockPrefix(null);
-      } else if (dir.toRealPath().equals(directory)) {
-        lf.setLockPrefix(null);
-      }
-    }
-
-  }
-  
   /** Lists all files (not subdirectories) in the
    *  directory.
    *
@@ -280,19 +254,6 @@ public abstract class FSDirectory extend
     IOUtils.fsync(directory, true);
   }
 
-  @Override
-  public String getLockID() {
-    ensureOpen();
-    String dirName = directory.toString();  // name to be hashed
-
-    int digest = 0;
-    for(int charIDX=0;charIDX<dirName.length();charIDX++) {
-      final char ch = dirName.charAt(charIDX);
-      digest = 31 * digest + ch;
-    }
-    return "lucene-" + Integer.toHexString(digest);
-  }
-
   /** Closes the store to future operations. */
   @Override
   public synchronized void close() {
@@ -308,7 +269,7 @@ public abstract class FSDirectory extend
   /** For debug output. */
   @Override
   public String toString() {
-    return this.getClass().getSimpleName() + "@" + directory + " lockFactory=" + getLockFactory();
+    return this.getClass().getSimpleName() + "@" + directory + " lockFactory=" + lockFactory;
   }
 
   final class FSIndexOutput extends OutputStreamIndexOutput {

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/FSLockFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/FSLockFactory.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/FSLockFactory.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/FSLockFactory.java Sun Nov  9 13:08:16 2014
@@ -17,47 +17,29 @@ package org.apache.lucene.store;
  * limitations under the License.
  */
 
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-
 /**
  * Base class for file system based locking implementation.
+ * This class is explicitly checking that the passed {@link Directory}
+ * is an {@link FSDirectory}.
  */
-
 public abstract class FSLockFactory extends LockFactory {
-
-  /**
-   * Directory for the lock files.
-   */
-  protected Path lockDir = null;
-
-  /**
-   * Set the lock directory. This method can be only called
-   * once to initialize the lock directory. It is used by {@link FSDirectory}
-   * to set the lock directory to itself.
-   * Subclasses can also use this method to set the directory
-   * in the constructor.
-   */
-  protected final void setLockDir(Path lockDir) throws IOException {
-    if (this.lockDir != null)
-      throw new IllegalStateException("You can set the lock directory for this factory only once.");
-    if (lockDir != null) {
-      Files.createDirectories(lockDir);
-    }
-    this.lockDir = lockDir;
-  }
   
-  /**
-   * Retrieve the lock directory.
+  /** Returns the default locking implementation for this platform.
+   * This method currently returns always {@link NativeFSLockFactory}.
    */
-  public Path getLockDir() {
-    return lockDir;
+  public static final FSLockFactory getDefault() {
+    return NativeFSLockFactory.INSTANCE;
   }
 
   @Override
-  public String toString() {
-    return this.getClass().getSimpleName() + "@" + lockDir;
+  public final Lock makeLock(Directory dir, String lockName) {
+    if (!(dir instanceof FSDirectory)) {
+      throw new UnsupportedOperationException(getClass().getSimpleName() + " can only be used with FSDirectory subclasses, got: " + dir);
+    }
+    return makeFSLock((FSDirectory) dir, lockName);
   }
   
+  /** Implement this method to create a lock for a FSDirectory instance. */
+  protected abstract Lock makeFSLock(FSDirectory dir, String lockName);
+
 }

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/FileSwitchDirectory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/FileSwitchDirectory.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/FileSwitchDirectory.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/FileSwitchDirectory.java Sun Nov  9 13:08:16 2014
@@ -20,13 +20,14 @@ package org.apache.lucene.store;
 import java.io.IOException;
 import java.nio.file.AtomicMoveNotSupportedException;
 import java.nio.file.NoSuchFileException;
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Set;
 import java.util.HashSet;
 
+import org.apache.lucene.util.IOUtils;
+
 
 /**
  * Expert: A Directory instance that switches files between
@@ -38,10 +39,15 @@ import java.util.HashSet;
  * to this class, and must allow multiple threads to call
  * contains at once.</p>
  *
+ * <p>Locks with a name having the specified extensions are
+ * delegated to the primary directory; others are delegated
+ * to the secondary directory. Ideally, both Directory
+ * instances should use the same lock factory.</p>
+ *
  * @lucene.experimental
  */
 
-public class FileSwitchDirectory extends BaseDirectory {
+public class FileSwitchDirectory extends Directory {
   private final Directory secondaryDir;
   private final Directory primaryDir;
   private final Set<String> primaryExtensions;
@@ -52,7 +58,6 @@ public class FileSwitchDirectory extends
     this.primaryDir = primaryDir;
     this.secondaryDir = secondaryDir;
     this.doClose = doClose;
-    this.lockFactory = primaryDir.getLockFactory();
   }
 
   /** Return the primary directory */
@@ -66,13 +71,14 @@ public class FileSwitchDirectory extends
   }
   
   @Override
+  public Lock makeLock(String name) {
+    return getDirectory(name).makeLock(name);
+  }
+
+  @Override
   public void close() throws IOException {
     if (doClose) {
-      try {
-        secondaryDir.close();
-      } finally { 
-        primaryDir.close();
-      }
+      IOUtils.close(primaryDir, secondaryDir);
       doClose = false;
     }
   }

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/FilterDirectory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/FilterDirectory.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/FilterDirectory.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/FilterDirectory.java Sun Nov  9 13:08:16 2014
@@ -86,31 +86,11 @@ public class FilterDirectory extends Dir
   }
 
   @Override
-  public void clearLock(String name) throws IOException {
-    in.clearLock(name);
-  }
-
-  @Override
   public void close() throws IOException {
     in.close();
   }
 
   @Override
-  public void setLockFactory(LockFactory lockFactory) throws IOException {
-    in.setLockFactory(lockFactory);
-  }
-
-  @Override
-  public String getLockID() {
-    return in.getLockID();
-  }
-  
-  @Override
-  public LockFactory getLockFactory() {
-    return in.getLockFactory();
-  }
-
-  @Override
   public String toString() {
     return getClass().getSimpleName() + "(" + in.toString() + ")";
   }

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/LockFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/LockFactory.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/LockFactory.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/LockFactory.java Sun Nov  9 13:08:16 2014
@@ -17,7 +17,6 @@ package org.apache.lucene.store;
  * limitations under the License.
  */
 
-import java.io.IOException;
 
 /**
  * <p>Base class for Locking implementation.  {@link Directory} uses
@@ -46,40 +45,10 @@ import java.io.IOException;
 
 public abstract class LockFactory {
 
-  protected String lockPrefix = null;
-
-  /**
-   * Set the prefix in use for all locks created in this
-   * LockFactory.  This is normally called once, when a
-   * Directory gets this LockFactory instance.  However, you
-   * can also call this (after this instance is assigned to
-   * a Directory) to override the prefix in use.  This
-   * is helpful if you're running Lucene on machines that
-   * have different mount points for the same shared
-   * directory.
-   */
-  public void setLockPrefix(String lockPrefix) {
-    this.lockPrefix = lockPrefix;
-  }
-
-  /**
-   * Get the prefix in use for all locks created in this LockFactory.
-   */
-  public String getLockPrefix() {
-    return this.lockPrefix;
-  }
-
   /**
    * Return a new Lock instance identified by lockName.
    * @param lockName name of the lock to be created.
    */
-  public abstract Lock makeLock(String lockName);
+  public abstract Lock makeLock(Directory dir, String lockName);
 
-  /**
-   * Attempt to clear (forcefully unlock and remove) the
-   * specified lock.  Only call this at a time when you are
-   * certain this lock is no longer in use.
-   * @param lockName name of the lock to be cleared.
-   */
-  abstract public void clearLock(String lockName) throws IOException;
 }

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/LockStressTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/LockStressTest.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/LockStressTest.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/LockStressTest.java Sun Nov  9 13:08:16 2014
@@ -45,8 +45,8 @@ public class LockStressTest {
                          "  myID = int from 0 .. 255 (should be unique for test process)\n" +
                          "  verifierHost = hostname that LockVerifyServer is listening on\n" +
                          "  verifierPort = port that LockVerifyServer is listening on\n" +
-                         "  lockFactoryClassName = primary LockFactory class that we will use\n" +
-                         "  lockDirName = path to the lock directory (only set for Simple/NativeFSLockFactory\n" +
+                         "  lockFactoryClassName = primary FSLockFactory class that we will use\n" +
+                         "  lockDirName = path to the lock directory\n" +
                          "  sleepTimeMS = milliseconds to pause betweeen each lock obtain/release\n" +
                          "  count = number of locking tries\n" +
                          "\n" +
@@ -69,11 +69,13 @@ public class LockStressTest {
     final String verifierHost = args[arg++];
     final int verifierPort = Integer.parseInt(args[arg++]);
     final String lockFactoryClassName = args[arg++];
-    final String lockDirName = args[arg++];
+    final Path lockDirPath = Paths.get(args[arg++]);
     final int sleepTimeMS = Integer.parseInt(args[arg++]);
     final int count = Integer.parseInt(args[arg++]);
 
-    final LockFactory lockFactory = getNewLockFactory(lockFactoryClassName, lockDirName);
+    final LockFactory lockFactory = getNewLockFactory(lockFactoryClassName);
+    // we test the lock factory directly, so we don't need it on the directory itsself (the directory is just for testing)
+    final FSDirectory lockDir = new SimpleFSDirectory(lockDirPath, NoLockFactory.INSTANCE);
     final InetSocketAddress addr = new InetSocketAddress(verifierHost, verifierPort);
     System.out.println("Connecting to server " + addr +
         " and registering as client " + myID + "...");
@@ -86,7 +88,7 @@ public class LockStressTest {
       out.write(myID);
       out.flush();
       LockFactory verifyLF = new VerifyingLockFactory(lockFactory, in, out);
-      Lock l = verifyLF.makeLock("test.lock");
+      Lock l = verifyLF.makeLock(lockDir, "test.lock");
       final Random rnd = new Random();
       
       // wait for starting gun
@@ -103,9 +105,9 @@ public class LockStressTest {
         if (obtained) {
           if (rnd.nextInt(10) == 0) {
             if (rnd.nextBoolean()) {
-              verifyLF = new VerifyingLockFactory(getNewLockFactory(lockFactoryClassName, lockDirName), in, out);
+              verifyLF = new VerifyingLockFactory(getNewLockFactory(lockFactoryClassName), in, out);
             }
-            final Lock secondLock = verifyLF.makeLock("test.lock");
+            final Lock secondLock = verifyLF.makeLock(lockDir, "test.lock");
             if (secondLock.obtain()) {
               throw new IOException("Double Obtain");
             }
@@ -126,20 +128,21 @@ public class LockStressTest {
   }
 
 
-  private static LockFactory getNewLockFactory(String lockFactoryClassName, String lockDirName) throws IOException {
-    LockFactory lockFactory;
+  private static FSLockFactory getNewLockFactory(String lockFactoryClassName) throws IOException {
+    // try to get static INSTANCE field of class
     try {
-      lockFactory = Class.forName(lockFactoryClassName).asSubclass(LockFactory.class).newInstance();
+      return (FSLockFactory) Class.forName(lockFactoryClassName).getField("INSTANCE").get(null);
+    } catch (ReflectiveOperationException e) {
+      // fall-through
+    }
+    
+    // try to create a new instance
+    try {
+      return Class.forName(lockFactoryClassName).asSubclass(FSLockFactory.class).newInstance();
     } catch (IllegalAccessException | InstantiationException | ClassCastException | ClassNotFoundException e) {
-      throw new IOException("Cannot instantiate lock factory " + lockFactoryClassName);
+      // fall-through
     }
 
-    Path lockDir = Paths.get(lockDirName);
-
-    if (lockFactory instanceof FSLockFactory) {
-      ((FSLockFactory) lockFactory).setLockDir(lockDir);
-    }
-    lockFactory.setLockPrefix("test");
-    return lockFactory;
+    throw new IOException("Cannot get lock factory singleton of " + lockFactoryClassName);
   }
 }

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/MMapDirectory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/MMapDirectory.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/MMapDirectory.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/MMapDirectory.java Sun Nov  9 13:08:16 2014
@@ -24,7 +24,6 @@ import java.nio.channels.FileChannel;
 import java.nio.channels.FileChannel.MapMode;
 import java.nio.file.Path;
 import java.nio.file.StandardOpenOption;
-
 import java.security.AccessController;
 import java.security.PrivilegedExceptionAction;
 import java.security.PrivilegedActionException;
@@ -85,27 +84,37 @@ public class MMapDirectory extends FSDir
    * Default max chunk size.
    * @see #MMapDirectory(Path, LockFactory, int)
    */
-  public static final int DEFAULT_MAX_BUFF = Constants.JRE_IS_64BIT ? (1 << 30) : (1 << 28);
+  public static final int DEFAULT_MAX_CHUNK_SIZE = Constants.JRE_IS_64BIT ? (1 << 30) : (1 << 28);
   final int chunkSizePower;
 
   /** Create a new MMapDirectory for the named location.
    *
    * @param path the path of the directory
-   * @param lockFactory the lock factory to use, or null for the default
-   * ({@link NativeFSLockFactory});
+   * @param lockFactory the lock factory to use
    * @throws IOException if there is a low-level I/O error
    */
   public MMapDirectory(Path path, LockFactory lockFactory) throws IOException {
-    this(path, lockFactory, DEFAULT_MAX_BUFF);
+    this(path, lockFactory, DEFAULT_MAX_CHUNK_SIZE);
   }
 
-  /** Create a new MMapDirectory for the named location and {@link NativeFSLockFactory}.
-   *
-   * @param path the path of the directory
-   * @throws IOException if there is a low-level I/O error
-   */
+  /** Create a new MMapDirectory for the named location and {@link FSLockFactory#getDefault()}.
+  *
+  * @param path the path of the directory
+  * @throws IOException if there is a low-level I/O error
+  */
   public MMapDirectory(Path path) throws IOException {
-    this(path, null);
+    this(path, FSLockFactory.getDefault());
+  }
+  
+  /** Create a new MMapDirectory for the named location and {@link FSLockFactory#getDefault()}.
+  *
+  * @param path the path of the directory
+  * @param maxChunkSize maximum chunk size (default is 1 GiBytes for
+  * 64 bit JVMs and 256 MiBytes for 32 bit JVMs) used for memory mapping.
+  * @throws IOException if there is a low-level I/O error
+  */
+  public MMapDirectory(Path path, int maxChunkSize) throws IOException {
+    this(path, FSLockFactory.getDefault(), maxChunkSize);
   }
   
   /**

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/NIOFSDirectory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/NIOFSDirectory.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/NIOFSDirectory.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/NIOFSDirectory.java Sun Nov  9 13:08:16 2014
@@ -56,21 +56,20 @@ public class NIOFSDirectory extends FSDi
   /** Create a new NIOFSDirectory for the named location.
    * 
    * @param path the path of the directory
-   * @param lockFactory the lock factory to use, or null for the default
-   * ({@link NativeFSLockFactory});
+   * @param lockFactory the lock factory to use
    * @throws IOException if there is a low-level I/O error
    */
   public NIOFSDirectory(Path path, LockFactory lockFactory) throws IOException {
     super(path, lockFactory);
   }
 
-  /** Create a new NIOFSDirectory for the named location and {@link NativeFSLockFactory}.
+  /** Create a new NIOFSDirectory for the named location and {@link FSLockFactory#getDefault()}.
    *
    * @param path the path of the directory
    * @throws IOException if there is a low-level I/O error
    */
   public NIOFSDirectory(Path path) throws IOException {
-    super(path, null);
+    this(path, FSLockFactory.getDefault());
   }
 
   /** Creates an IndexInput for the file with the given name. */

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/NativeFSLockFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/NativeFSLockFactory.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/NativeFSLockFactory.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/NativeFSLockFactory.java Sun Nov  9 13:08:16 2014
@@ -23,7 +23,6 @@ import java.nio.channels.OverlappingFile
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.StandardOpenOption;
-import java.io.File;
 import java.io.IOException;
 import java.util.Collections;
 import java.util.HashSet;
@@ -66,167 +65,149 @@ import org.apache.lucene.util.IOUtils;
  * not working properly in your environment, you can easily
  * test it by using {@link VerifyingLockFactory}, {@link
  * LockVerifyServer} and {@link LockStressTest}.</p>
+ * 
+ * <p>This is a singleton, you have to use {@link #INSTANCE}.
  *
  * @see LockFactory
  */
 
-public class NativeFSLockFactory extends FSLockFactory {
-
+public final class NativeFSLockFactory extends FSLockFactory {
+  
   /**
-   * Create a NativeFSLockFactory instance, with null (unset)
-   * lock directory. When you pass this factory to a {@link FSDirectory}
-   * subclass, the lock directory is automatically set to the
-   * directory itself. Be sure to create one instance for each directory
-   * your create!
+   * Singleton instance
    */
-  public NativeFSLockFactory() throws IOException {
-    this((Path) null);
-  }
+  public static final NativeFSLockFactory INSTANCE = new NativeFSLockFactory();
 
-  /**
-   * Create a NativeFSLockFactory instance, storing lock
-   * files into the specified lockDir:
-   * 
-   * @param lockDir where lock files are created.
-   */
-  public NativeFSLockFactory(Path lockDir) throws IOException {
-    setLockDir(lockDir);
-  }
-
-  @Override
-  public synchronized Lock makeLock(String lockName) {
-    if (lockPrefix != null)
-      lockName = lockPrefix + "-" + lockName;
-    return new NativeFSLock(lockDir, lockName);
-  }
+  private NativeFSLockFactory() {}
 
   @Override
-  public void clearLock(String lockName) throws IOException {
-    makeLock(lockName).close();
+  protected Lock makeFSLock(FSDirectory dir, String lockName) {
+    return new NativeFSLock(dir.getDirectory(), lockName);
   }
-}
+  
+  static final class NativeFSLock extends Lock {
 
-class NativeFSLock extends Lock {
+    private FileChannel channel;
+    private FileLock lock;
+    private Path path;
+    private Path lockDir;
+    private static final Set<String> LOCK_HELD = Collections.synchronizedSet(new HashSet<String>());
 
-  private FileChannel channel;
-  private FileLock lock;
-  private Path path;
-  private Path lockDir;
-  private static final Set<String> LOCK_HELD = Collections.synchronizedSet(new HashSet<String>());
 
+    public NativeFSLock(Path lockDir, String lockFileName) {
+      this.lockDir = lockDir;
+      path = lockDir.resolve(lockFileName);
+    }
 
-  public NativeFSLock(Path lockDir, String lockFileName) {
-    this.lockDir = lockDir;
-    path = lockDir.resolve(lockFileName);
-  }
 
+    @Override
+    public synchronized boolean obtain() throws IOException {
 
-  @Override
-  public synchronized boolean obtain() throws IOException {
+      if (lock != null) {
+        // Our instance is already locked:
+        return false;
+      }
 
-    if (lock != null) {
-      // Our instance is already locked:
-      return false;
-    }
-
-    // Ensure that lockDir exists and is a directory.
-    Files.createDirectories(lockDir);
-    try {
-      Files.createFile(path);
-    } catch (IOException ignore) {
-      // we must create the file to have a truly canonical path.
-      // if its already created, we don't care. if it cant be created, it will fail below.
-    }
-    final Path canonicalPath = path.toRealPath();
-    // Make sure nobody else in-process has this lock held
-    // already, and, mark it held if not:
-    // This is a pretty crazy workaround for some documented
-    // but yet awkward JVM behavior:
-    //
-    //   On some systems, closing a channel releases all locks held by the Java virtual machine on the underlying file
-    //   regardless of whether the locks were acquired via that channel or via another channel open on the same file.
-    //   It is strongly recommended that, within a program, a unique channel be used to acquire all locks on any given
-    //   file.
-    //
-    // This essentially means if we close "A" channel for a given file all locks might be released... the odd part
-    // is that we can't re-obtain the lock in the same JVM but from a different process if that happens. Nevertheless
-    // this is super trappy. See LUCENE-5738
-    boolean obtained = false;
-    if (LOCK_HELD.add(canonicalPath.toString())) {
+      // Ensure that lockDir exists and is a directory.
+      Files.createDirectories(lockDir);
       try {
-        channel = FileChannel.open(path, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
+        Files.createFile(path);
+      } catch (IOException ignore) {
+        // we must create the file to have a truly canonical path.
+        // if its already created, we don't care. if it cant be created, it will fail below.
+      }
+      final Path canonicalPath = path.toRealPath();
+      // Make sure nobody else in-process has this lock held
+      // already, and, mark it held if not:
+      // This is a pretty crazy workaround for some documented
+      // but yet awkward JVM behavior:
+      //
+      //   On some systems, closing a channel releases all locks held by the Java virtual machine on the underlying file
+      //   regardless of whether the locks were acquired via that channel or via another channel open on the same file.
+      //   It is strongly recommended that, within a program, a unique channel be used to acquire all locks on any given
+      //   file.
+      //
+      // This essentially means if we close "A" channel for a given file all locks might be released... the odd part
+      // is that we can't re-obtain the lock in the same JVM but from a different process if that happens. Nevertheless
+      // this is super trappy. See LUCENE-5738
+      boolean obtained = false;
+      if (LOCK_HELD.add(canonicalPath.toString())) {
         try {
-          lock = channel.tryLock();
-          obtained = lock != null;
-        } catch (IOException | OverlappingFileLockException e) {
-          // At least on OS X, we will sometimes get an
-          // intermittent "Permission Denied" IOException,
-          // which seems to simply mean "you failed to get
-          // the lock".  But other IOExceptions could be
-          // "permanent" (eg, locking is not supported via
-          // the filesystem).  So, we record the failure
-          // reason here; the timeout obtain (usually the
-          // one calling us) will use this as "root cause"
-          // if it fails to get the lock.
-          failureReason = e;
-        }
-      } finally {
-        if (obtained == false) { // not successful - clear up and move out
-          clearLockHeld(path);
-          final FileChannel toClose = channel;
-          channel = null;
-          IOUtils.closeWhileHandlingException(toClose);
+          channel = FileChannel.open(path, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
+          try {
+            lock = channel.tryLock();
+            obtained = lock != null;
+          } catch (IOException | OverlappingFileLockException e) {
+            // At least on OS X, we will sometimes get an
+            // intermittent "Permission Denied" IOException,
+            // which seems to simply mean "you failed to get
+            // the lock".  But other IOExceptions could be
+            // "permanent" (eg, locking is not supported via
+            // the filesystem).  So, we record the failure
+            // reason here; the timeout obtain (usually the
+            // one calling us) will use this as "root cause"
+            // if it fails to get the lock.
+            failureReason = e;
+          }
+        } finally {
+          if (obtained == false) { // not successful - clear up and move out
+            clearLockHeld(path);
+            final FileChannel toClose = channel;
+            channel = null;
+            IOUtils.closeWhileHandlingException(toClose);
+          }
         }
       }
+      return obtained;
     }
-    return obtained;
-  }
 
-  @Override
-  public synchronized void close() throws IOException {
-    try {
-      if (lock != null) {
-        try {
-          lock.release();
-          lock = null;
-        } finally {
-          clearLockHeld(path);
+    @Override
+    public synchronized void close() throws IOException {
+      try {
+        if (lock != null) {
+          try {
+            lock.release();
+            lock = null;
+          } finally {
+            clearLockHeld(path);
+          }
         }
+      } finally {
+        IOUtils.close(channel);
+        channel = null;
       }
-    } finally {
-      IOUtils.close(channel);
-      channel = null;
     }
-  }
 
-  private static final void clearLockHeld(Path path) throws IOException {
-    path = path.toRealPath();
-    boolean remove = LOCK_HELD.remove(path.toString());
-    assert remove : "Lock was cleared but never marked as held";
-  }
+    private static final void clearLockHeld(Path path) throws IOException {
+      path = path.toRealPath();
+      boolean remove = LOCK_HELD.remove(path.toString());
+      assert remove : "Lock was cleared but never marked as held";
+    }
 
-  @Override
-  public synchronized boolean isLocked() {
-    // The test for is isLocked is not directly possible with native file locks:
-    
-    // First a shortcut, if a lock reference in this instance is available
-    if (lock != null) return true;
-    
-    // Look if lock file is definitely not present; if not, there can definitely be no lock!
-    if (Files.notExists(path)) return false;
-    
-    // Try to obtain and release (if was locked) the lock
-    try {
-      boolean obtained = obtain();
-      if (obtained) close();
-      return !obtained;
-    } catch (IOException ioe) {
-      return false;
-    }    
-  }
+    @Override
+    public synchronized boolean isLocked() {
+      // The test for is isLocked is not directly possible with native file locks:
+      
+      // First a shortcut, if a lock reference in this instance is available
+      if (lock != null) return true;
+      
+      // Look if lock file is definitely not present; if not, there can definitely be no lock!
+      if (Files.notExists(path)) return false;
+      
+      // Try to obtain and release (if was locked) the lock
+      try {
+        boolean obtained = obtain();
+        if (obtained) close();
+        return !obtained;
+      } catch (IOException ioe) {
+        return false;
+      }    
+    }
 
-  @Override
-  public String toString() {
-    return "NativeFSLock@" + path;
+    @Override
+    public String toString() {
+      return "NativeFSLock@" + path;
+    }
   }
+
 }

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/NoLockFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/NoLockFactory.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/NoLockFactory.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/NoLockFactory.java Sun Nov  9 13:08:16 2014
@@ -21,50 +21,45 @@ import java.io.IOException;
 
 /**
  * Use this {@link LockFactory} to disable locking entirely.
- * Only one instance of this lock is created.  You should call {@link
- * #getNoLockFactory()} to get the instance.
+ * This is a singleton, you have to use {@link #INSTANCE}.
  *
  * @see LockFactory
  */
 
-public class NoLockFactory extends LockFactory {
+public final class NoLockFactory extends LockFactory {
 
-  // Single instance returned whenever makeLock is called.
-  private static NoLock singletonLock = new NoLock();
-  private static NoLockFactory singleton = new NoLockFactory();
+  /** The singleton */
+  public static final NoLockFactory INSTANCE = new NoLockFactory();
+  
+  // visible for AssertingLock!
+  static final NoLock SINGLETON_LOCK = new NoLock();
   
   private NoLockFactory() {}
 
-  public static NoLockFactory getNoLockFactory() {
-    return singleton;
-  }
-
-  @Override
-  public Lock makeLock(String lockName) {
-    return singletonLock;
-  }
-
-  @Override
-  public void clearLock(String lockName) {}
-}
-
-class NoLock extends Lock {
   @Override
-  public boolean obtain() throws IOException {
-    return true;
+  public Lock makeLock(Directory dir, String lockName) {
+    return SINGLETON_LOCK;
   }
-
-  @Override
-  public void close() {
-  }
-
-  @Override
-  public boolean isLocked() {
-    return false;
+  
+  private static class NoLock extends Lock {
+    @Override
+    public boolean obtain() throws IOException {
+      return true;
+    }
+
+    @Override
+    public void close() {
+    }
+
+    @Override
+    public boolean isLocked() {
+      return false;
+    }
+
+    @Override
+    public String toString() {
+      return "NoLock";
+    }
   }
 
-  @Override
-  public String toString() {
-    return "NoLock";
-  }
 }

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/RAMDirectory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/RAMDirectory.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/RAMDirectory.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/RAMDirectory.java Sun Nov  9 13:08:16 2014
@@ -33,8 +33,7 @@ import org.apache.lucene.util.Accountabl
 
 /**
  * A memory-resident {@link Directory} implementation.  Locking
- * implementation is by default the {@link SingleInstanceLockFactory}
- * but can be changed with {@link #setLockFactory}.
+ * implementation is by default the {@link SingleInstanceLockFactory}.
  * 
  * <p><b>Warning:</b> This class is not intended to work with huge
  * indexes. Everything beyond several hundred megabytes will waste
@@ -52,17 +51,14 @@ public class RAMDirectory extends BaseDi
   protected final Map<String,RAMFile> fileMap = new ConcurrentHashMap<>();
   protected final AtomicLong sizeInBytes = new AtomicLong();
   
-  // *****
-  // Lock acquisition sequence:  RAMDirectory, then RAMFile
-  // ***** 
-
   /** Constructs an empty {@link Directory}. */
   public RAMDirectory() {
-    try {
-      setLockFactory(new SingleInstanceLockFactory());
-    } catch (IOException e) {
-      // Cannot happen
-    }
+    this(new SingleInstanceLockFactory());
+  }
+
+  /** Constructs an empty {@link Directory} with the given {@link LockFactory}. */
+  public RAMDirectory(LockFactory lockFactory) {
+    super(lockFactory);
   }
 
   /**
@@ -106,11 +102,6 @@ public class RAMDirectory extends BaseDi
   }
 
   @Override
-  public String getLockID() {
-    return "lucene-" + Integer.toHexString(hashCode());
-  }
-  
-  @Override
   public final String[] listAll() {
     ensureOpen();
     // NOTE: this returns a "weakly consistent view". Unless we change Dir API, keep this,
@@ -156,11 +147,6 @@ public class RAMDirectory extends BaseDi
     return Accountables.namedAccountables("file", fileMap);
   }
   
-  @Override
-  public String toString() {
-    return getClass().getSimpleName() + "(id=" + getLockID() + ")";
-  }
-
   /** Removes an existing file in the directory.
    * @throws IOException if the file does not exist
    */

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/SimpleFSDirectory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/SimpleFSDirectory.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/SimpleFSDirectory.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/SimpleFSDirectory.java Sun Nov  9 13:08:16 2014
@@ -37,21 +37,20 @@ public class SimpleFSDirectory extends F
   /** Create a new SimpleFSDirectory for the named location.
    *
    * @param path the path of the directory
-   * @param lockFactory the lock factory to use, or null for the default
-   * ({@link NativeFSLockFactory});
+   * @param lockFactory the lock factory to use
    * @throws IOException if there is a low-level I/O error
    */
   public SimpleFSDirectory(Path path, LockFactory lockFactory) throws IOException {
     super(path, lockFactory);
   }
   
-  /** Create a new SimpleFSDirectory for the named location and {@link NativeFSLockFactory}.
+  /** Create a new SimpleFSDirectory for the named location and {@link FSLockFactory#getDefault()}.
    *
    * @param path the path of the directory
    * @throws IOException if there is a low-level I/O error
    */
   public SimpleFSDirectory(Path path) throws IOException {
-    super(path, null);
+    this(path, FSLockFactory.getDefault());
   }
 
   /** Creates an IndexInput for the file with the given name. */

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/SimpleFSLockFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/SimpleFSLockFactory.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/SimpleFSLockFactory.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/SimpleFSLockFactory.java Sun Nov  9 13:08:16 2014
@@ -56,91 +56,71 @@ import java.nio.file.Path;
  * not working properly in your environment, you can easily
  * test it by using {@link VerifyingLockFactory}, {@link
  * LockVerifyServer} and {@link LockStressTest}.</p>
+ * 
+ * <p>This is a singleton, you have to use {@link #INSTANCE}.
  *
  * @see LockFactory
  */
 
-public class SimpleFSLockFactory extends FSLockFactory {
+public final class SimpleFSLockFactory extends FSLockFactory {
 
   /**
-   * Create a SimpleFSLockFactory instance, with null (unset)
-   * lock directory. When you pass this factory to a {@link FSDirectory}
-   * subclass, the lock directory is automatically set to the
-   * directory itself. Be sure to create one instance for each directory
-   * your create!
+   * Singleton instance
    */
-  public SimpleFSLockFactory() throws IOException {
-    this((Path) null);
-  }
-
-  /**
-   * Instantiate using the provided directory (as a Path instance).
-   * @param lockDir where lock files should be created.
-   */
-  public SimpleFSLockFactory(Path lockDir) throws IOException {
-    setLockDir(lockDir);
-  }
+  public static final SimpleFSLockFactory INSTANCE = new SimpleFSLockFactory();
+  
+  private SimpleFSLockFactory() {}
 
   @Override
-  public Lock makeLock(String lockName) {
-    if (lockPrefix != null) {
-      lockName = lockPrefix + "-" + lockName;
-    }
-    return new SimpleFSLock(lockDir, lockName);
+  protected Lock makeFSLock(FSDirectory dir, String lockName) {
+    return new SimpleFSLock(dir.getDirectory(), lockName);
   }
+  
+  static class SimpleFSLock extends Lock {
 
-  @Override
-  public void clearLock(String lockName) throws IOException {
-    if (lockPrefix != null) {
-      lockName = lockPrefix + "-" + lockName;
-    }
-    Files.deleteIfExists(lockDir.resolve(lockName));
-  }
-}
-
-class SimpleFSLock extends Lock {
+    Path lockFile;
+    Path lockDir;
 
-  Path lockFile;
-  Path lockDir;
+    public SimpleFSLock(Path lockDir, String lockFileName) {
+      this.lockDir = lockDir;
+      lockFile = lockDir.resolve(lockFileName);
+    }
 
-  public SimpleFSLock(Path lockDir, String lockFileName) {
-    this.lockDir = lockDir;
-    lockFile = lockDir.resolve(lockFileName);
-  }
+    @Override
+    public boolean obtain() throws IOException {
+      try {
+        Files.createDirectories(lockDir);
+        Files.createFile(lockFile);
+        return true;
+      } catch (IOException ioe) {
+        // On Windows, on concurrent createNewFile, the 2nd process gets "access denied".
+        // In that case, the lock was not aquired successfully, so return false.
+        // We record the failure reason here; the obtain with timeout (usually the
+        // one calling us) will use this as "root cause" if it fails to get the lock.
+        failureReason = ioe;
+        return false;
+      }
+    }
 
-  @Override
-  public boolean obtain() throws IOException {
-    try {
-      Files.createDirectories(lockDir);
-      Files.createFile(lockFile);
-      return true;
-    } catch (IOException ioe) {
-      // On Windows, on concurrent createNewFile, the 2nd process gets "access denied".
-      // In that case, the lock was not aquired successfully, so return false.
-      // We record the failure reason here; the obtain with timeout (usually the
-      // one calling us) will use this as "root cause" if it fails to get the lock.
-      failureReason = ioe;
-      return false;
+    @Override
+    public void close() throws LockReleaseFailedException {
+      // TODO: wierd that clearLock() throws the raw IOException...
+      try {
+        Files.deleteIfExists(lockFile);
+      } catch (Throwable cause) {
+        throw new LockReleaseFailedException("failed to delete " + lockFile, cause);
+      }
     }
-  }
 
-  @Override
-  public void close() throws LockReleaseFailedException {
-    // TODO: wierd that clearLock() throws the raw IOException...
-    try {
-      Files.deleteIfExists(lockFile);
-    } catch (Throwable cause) {
-      throw new LockReleaseFailedException("failed to delete " + lockFile, cause);
+    @Override
+    public boolean isLocked() {
+      return Files.exists(lockFile);
     }
-  }
 
-  @Override
-  public boolean isLocked() {
-    return Files.exists(lockFile);
+    @Override
+    public String toString() {
+      return "SimpleFSLock@" + lockFile;
+    }
   }
 
-  @Override
-  public String toString() {
-    return "SimpleFSLock@" + lockFile;
-  }
 }

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/SingleInstanceLockFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/SingleInstanceLockFactory.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/SingleInstanceLockFactory.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/SingleInstanceLockFactory.java Sun Nov  9 13:08:16 2014
@@ -31,61 +31,49 @@ import java.util.HashSet;
  * @see LockFactory
  */
 
-public class SingleInstanceLockFactory extends LockFactory {
+public final class SingleInstanceLockFactory extends LockFactory {
 
-  private HashSet<String> locks = new HashSet<>();
+  private final HashSet<String> locks = new HashSet<>();
 
   @Override
-  public Lock makeLock(String lockName) {
-    // We do not use the LockPrefix at all, because the private
-    // HashSet instance effectively scopes the locking to this
-    // single Directory instance.
+  public Lock makeLock(Directory dir, String lockName) {
     return new SingleInstanceLock(locks, lockName);
   }
 
-  @Override
-  public void clearLock(String lockName) throws IOException {
-    synchronized(locks) {
-      if (locks.contains(lockName)) {
-        locks.remove(lockName);
-      }
-    }
-  }
-}
+  private static class SingleInstanceLock extends Lock {
 
-class SingleInstanceLock extends Lock {
+    private final String lockName;
+    private final HashSet<String> locks;
 
-  String lockName;
-  private HashSet<String> locks;
-
-  public SingleInstanceLock(HashSet<String> locks, String lockName) {
-    this.locks = locks;
-    this.lockName = lockName;
-  }
+    public SingleInstanceLock(HashSet<String> locks, String lockName) {
+      this.locks = locks;
+      this.lockName = lockName;
+    }
 
-  @Override
-  public boolean obtain() throws IOException {
-    synchronized(locks) {
-      return locks.add(lockName);
+    @Override
+    public boolean obtain() throws IOException {
+      synchronized(locks) {
+        return locks.add(lockName);
+      }
     }
-  }
 
-  @Override
-  public void close() {
-    synchronized(locks) {
-      locks.remove(lockName);
+    @Override
+    public void close() {
+      synchronized(locks) {
+        locks.remove(lockName);
+      }
     }
-  }
 
-  @Override
-  public boolean isLocked() {
-    synchronized(locks) {
-      return locks.contains(lockName);
+    @Override
+    public boolean isLocked() {
+      synchronized(locks) {
+        return locks.contains(lockName);
+      }
     }
-  }
 
-  @Override
-  public String toString() {
-    return super.toString() + ": " + lockName;
+    @Override
+    public String toString() {
+      return super.toString() + ": " + lockName;
+    }
   }
 }

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/VerifyingLockFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/VerifyingLockFactory.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/VerifyingLockFactory.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/store/VerifyingLockFactory.java Sun Nov  9 13:08:16 2014
@@ -35,7 +35,7 @@ import java.io.OutputStream;
  * @see LockStressTest
  */
 
-public class VerifyingLockFactory extends LockFactory {
+public final class VerifyingLockFactory extends LockFactory {
 
   final LockFactory lf;
   final InputStream in;
@@ -94,13 +94,7 @@ public class VerifyingLockFactory extend
   }
 
   @Override
-  public synchronized Lock makeLock(String lockName) {
-    return new CheckedLock(lf.makeLock(lockName));
-  }
-
-  @Override
-  public synchronized void clearLock(String lockName)
-    throws IOException {
-    lf.clearLock(lockName);
+  public Lock makeLock(Directory dir, String lockName) {
+    return new CheckedLock(lf.makeLock(dir, lockName));
   }
 }

Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/util/CommandLineUtil.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/util/CommandLineUtil.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/util/CommandLineUtil.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/util/CommandLineUtil.java Sun Nov  9 13:08:16 2014
@@ -23,6 +23,8 @@ import java.nio.file.Path;
 
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.FSDirectory;
+import org.apache.lucene.store.FSLockFactory;
+import org.apache.lucene.store.LockFactory;
 
 /**
  * Class containing some useful methods used by command line tools 
@@ -35,15 +37,26 @@ public final class CommandLineUtil {
   }
   
   /**
-   * Creates a specific FSDirectory instance starting from its class name
+   * Creates a specific FSDirectory instance starting from its class name, using the default lock factory
    * @param clazzName The name of the FSDirectory class to load
    * @param path The path to be used as parameter constructor
    * @return the new FSDirectory instance
    */
   public static FSDirectory newFSDirectory(String clazzName, Path path) {
+    return newFSDirectory(clazzName, path, FSLockFactory.getDefault());
+  }
+  
+  /**
+   * Creates a specific FSDirectory instance starting from its class name
+   * @param clazzName The name of the FSDirectory class to load
+   * @param path The path to be used as parameter constructor
+   * @param lf The lock factory to be used
+   * @return the new FSDirectory instance
+   */
+  public static FSDirectory newFSDirectory(String clazzName, Path path, LockFactory lf) {
     try {
       final Class<? extends FSDirectory> clazz = loadFSDirectoryClass(clazzName);
-      return newFSDirectory(clazz, path);
+      return newFSDirectory(clazz, path, lf);
     } catch (ClassNotFoundException e) {
       throw new IllegalArgumentException(FSDirectory.class.getSimpleName()
           + " implementation not found: " + clazzName, e);
@@ -103,10 +116,26 @@ public final class CommandLineUtil {
    * @throws InvocationTargetException If the constructor throws an exception
    */
   public static FSDirectory newFSDirectory(Class<? extends FSDirectory> clazz, Path path) 
-      throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
+      throws ReflectiveOperationException {
+    return newFSDirectory(clazz, path, FSLockFactory.getDefault());
+  }
+  
+  /**
+   * Creates a new specific FSDirectory instance
+   * @param clazz The class of the object to be created
+   * @param path The file to be used as parameter constructor
+   * @param lf The lock factory to be used
+   * @return The new FSDirectory instance
+   * @throws NoSuchMethodException If the Directory does not have a constructor that takes <code>Path</code>.
+   * @throws InstantiationException If the class is abstract or an interface.
+   * @throws IllegalAccessException If the constructor does not have public visibility.
+   * @throws InvocationTargetException If the constructor throws an exception
+   */
+  public static FSDirectory newFSDirectory(Class<? extends FSDirectory> clazz, Path path, LockFactory lf) 
+      throws ReflectiveOperationException {
     // Assuming every FSDirectory has a ctor(Path):
-    Constructor<? extends FSDirectory> ctor = clazz.getConstructor(Path.class);
-    return ctor.newInstance(path);
+    Constructor<? extends FSDirectory> ctor = clazz.getConstructor(Path.class, LockFactory.class);
+    return ctor.newInstance(path, lf);
   }
   
 }

Modified: lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestCrash.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestCrash.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestCrash.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestCrash.java Sun Nov  9 13:08:16 2014
@@ -31,12 +31,10 @@ import org.apache.lucene.util.LuceneTest
 public class TestCrash extends LuceneTestCase {
 
   private IndexWriter initIndex(Random random, boolean initialCommit) throws IOException {
-    return initIndex(random, newMockDirectory(random), initialCommit, true);
+    return initIndex(random, newMockDirectory(random, NoLockFactory.INSTANCE), initialCommit, true);
   }
 
   private IndexWriter initIndex(Random random, MockDirectoryWrapper dir, boolean initialCommit, boolean commitOnClose) throws IOException {
-    dir.setLockFactory(NoLockFactory.getNoLockFactory());
-
     IndexWriter writer  = new IndexWriter(dir, newIndexWriterConfig(new MockAnalyzer(random))
         .setMaxBufferedDocs(10).setMergeScheduler(new ConcurrentMergeScheduler()).setCommitOnClose(commitOnClose));
     ((ConcurrentMergeScheduler) writer.getConfig().getMergeScheduler()).setSuppressExceptions();
@@ -187,7 +185,7 @@ public class TestCrash extends LuceneTes
 
   public void testCrashAfterCloseNoWait() throws IOException {
     Random random = random();
-    MockDirectoryWrapper dir = newMockDirectory(random);
+    MockDirectoryWrapper dir = newMockDirectory(random, NoLockFactory.INSTANCE);
     IndexWriter writer = initIndex(random, dir, false, false);
 
     try {

Modified: lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestCrashCausesCorruptIndex.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestCrashCausesCorruptIndex.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestCrashCausesCorruptIndex.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestCrashCausesCorruptIndex.java Sun Nov  9 13:08:16 2014
@@ -150,7 +150,6 @@ public class TestCrashCausesCorruptIndex
 
     public CrashAfterCreateOutput(Directory realDirectory) throws IOException {
       super(realDirectory);
-      setLockFactory(realDirectory.getLockFactory());
     }
         
     public void setCrashAfterCreateOutput(String name) {

Modified: lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestDoc.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestDoc.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestDoc.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestDoc.java Sun Nov  9 13:08:16 2014
@@ -38,6 +38,7 @@ import org.apache.lucene.document.TextFi
 import org.apache.lucene.index.IndexWriterConfig.OpenMode;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.FSLockFactory;
 import org.apache.lucene.store.IOContext;
 import org.apache.lucene.store.MockDirectoryWrapper;
 import org.apache.lucene.store.TrackingDirectoryWrapper;
@@ -111,7 +112,7 @@ public class TestDoc extends LuceneTestC
       StringWriter sw = new StringWriter();
       PrintWriter out = new PrintWriter(sw, true);
       
-      Directory directory = newFSDirectory(indexDir, null);
+      Directory directory = newFSDirectory(indexDir);
 
       if (directory instanceof MockDirectoryWrapper) {
         // We create unreferenced files (we don't even write
@@ -155,7 +156,7 @@ public class TestDoc extends LuceneTestC
       sw = new StringWriter();
       out = new PrintWriter(sw, true);
 
-      directory = newFSDirectory(indexDir, null);
+      directory = newFSDirectory(indexDir);
 
       if (directory instanceof MockDirectoryWrapper) {
         // We create unreferenced files (we don't even write

Modified: lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestFieldsReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestFieldsReader.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestFieldsReader.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestFieldsReader.java Sun Nov  9 13:08:16 2014
@@ -27,15 +27,13 @@ import org.apache.lucene.document.Docume
 import org.apache.lucene.document.DocumentStoredFieldVisitor;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.index.IndexWriterConfig.OpenMode;
-import org.apache.lucene.store.BaseDirectory;
 import org.apache.lucene.store.BufferedIndexInput;
 import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.FilterDirectory;
 import org.apache.lucene.store.IOContext;
 import org.apache.lucene.store.IndexInput;
-import org.apache.lucene.store.IndexOutput;
 import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.LuceneTestCase;
-import org.apache.lucene.util.TestUtil;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 
@@ -111,55 +109,18 @@ public class TestFieldsReader extends Lu
   }
 
 
-  public class FaultyFSDirectory extends BaseDirectory {
-    Directory fsDir;
+  public class FaultyFSDirectory extends FilterDirectory {
     AtomicBoolean doFail = new AtomicBoolean();
 
-    public FaultyFSDirectory(Path dir) {
-      fsDir = newFSDirectory(dir);
-      lockFactory = fsDir.getLockFactory();
+    public FaultyFSDirectory(Directory fsDir) {
+      super(fsDir);
     }
     
     @Override
     public IndexInput openInput(String name, IOContext context) throws IOException {
-      return new FaultyIndexInput(doFail, fsDir.openInput(name, context));
+      return new FaultyIndexInput(doFail, in.openInput(name, context));
     }
     
-    @Override
-    public String[] listAll() throws IOException {
-      return fsDir.listAll();
-    }
-    
-    @Override
-    public void deleteFile(String name) throws IOException {
-      fsDir.deleteFile(name);
-    }
-    
-    @Override
-    public long fileLength(String name) throws IOException {
-      return fsDir.fileLength(name);
-    }
-    
-    @Override
-    public IndexOutput createOutput(String name, IOContext context) throws IOException {
-      return fsDir.createOutput(name, context);
-    }
-    
-    @Override
-    public void sync(Collection<String> names) throws IOException {
-      fsDir.sync(names);
-    }
-
-    @Override
-    public void renameFile(String source, String dest) throws IOException {
-      fsDir.renameFile(source, dest);
-    }
-
-    @Override
-    public void close() throws IOException {
-      fsDir.close();
-    }
-
     public void startFailing() {
       doFail.set(true);
     }
@@ -228,7 +189,8 @@ public class TestFieldsReader extends Lu
     Path indexDir = createTempDir("testfieldswriterexceptions");
 
     try {
-      FaultyFSDirectory dir = new FaultyFSDirectory(indexDir);
+      Directory fsDir = newFSDirectory(indexDir);
+      FaultyFSDirectory dir = new FaultyFSDirectory(fsDir);
       IndexWriterConfig iwc = newIndexWriterConfig(new MockAnalyzer(random()))
                                 .setOpenMode(OpenMode.CREATE);
       IndexWriter writer = new IndexWriter(dir, iwc);

Modified: lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java?rev=1637674&r1=1637673&r2=1637674&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java Sun Nov  9 13:08:16 2014
@@ -65,14 +65,11 @@ import org.apache.lucene.store.BaseDirec
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.IOContext;
 import org.apache.lucene.store.IndexOutput;
-import org.apache.lucene.store.Lock;
-import org.apache.lucene.store.LockFactory;
 import org.apache.lucene.store.LockObtainFailedException;
 import org.apache.lucene.store.MockDirectoryWrapper;
 import org.apache.lucene.store.NoLockFactory;
 import org.apache.lucene.store.RAMDirectory;
 import org.apache.lucene.store.SimpleFSLockFactory;
-import org.apache.lucene.store.SingleInstanceLockFactory;
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.Constants;
@@ -516,45 +513,6 @@ public class TestIndexWriter extends Luc
       dir.close();
     }
 
-    // Make sure that a Directory implementation that does
-    // not use LockFactory at all (ie overrides makeLock and
-    // implements its own private locking) works OK.  This
-    // was raised on java-dev as loss of backwards
-    // compatibility.
-    public void testNullLockFactory() throws IOException {
-
-      final class MyRAMDirectory extends MockDirectoryWrapper {
-        private LockFactory myLockFactory;
-        MyRAMDirectory(Directory delegate) {
-          super(random(), delegate);
-          lockFactory = null;
-          myLockFactory = new SingleInstanceLockFactory();
-        }
-        @Override
-        public Lock makeLock(String name) {
-          return myLockFactory.makeLock(name);
-        }
-      }
-
-      Directory dir = new MyRAMDirectory(new RAMDirectory());
-      IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(new MockAnalyzer(random())));
-      for (int i = 0; i < 100; i++) {
-        addDoc(writer);
-      }
-      writer.close();
-      Term searchTerm = new Term("content", "aaa");
-      IndexReader reader = DirectoryReader.open(dir);
-      IndexSearcher searcher = newSearcher(reader);
-      ScoreDoc[] hits = searcher.search(new TermQuery(searchTerm), null, 1000).scoreDocs;
-      assertEquals("did not get right number of hits", 100, hits.length);
-      reader.close();
-
-      writer = new IndexWriter(dir, newIndexWriterConfig(new MockAnalyzer(random()))
-        .setOpenMode(OpenMode.CREATE));
-      writer.close();
-      dir.close();
-    }
-
     public void testFlushWithNoMerging() throws IOException {
       Directory dir = newDirectory();
       IndexWriter writer = new IndexWriter(
@@ -1464,7 +1422,7 @@ public class TestIndexWriter extends Luc
     // Tests that if FSDir is opened w/ a NoLockFactory (or SingleInstanceLF),
     // then IndexWriter ctor succeeds. Previously (LUCENE-2386) it failed
     // when listAll() was called in IndexFileDeleter.
-    Directory dir = newFSDirectory(createTempDir("emptyFSDirNoLock"), NoLockFactory.getNoLockFactory());
+    Directory dir = newFSDirectory(createTempDir("emptyFSDirNoLock"), NoLockFactory.INSTANCE);
     new IndexWriter(dir, newIndexWriterConfig(new MockAnalyzer(random()))).close();
     dir.close();
   }
@@ -1535,8 +1493,7 @@ public class TestIndexWriter extends Luc
   }
 
   public void testNoSegmentFile() throws IOException {
-    BaseDirectoryWrapper dir = newDirectory();
-    dir.setLockFactory(NoLockFactory.getNoLockFactory());
+    BaseDirectoryWrapper dir = newDirectory(random(), NoLockFactory.INSTANCE);
     IndexWriter w = new IndexWriter(dir, newIndexWriterConfig(new MockAnalyzer(random()))
                                            .setMaxBufferedDocs(2));
 
@@ -1778,11 +1735,10 @@ public class TestIndexWriter extends Luc
   }
 
   public void testWhetherDeleteAllDeletesWriteLock() throws Exception {
-    Directory d = newFSDirectory(createTempDir("TestIndexWriter.testWhetherDeleteAllDeletesWriteLock"));
     // Must use SimpleFSLockFactory... NativeFSLockFactory
     // somehow "knows" a lock is held against write.lock
     // even if you remove that file:
-    d.setLockFactory(new SimpleFSLockFactory());
+    Directory d = newFSDirectory(createTempDir("TestIndexWriter.testWhetherDeleteAllDeletesWriteLock"), SimpleFSLockFactory.INSTANCE);
     RandomIndexWriter w1 = new RandomIndexWriter(random(), d);
     w1.deleteAll();
     try {