mirror of https://github.com/apache/lucene.git
Put lock files in /tmp instead of with the index.
git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@149983 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7d50426c4c
commit
1c8db6cfd0
|
@ -7,6 +7,11 @@ $Id$
|
|||
1. Added getFieldNames(boolean) to IndexReader, SegmentReader, and
|
||||
SegmentsReader. (Julien Nioche via otis)
|
||||
|
||||
2. Changed file locking to place lock files in
|
||||
System.getProperty("java.io.tmpdir"), where all users are
|
||||
permitted to write files. This way folks can open and correctly
|
||||
lock indexes which are read-only to them.
|
||||
|
||||
|
||||
1.3 RC1
|
||||
|
||||
|
|
|
@ -335,7 +335,10 @@ public abstract class IndexReader {
|
|||
* @throws IOException if there is a problem with accessing the index
|
||||
*/
|
||||
public static boolean isLocked(Directory directory) throws IOException {
|
||||
return directory.fileExists("write.lock");
|
||||
return
|
||||
directory.makeLock("write.lock").isLocked() ||
|
||||
directory.makeLock("commit.lock").isLocked();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -345,7 +348,7 @@ public abstract class IndexReader {
|
|||
* @throws IOException if there is a problem with accessing the index
|
||||
*/
|
||||
public static boolean isLocked(String directory) throws IOException {
|
||||
return (new File(directory, "write.lock")).exists();
|
||||
return isLocked(FSDirectory.getDirectory(directory, false));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -356,7 +359,7 @@ public abstract class IndexReader {
|
|||
* currently accessing this index.
|
||||
*/
|
||||
public static void unlock(Directory directory) throws IOException {
|
||||
directory.deleteFile("write.lock");
|
||||
directory.deleteFile("commit.lock");
|
||||
directory.makeLock("write.lock").release();
|
||||
directory.makeLock("commit.lock").release();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,8 @@ import java.io.RandomAccessFile;
|
|||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.Hashtable;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import org.apache.lucene.util.Constants;
|
||||
|
||||
|
@ -84,6 +86,16 @@ public final class FSDirectory extends Directory {
|
|||
private static final boolean DISABLE_LOCKS =
|
||||
Boolean.getBoolean("disableLuceneLocks") || Constants.JAVA_1_1;
|
||||
|
||||
private static MessageDigest DIGESTER;
|
||||
|
||||
static {
|
||||
try {
|
||||
DIGESTER = MessageDigest.getInstance("MD5");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/** A buffer optionally used in renameTo method */
|
||||
private byte[] buffer = null;
|
||||
|
||||
|
@ -268,6 +280,12 @@ public final class FSDirectory extends Directory {
|
|||
return new FSInputStream(new File(directory, name));
|
||||
}
|
||||
|
||||
/**
|
||||
* So we can do some byte-to-hexchar conversion below
|
||||
*/
|
||||
private static final char[] HEX_DIGITS =
|
||||
{'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
|
||||
|
||||
/** Constructs a {@link Lock} with the specified name. Locks are implemented
|
||||
* with {@link File#createNewFile() }.
|
||||
*
|
||||
|
@ -280,7 +298,32 @@ public final class FSDirectory extends Directory {
|
|||
* @return an instance of <code>Lock</code> holding the lock
|
||||
*/
|
||||
public final Lock makeLock(String name) {
|
||||
final File lockFile = new File(directory, name);
|
||||
// the fully-qualified file name which uniquely identifies this lock
|
||||
String fullName;
|
||||
try {
|
||||
fullName = new File(directory, name).getCanonicalPath();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e.toString());
|
||||
}
|
||||
|
||||
// hash full name to create the tmp file name
|
||||
byte digest[];
|
||||
synchronized (DIGESTER) {
|
||||
digest = DIGESTER.digest(fullName.getBytes());
|
||||
}
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("lucene-");
|
||||
for (int i = 0; i < digest.length; i++) {
|
||||
int b = digest[i];
|
||||
buf.append(HEX_DIGITS[(b >> 4) & 0xf]);
|
||||
buf.append(HEX_DIGITS[b & 0xf]);
|
||||
}
|
||||
buf.append(".lock");
|
||||
|
||||
// make the lock file in tmp, where anyone can create files.
|
||||
final File lockFile = new File(System.getProperty("java.io.tmpdir"),
|
||||
buf.toString());
|
||||
|
||||
return new Lock() {
|
||||
public boolean obtain() throws IOException {
|
||||
if (DISABLE_LOCKS)
|
||||
|
@ -292,6 +335,12 @@ public final class FSDirectory extends Directory {
|
|||
return;
|
||||
lockFile.delete();
|
||||
}
|
||||
public boolean isLocked() {
|
||||
if (DISABLE_LOCKS)
|
||||
return false;
|
||||
return lockFile.exists();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Lock@" + lockFile;
|
||||
}
|
||||
|
|
|
@ -79,6 +79,11 @@ public abstract class Lock {
|
|||
/** Release exclusive access. */
|
||||
public abstract void release();
|
||||
|
||||
/** Returns true if the resource is currently locked. Note that one must
|
||||
* still call {@link #obtain()} before using the resource. */
|
||||
public abstract boolean isLocked();
|
||||
|
||||
|
||||
/** Utility class for executing code with exclusive access. */
|
||||
public abstract static class With {
|
||||
private Lock lock;
|
||||
|
|
|
@ -199,6 +199,9 @@ public final class RAMDirectory extends Directory {
|
|||
public void release() {
|
||||
deleteFile(name);
|
||||
}
|
||||
public boolean isLocked() {
|
||||
return fileExists(name);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -164,6 +164,8 @@ class ThreadSafetyTest {
|
|||
add = true;
|
||||
}
|
||||
|
||||
IndexReader.unlock(FSDirectory.getDirectory("index", false));
|
||||
|
||||
if (!readOnly) {
|
||||
IndexWriter writer = new IndexWriter("index", ANALYZER, !add);
|
||||
|
||||
|
|
Loading…
Reference in New Issue