Clover Coverage Report
Coverage timestamp: Fri May 9 2008 10:54:27 EST
../../../../img/srcFileCovDistChart7.png 63% of files have more coverage
91   340   38   7.58
42   185   0.42   6
12     3.17  
2    
 
  NativeFSLockFactory       Line # 61 32 16 62.5% 0.625
  NativeFSLock       Line # 173 59 22 62.9% 0.6292135
 
  (4)
 
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 toggle 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 toggle 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 toggle 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 toggle 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 toggle 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 toggle 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