|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| NativeFSLockFactory | Line # 61 | 32 | 16 | 62.5% |
0.625
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
| NativeFSLock | Line # 173 | 59 | 22 | 62.9% |
0.6292135
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (4) | |||
| Result | |||
|
0.6137931
|
org.apache.lucene.store.TestLockFactory.testStressLocksNativeFSLockFactory
org.apache.lucene.store.TestLockFactory.testStressLocksNativeFSLockFactory
|
1 PASS | |
|
0.57931036
|
org.apache.lucene.store.TestLockFactory.testNativeFSLockFactoryPrefix
org.apache.lucene.store.TestLockFactory.testNativeFSLockFactoryPrefix
|
1 PASS | |
|
0.5241379
|
org.apache.lucene.store.TestLockFactory.testNativeFSLockFactory
org.apache.lucene.store.TestLockFactory.testNativeFSLockFactory
|
1 PASS | |
|
0.03448276
|
org.apache.lucene.store.TestLockFactory.testDefaultFSLockFactoryPrefix
org.apache.lucene.store.TestLockFactory.testDefaultFSLockFactoryPrefix
|
1 PASS | |
| 1 | package org.apache.lucene.store; | |
| 2 | ||
| 3 | /** | |
| 4 | * Copyright 2006 The Apache Software Foundation | |
| 5 | * | |
| 6 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 7 | * you may not use this file except in compliance with the License. | |
| 8 | * You may obtain a copy of the License at | |
| 9 | * | |
| 10 | * http://www.apache.org/licenses/LICENSE-2.0 | |
| 11 | * | |
| 12 | * Unless required by applicable law or agreed to in writing, software | |
| 13 | * distributed under the License is distributed on an "AS IS" BASIS, | |
| 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 15 | * See the License for the specific language governing permissions and | |
| 16 | * limitations under the License. | |
| 17 | */ | |
| 18 | ||
| 19 | import java.nio.channels.FileChannel; | |
| 20 | import java.nio.channels.FileLock; | |
| 21 | import java.io.File; | |
| 22 | import java.io.RandomAccessFile; | |
| 23 | import java.io.IOException; | |
| 24 | import java.util.HashSet; | |
| 25 | import java.util.Random; | |
| 26 | ||
| 27 | /** | |
| 28 | * Implements {@link LockFactory} using native OS file locks | |
| 29 | * (available through java.nio.*). Note that for certain | |
| 30 | * filesystems native locks are possible but must be | |
| 31 | * explicity configured and enabled (and may be disabled by | |
| 32 | * default). For example, for NFS servers there sometimes | |
| 33 | * must be a separate lockd process running, and other | |
| 34 | * configuration may be required such as running the server | |
| 35 | * in kernel mode. Other filesystems may not even support | |
| 36 | * native OS locks in which case you must use a different | |
| 37 | * {@link LockFactory} implementation. | |
| 38 | * | |
| 39 | * <p>The advantage of this lock factory over | |
| 40 | * {@link SimpleFSLockFactory} is that the locks should be | |
| 41 | * "correct", whereas {@link SimpleFSLockFactory} uses | |
| 42 | * java.io.File.createNewFile which | |
| 43 | * <a target="_top" href="http://java.sun.com/j2se/1.4.2/docs/api/java/io/File.html#createNewFile()">has warnings</a> about not | |
| 44 | * using it for locking. Furthermore, if the JVM crashes, | |
| 45 | * the OS will free any held locks, whereas | |
| 46 | * {@link SimpleFSLockFactory} will keep the locks held, requiring | |
| 47 | * manual removal before re-running Lucene.</p> | |
| 48 | * | |
| 49 | * <p>Note that, unlike {@link SimpleFSLockFactory}, the existence of | |
| 50 | * leftover lock files in the filesystem on exiting the JVM | |
| 51 | * is fine because the OS will free the locks held against | |
| 52 | * these files even though the files still remain.</p> | |
| 53 | * | |
| 54 | * <p>Native locks file names have the substring "-n-", which | |
| 55 | * you can use to differentiate them from lock files created | |
| 56 | * by {@link SimpleFSLockFactory}.</p> | |
| 57 | * | |
| 58 | * @see LockFactory | |
| 59 | */ | |
| 60 | ||
| 61 | public class NativeFSLockFactory extends LockFactory { | |
| 62 | ||
| 63 | /** | |
| 64 | * Directory specified by <code>org.apache.lucene.lockDir</code> | |
| 65 | * system property. If that is not set, then <code>java.io.tmpdir</code> | |
| 66 | * system property is used. | |
| 67 | */ | |
| 68 | ||
| 69 | public static final String LOCK_DIR = | |
| 70 | System.getProperty("org.apache.lucene.lockDir", | |
| 71 | System.getProperty("java.io.tmpdir")); | |
| 72 | ||
| 73 | private File lockDir; | |
| 74 | ||
| 75 | // Simple test to verify locking system is "working". On | |
| 76 | // NFS, if it's misconfigured, you can hit long (35 | |
| 77 | // second) timeouts which cause Lock.obtain to take far | |
| 78 | // too long (it assumes the obtain() call takes zero | |
| 79 | // time). Since it's a configuration problem, we test up | |
| 80 | // front once on creating the LockFactory: | |
| 81 | 5 |
private void acquireTestLock() throws IOException { |
| 82 | 5 | String randomLockName = "lucene-" + Long.toString(new Random().nextInt(), Character.MAX_RADIX) + "-test.lock"; |
| 83 | ||
| 84 | 5 | Lock l = makeLock(randomLockName); |
| 85 | 5 | try { |
| 86 | 5 | l.obtain(); |
| 87 | } catch (IOException e) { | |
| 88 | 0 | IOException e2 = new IOException("Failed to acquire random test lock; please verify filesystem for lock directory '" + lockDir + "' supports locking"); |
| 89 | 0 | e2.initCause(e); |
| 90 | 0 | throw e2; |
| 91 | } | |
| 92 | ||
| 93 | 5 | l.release(); |
| 94 | } | |
| 95 | ||
| 96 | /** | |
| 97 | * Create a NativeFSLockFactory instance, storing lock | |
| 98 | * files into the default LOCK_DIR: | |
| 99 | * <code>org.apache.lucene.lockDir</code> system property, | |
| 100 | * or (if that is null) then the | |
| 101 | * <code>java.io.tmpdir</code> system property. | |
| 102 | */ | |
| 103 | 5 |
public NativeFSLockFactory() throws IOException { |
| 104 | 5 | this(new File(LOCK_DIR)); |
| 105 | } | |
| 106 | ||
| 107 | /** | |
| 108 | * Create a NativeFSLockFactory instance, storing lock | |
| 109 | * files into the specified lockDirName: | |
| 110 | * | |
| 111 | * @param lockDirName where lock files are created. | |
| 112 | */ | |
| 113 | 0 |
public NativeFSLockFactory(String lockDirName) throws IOException { |
| 114 | 0 | this(new File(lockDirName)); |
| 115 | } | |
| 116 | ||
| 117 | /** | |
| 118 | * Create a NativeFSLockFactory instance, storing lock | |
| 119 | * files into the specified lockDir: | |
| 120 | * | |
| 121 | * @param lockDir where lock files are created. | |
| 122 | */ | |
| 123 | 5 |
public NativeFSLockFactory(File lockDir) throws IOException { |
| 124 | ||
| 125 | 5 | this.lockDir = lockDir; |
| 126 | ||
| 127 | // Ensure that lockDir exists and is a directory. | |
| 128 | 5 | if (!lockDir.exists()) { |
| 129 | 0 | if (!lockDir.mkdirs()) |
| 130 | 0 | throw new IOException("Cannot create directory: " + |
| 131 | lockDir.getAbsolutePath()); | |
| 132 | 5 | } else if (!lockDir.isDirectory()) { |
| 133 | 0 | throw new IOException("Found regular file where directory expected: " + |
| 134 | lockDir.getAbsolutePath()); | |
| 135 | } | |
| 136 | ||
| 137 | 5 | acquireTestLock(); |
| 138 | } | |
| 139 | ||
| 140 | 531 |
public synchronized Lock makeLock(String lockName) { |
| 141 | 531 | String fullName; |
| 142 | 531 | if (lockPrefix.equals("")) { |
| 143 | 5 | fullName = lockName; |
| 144 | } else { | |
| 145 | 526 | fullName = lockPrefix + "-n-" + lockName; |
| 146 | } | |
| 147 | ||
| 148 | 531 | return new NativeFSLock(lockDir, fullName); |
| 149 | } | |
| 150 | ||
| 151 | 3 |
public void clearAllLocks() throws IOException { |
| 152 | // Note that this isn't strictly required anymore | |
| 153 | // because the existence of these files does not mean | |
| 154 | // they are locked, but, still do this in case people | |
| 155 | // really want to see the files go away: | |
| 156 | 3 | if (lockDir.exists()) { |
| 157 | 3 | String[] files = lockDir.list(); |
| 158 | 3 | if (files == null) |
| 159 | 0 | throw new IOException("Cannot read lock directory " + |
| 160 | lockDir.getAbsolutePath()); | |
| 161 | 3 | String prefix = lockPrefix + "-n-"; |
| 162 | 34785 | for (int i = 0; i < files.length; i++) { |
| 163 | 34782 | if (files[i].startsWith(prefix)) { |
| 164 | 0 | File lockFile = new File(lockDir, files[i]); |
| 165 | 0 | if (!lockFile.delete()) |
| 166 | 0 | throw new IOException("Cannot delete " + lockFile); |
| 167 | } | |
| 168 | } | |
| 169 | } | |
| 170 | } | |
| 171 | }; | |
| 172 | ||
| 173 | class N | |