[prev in list] [next in list] [prev in thread] [next in thread] 

List:       lucene-dev
Subject:    [jira] Closed: (LUCENE-84) Enhanced FSDirectory that allow lock disable via API
From:       "Otis Gospodnetic (JIRA)" <jira () apache ! org>
Date:       2005-09-26 16:58:55
Message-ID: 373984734.1127753935418.JavaMail.jira () ajax ! apache ! org
[Download RAW message or body]

     [ http://issues.apache.org/jira/browse/LUCENE-84?page=all ]
     
Otis Gospodnetic closed LUCENE-84:
----------------------------------


> Enhanced FSDirectory that allow lock disable via API
> ----------------------------------------------------
>
>          Key: LUCENE-84
>          URL: http://issues.apache.org/jira/browse/LUCENE-84
>      Project: Lucene - Java
>         Type: Improvement
>   Components: Store
>     Versions: CVS Nightly - Specify date in submission
>  Environment: Operating System: All
> Platform: PC
>     Reporter: John Methot
>     Assignee: Otis Gospodnetic
>     Priority: Minor
>      Fix For: 1.9
>  Attachments: FSDirectory.java, FSDirectory.java
>
> Below is a new version of FSDirectory.java.  It is based on 1/30/2003 source.
> I have added one new version each of getDirectory(File) and getDirectory
> (String). They take a new third argument 'boolean useLocks'.
> The previous 'private static final boolean DISABLE_LOCKS' has been changed 
> to 'private static boolean _disableLocks' and is initialized to false. I also 
> added a new method 'private boolean locksDisabledByProp' that checks 
> the 'disableLuceneLocks' system property.
> Method makeLock now checks the static _disableLocks as the first term in an OR 
> clause, the second of which is a call to locksDisabledByProp. This allows use 
> in an applet that does not have write access to the local filesystem, and when 
> the API is used in that way prevents the query of the system property that is 
> also disallowed in an applet by default (at least in Mozilla/Netscape).
> From my applet, I can now invoke:
> Searcher searcher = new IndexSearcher(
>       IndexReader.open(FSDirectory.getDirectory(indexFile, false, false)));
> and I get an IndexSearcher that will work in the applet with no special 
> permissions other than applet JAR signing.
> Obviously, email me (jmethot@bea.com) if you have any questions.
> ************************* FSDirectory.java *******************************
> package org.apache.lucene.store;
> /* ====================================================================
>  * The Apache Software License, Version 1.1
>  *
>  * Copyright (c) 2001 The Apache Software Foundation.  All rights
>  * reserved.
>  *
>  * Redistribution and use in source and binary forms, with or without
>  * modification, are permitted provided that the following conditions
>  * are met:
>  *
>  * 1. Redistributions of source code must retain the above copyright
>  *    notice, this list of conditions and the following disclaimer.
>  *
>  * 2. Redistributions in binary form must reproduce the above copyright
>  *    notice, this list of conditions and the following disclaimer in
>  *    the documentation and/or other materials provided with the
>  *    distribution.
>  *
>  * 3. The end-user documentation included with the redistribution,
>  *    if any, must include the following acknowledgment:
>  *       "This product includes software developed by the
>  *        Apache Software Foundation (http://www.apache.org/)."
>  *    Alternately, this acknowledgment may appear in the software itself,
>  *    if and wherever such third-party acknowledgments normally appear.
>  *
>  * 4. The names "Apache" and "Apache Software Foundation" and
>  *    "Apache Lucene" must not be used to endorse or promote products
>  *    derived from this software without prior written permission. For
>  *    written permission, please contact apache@apache.org.
>  *
>  * 5. Products derived from this software may not be called "Apache",
>  *    "Apache Lucene", nor may "Apache" appear in their name, without
>  *    prior written permission of the Apache Software Foundation.
>  *
>  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
>  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
>  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
>  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
>  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
>  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
>  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>  * SUCH DAMAGE.
>  * ====================================================================
>  *
>  * This software consists of voluntary contributions made by many
>  * individuals on behalf of the Apache Software Foundation.  For more
>  * information on the Apache Software Foundation, please see
>  * <http://www.apache.org/>.
>  */
> import java.io.IOException;
> import java.io.File;
> import java.io.RandomAccessFile;
> import java.util.Hashtable;
> import org.apache.lucene.util.Constants;
> /**
>  * Straightforward implementation of {@link Directory} as a directory of files.
>  * <p>If the system property 'disableLuceneLocks' has the String value of
>  * "true", lock creation will be disabled.
>  *
>  * @see Directory
>  * @author Doug Cutting
>  */
> public final class FSDirectory extends Directory {
>   /** This cache of directories ensures that there is a unique Directory
>    * instance per path, so that synchronization on the Directory can be used to
>    * synchronize access between readers and writers.
>    *
>    * This should be a WeakHashMap, so that entries can be GC'd, but that would
>    * require Java 1.2.  Instead we use refcounts...  */
>   private static final Hashtable DIRECTORIES = new Hashtable();
>   private static boolean _disableLocks = false;
>   private boolean locksDisabledByProp()
>   {
>       return Boolean.getBoolean("disableLuceneLocks") || Constants.JAVA_1_1;
>   }
>   /** Returns the directory instance for the named location, with option of
>    *  disabled locking.
>    *
>    * <p>Directories are cached, so that, for a given canonical path, the same
>    * FSDirectory instance will always be returned.  This permits
>    * synchronization on directories.
>    *
>    * @param path the path to the directory.
>    * @param create if true, create, or erase any existing contents.
>    * @param useLocks if false, don't use locks during index reads. Useful in
>    *                 read-only filesystems or from applets.
>    * @return the FSDirectory for the named file.  */
>   public static FSDirectory getDirectory(String path, boolean create, boolean 
> useLocks)
>       throws IOException {
>     _disableLocks = !useLocks;
>     return getDirectory(new File(path), create);
>   }
>   /** Returns the directory instance for the named location.
>    *
>    * <p>Directories are cached, so that, for a given canonical path, the same
>    * FSDirectory instance will always be returned.  This permits
>    * synchronization on directories.
>    *
>    * @param path the path to the directory.
>    * @param create if true, create, or erase any existing contents.
>    * @return the FSDirectory for the named file.  */
>   public static FSDirectory getDirectory(String path, boolean create)
>       throws IOException {
>     return getDirectory(new File(path), create);
>   }
>   /** Returns the directory instance for the named location, with option of
>    *  disabled locking.
>    *
>    * <p>Directories are cached, so that, for a given canonical path, the same
>    * FSDirectory instance will always be returned.  This permits
>    * synchronization on directories.
>    *
>    * @param file the path to the directory.
>    * @param create if true, create, or erase any existing contents.
>    * @param useLocks if false, don't use locks during index reads. Useful in
>    *                 read-only filesystems or from applets.
>    * @return the FSDirectory for the named file.  */
>   public static FSDirectory getDirectory(File file, boolean create, boolean 
> useLocks)
>     throws IOException {
>     _disableLocks = !useLocks;
>     return getDirectory(file, create);
>   }
>   /** Returns the directory instance for the named location.
>    *
>    * <p>Directories are cached, so that, for a given canonical path, the same
>    * FSDirectory instance will always be returned.  This permits
>    * synchronization on directories.
>    *
>    * @param file the path to the directory.
>    * @param create if true, create, or erase any existing contents.
>    * @return the FSDirectory for the named file.  */
>   public static FSDirectory getDirectory(File file, boolean create)
>     throws IOException {
>     file = new File(file.getCanonicalPath());
>     FSDirectory dir;
>     synchronized (DIRECTORIES) {
>       dir = (FSDirectory)DIRECTORIES.get(file);
>       if (dir == null) {
> 	dir = new FSDirectory(file, create);
> 	DIRECTORIES.put(file, dir);
>       } else if (create) {
>         dir.create();
>       }
>     }
>     synchronized (dir) {
>       dir.refCount++;
>     }
>     return dir;
>   }
>   private File directory = null;
>   private int refCount;
>   private FSDirectory(File path, boolean create) throws IOException {
>     directory = path;
>     if (create)
>       create();
>     if (!directory.isDirectory())
>       throw new IOException(path + " not a directory");
>   }
>   private synchronized void create() throws IOException {
>     if (!directory.exists())
> 	if (!directory.mkdir())
> 	    throw new IOException("Cannot create directory: " + directory);
>     String[] files = directory.list();            // clear old files
>     for (int i = 0; i < files.length; i++) {
>       File file = new File(directory, files[i]);
>       if (!file.delete())
>         throw new IOException("couldn't delete " + files[i]);
>     }
>   }
>   /** Returns an array of strings, one for each file in the directory. */
>   public final String[] list() throws IOException {
>     return directory.list();
>   }
>   /** Returns true iff a file with the given name exists. */
>   public final boolean fileExists(String name) throws IOException {
>     File file = new File(directory, name);
>     return file.exists();
>   }
>   /** Returns the time the named file was last modified. */
>   public final long fileModified(String name) throws IOException {
>     File file = new File(directory, name);
>     return file.lastModified();
>   }
>   /** Returns the time the named file was last modified. */
>   public static final long fileModified(File directory, String name)
>        throws IOException {
>     File file = new File(directory, name);
>     return file.lastModified();
>   }
>   /** Set the modified time of an existing file to now. */
>   public void touchFile(String name) throws IOException {
>     File file = new File(directory, name);
>     file.setLastModified(System.currentTimeMillis());
>   }
>   /** Returns the length in bytes of a file in the directory. */
>   public final long fileLength(String name) throws IOException {
>     File file = new File(directory, name);
>     return file.length();
>   }
>   /** Removes an existing file in the directory. */
>   public final void deleteFile(String name) throws IOException {
>     File file = new File(directory, name);
>     if (!file.delete())
>       throw new IOException("couldn't delete " + name);
>   }
>   /** Renames an existing file in the directory. */
>   public final synchronized void renameFile(String from, String to)
>       throws IOException {
>     File old = new File(directory, from);
>     File nu = new File(directory, to);
>     /* This is not atomic.  If the program crashes between the call to
>        delete() and the call to renameTo() then we're screwed, but I've
>        been unable to figure out how else to do this... */
>     if (nu.exists())
>       if (!nu.delete())
> 	throw new IOException("couldn't delete " + to);
>     if (!old.renameTo(nu))
>       throw new IOException("couldn't rename " + from + " to " + to);
>   }
>   /** Creates a new, empty file in the directory with the given name.
>       Returns a stream writing this file. */
>   public final OutputStream createFile(String name) throws IOException {
>     return new FSOutputStream(new File(directory, name));
>   }
>   /** Returns a stream reading an existing file. */
>   public final InputStream openFile(String name) throws IOException {
>     return new FSInputStream(new File(directory, name));
>   }
>   /** Constructs a {@link Lock} with the specified name.  Locks are implemented
>    * with {@link File#createNewFile() }.
>    *
>    * <p>In JDK 1.1 or if system property <I>disableLuceneLocks</I> is the
>    * string "true", locks are disabled.  Assigning this property any other
>    * string will <B>not</B> prevent creation of lock files. Locks are also
>    * disabled if getDirectory was invoked with the optional third argument
>    * useLocks set to false.
>    * Disabling locks is useful when using Lucene on read-only medium, such
>    * as CD-ROM, or from an applet that does not have filesystem write
>    * permission.
>    *
>    * @param name the name of the lock file
>    * @return an instance of <code>Lock</code> holding the lock
>    */
>   public final Lock makeLock(String name) {
>     final File lockFile = new File(directory, name);
>     if (_disableLocks || locksDisabledByProp())
>     {
>       return new Lock() {
> 	public boolean obtain() throws IOException {
> 	  return true;
> 	}
> 	public void release() {
> 	  return;
> 	}
> 	public String toString() {
> 	  return "Lock@locksDisabled";
> 	}
>       };
>     }
>     else
>     {
>       return new Lock() {
> 	public boolean obtain() throws IOException {
>           return lockFile.createNewFile();
> 	}
> 	public void release() {
> 	  lockFile.delete();
> 	}
> 	public String toString() {
> 	  return "Lock@" + lockFile;
> 	}
>       };
>     }
>   }
>   /** Closes the store to future operations. */
>   public final synchronized void close() throws IOException {
>     if (--refCount <= 0) {
>       synchronized (DIRECTORIES) {
> 	DIRECTORIES.remove(directory);
>       }
>     }
>   }
>   /** For debug output. */
>   public String toString() {
>     return "FSDirectory@" + directory;
>   }
> }
> final class FSInputStream extends InputStream {
>   private class Descriptor extends RandomAccessFile {
>     public long position;
>     public Descriptor(File file, String mode) throws IOException {
>       super(file, mode);
>     }
>   }
>   Descriptor file = null;
>   boolean isClone;
>   public FSInputStream(File path) throws IOException {
>     file = new Descriptor(path, "r");
>     length = file.length();
>   }
>   /** InputStream methods */
>   protected final void readInternal(byte[] b, int offset, int len)
>        throws IOException {
>     synchronized (file) {
>       long position = getFilePointer();
>       if (position != file.position) {
> 	file.seek(position);
> 	file.position = position;
>       }
>       int total = 0;
>       do {
> 	int i = file.read(b, offset+total, len-total);
> 	if (i == -1)
> 	  throw new IOException("read past EOF");
> 	file.position += i;
> 	total += i;
>       } while (total < len);
>     }
>   }
>   public final void close() throws IOException {
>     if (!isClone)
>       file.close();
>   }
>   /** Random-access methods */
>   protected final void seekInternal(long position) throws IOException {
>   }
>   protected final void finalize() throws IOException {
>     close();					  // close the file
>   }
>   public Object clone() {
>     FSInputStream clone = (FSInputStream)super.clone();
>     clone.isClone = true;
>     return clone;
>   }
> }
> final class FSOutputStream extends OutputStream {
>   RandomAccessFile file = null;
>   public FSOutputStream(File path) throws IOException {
>     file = new RandomAccessFile(path, "rw");
>   }
>   /** output methods: */
>   public final void flushBuffer(byte[] b, int size) throws IOException {
>     file.write(b, 0, size);
>   }
>   public final void close() throws IOException {
>     super.close();
>     file.close();
>   }
>   /** Random-access methods */
>   public final void seek(long pos) throws IOException {
>     super.seek(pos);
>     file.seek(pos);
>   }
>   public final long length() throws IOException {
>     return file.length();
>   }
>   protected final void finalize() throws IOException {
>     file.close();				  // close the file
>   }
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


---------------------------------------------------------------------
To unsubscribe, e-mail: java-dev-unsubscribe@lucene.apache.org
For additional commands, e-mail: java-dev-help@lucene.apache.org

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic