lucene-java-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mikemcc...@apache.org
Subject svn commit: r927761 - in /lucene/dev/trunk: lucene/ lucene/src/java/org/apache/lucene/store/ lucene/src/java/org/apache/lucene/util/ solr/src/java/org/apache/solr/core/
Date Fri, 26 Mar 2010 10:34:41 GMT
Author: mikemccand
Date: Fri Mar 26 10:34:41 2010
New Revision: 927761

URL: http://svn.apache.org/viewvc?rev=927761&view=rev
Log:
LUCENE-2339: deprecate static Directory.copy in favor non-static Directory.copyTo; if it's
FSDir -> FSDir, use nio's FileChannel.transferTo

Added:
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/util/IOUtils.java   (with props)
Modified:
    lucene/dev/trunk/lucene/CHANGES.txt
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/store/Directory.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/store/FSDirectory.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/core/RefCntRamDirectory.java

Modified: lucene/dev/trunk/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/CHANGES.txt?rev=927761&r1=927760&r2=927761&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/CHANGES.txt (original)
+++ lucene/dev/trunk/lucene/CHANGES.txt Fri Mar 26 10:34:41 2010
@@ -216,6 +216,11 @@ New features
   convenient classes in case you want to disable segment merges by IndexWriter
   without tweaking a particular MergePolicy parameters, such as mergeFactor.
   MergeScheduler's methods are now public. (Shai Erera via Mike McCandless)
+
+* LUCENE-2339: Deprecate static method Directory.copy in favor of
+  Directory.copyTo, and use nio's FileChannel.transferTo when copying
+  files between FSDirectory instances.  (Earwin Burrfoot via Mike
+  McCandless).
   
 Optimizations
 

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/store/Directory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/store/Directory.java?rev=927761&r1=927760&r2=927761&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/store/Directory.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/store/Directory.java Fri Mar 26 10:34:41
2010
@@ -22,7 +22,13 @@ import java.io.Closeable;
 import java.util.Collection;
 import java.util.Collections;
 
+import java.util.ArrayList;
+import static java.util.Arrays.asList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
 import org.apache.lucene.index.IndexFileNameFilter;
+import org.apache.lucene.util.IOUtils;
 
 /** A Directory is a flat list of files.  Files may be written once, when they
  * are created.  Once a file is created it may only be opened for read, or
@@ -183,64 +189,83 @@ public abstract class Directory implemen
       return this.toString();
   }
 
+
   /**
-   * Copy contents of a directory src to a directory dest.
-   * If a file in src already exists in dest then the
-   * one in dest will be blindly overwritten.
-   *
-   * <p><b>NOTE:</b> the source directory cannot change
-   * while this method is running.  Otherwise the results
-   * are undefined and you could easily hit a
-   * FileNotFoundException.
+   * <p>Copy all files of this directory to destination directory. All conflicting
files at destination are overwritten</p>
+   * <p><b>NOTE:</b> this method only copies files that look like index
files (ie, have extensions matching the known
+   * extensions of index files).
+   * <p><b>NOTE:</b> the source directory should not change while this
method is running.  Otherwise the results are
+   * undefined and you could easily hit a FileNotFoundException. </p>
    *
-   * <p><b>NOTE:</b> this method only copies files that look
-   * like index files (ie, have extensions matching the
-   * known extensions of index files).
-   *
-   * @param src source directory
-   * @param dest destination directory
-   * @param closeDirSrc if <code>true</code>, call {@link #close()} method on
source directory
-   * @throws IOException
+   * @param to        destination directory
    */
-  public static void copy(Directory src, Directory dest, boolean closeDirSrc) throws IOException
{
-    final String[] files = src.listAll();
-
+  public final void copyTo(Directory to) throws IOException {
+    List<String> filenames = new ArrayList<String>();
     IndexFileNameFilter filter = IndexFileNameFilter.getFilter();
 
-    byte[] buf = new byte[BufferedIndexOutput.BUFFER_SIZE];
-    for (int i = 0; i < files.length; i++) {
+    for (String name : listAll())
+      if (filter.accept(null, name))
+        filenames.add(name);
 
-      if (!filter.accept(null, files[i]))
-        continue;
+    copyTo(to, filenames);
+  }
 
+  /**
+   * <p>Copy given files of this directory to destination directory. All conflicting
files at destination are overwritten</p>
+   * <p><b>NOTE:</b> the source directory should not change while this
method is running.  Otherwise the results are
+   * undefined and you could easily hit a FileNotFoundException. </p>
+   * <p><b>NOTE:</b> implementations can check if destination directory
is of the same type as 'this' and perform optimized copy</p>
+   *
+   * @param to        destination directory
+   * @param filenames file names to be copied
+   */
+  public void copyTo(Directory to, Collection<String> filenames) throws IOException
{
+    byte[] buf = new byte[BufferedIndexOutput.BUFFER_SIZE];
+    for (String filename : filenames) {
       IndexOutput os = null;
       IndexInput is = null;
+      IOException priorException = null;
       try {
         // create file in dest directory
-        os = dest.createOutput(files[i]);
+        os = to.createOutput(filename);
         // read current file
-        is = src.openInput(files[i]);
+        is = openInput(filename);
         // and copy to dest directory
         long len = is.length();
         long readCount = 0;
         while (readCount < len) {
-          int toRead = readCount + BufferedIndexOutput.BUFFER_SIZE > len ? (int)(len -
readCount) : BufferedIndexOutput.BUFFER_SIZE;
+          int toRead = readCount + BufferedIndexOutput.BUFFER_SIZE > len ? (int) (len
- readCount) : BufferedIndexOutput.BUFFER_SIZE;
           is.readBytes(buf, 0, toRead);
           os.writeBytes(buf, toRead);
           readCount += toRead;
         }
+      } catch (IOException ioe) {
+        priorException = ioe;
       } finally {
-        // graceful cleanup
-        try {
-          if (os != null)
-            os.close();
-        } finally {
-          if (is != null)
-            is.close();
-        }
+        IOUtils.closeSafely(priorException, os, is);
       }
     }
-    if(closeDirSrc)
+  }
+
+  /**
+   * Copy contents of a directory src to a directory dest. If a file in src already exists
in dest then the one in dest
+   * will be blindly overwritten.
+   * <p/>
+   * <p><b>NOTE:</b> the source directory cannot change while this method
is running.  Otherwise the results are
+   * undefined and you could easily hit a FileNotFoundException.
+   * <p/>
+   * <p><b>NOTE:</b> this method only copies files that look like index
files (ie, have extensions matching the known
+   * extensions of index files).
+   *
+   * @param src         source directory
+   * @param dest        destination directory
+   * @param closeDirSrc if <code>true</code>, call {@link #close()} method on
source directory
+   * @deprecated should be replaced with src.copyTo(dest); [src.close();]
+   */
+  @Deprecated
+  public static void copy(Directory src, Directory dest, boolean closeDirSrc) throws IOException
{
+    src.copyTo(dest);
+    if (closeDirSrc)
       src.close();
   }
 

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/store/FSDirectory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/store/FSDirectory.java?rev=927761&r1=927760&r2=927761&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/store/FSDirectory.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/store/FSDirectory.java Fri Mar 26 10:34:41
2010
@@ -18,9 +18,12 @@ package org.apache.lucene.store;
  */
 
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.FilenameFilter;
 import java.io.IOException;
 import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 
@@ -29,6 +32,7 @@ import java.util.Collections;
 import static java.util.Collections.synchronizedSet;
 import java.util.HashSet;
 import java.util.Set;
+import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.ThreadInterruptedException;
 import org.apache.lucene.util.Constants;
 
@@ -422,6 +426,30 @@ public abstract class FSDirectory extend
     return chunkSize;
   }
 
+  @Override
+  public void copyTo(Directory to, Collection<String> filenames) throws IOException
{
+    if (to instanceof FSDirectory) {
+      FSDirectory target = (FSDirectory) to;
+
+      for (String filename : filenames) {
+        target.ensureCanWrite(filename);
+        FileChannel input = null;
+        FileChannel output = null;
+        IOException priorException = null;
+        try {
+          input = new FileInputStream(new File(directory, filename)).getChannel();
+          output = new FileOutputStream(new File(target.directory, filename)).getChannel();
+          output.transferFrom(input, 0, input.size());
+        } catch (IOException ioe) {
+          priorException = ioe;
+        } finally {
+          IOUtils.closeSafely(priorException, input, output);
+        }
+      }
+    } else
+      super.copyTo(to, filenames);
+  }
+
   protected static class FSIndexOutput extends BufferedIndexOutput {
     private final FSDirectory parent;
     private final String name;

Added: lucene/dev/trunk/lucene/src/java/org/apache/lucene/util/IOUtils.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/util/IOUtils.java?rev=927761&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/util/IOUtils.java (added)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/util/IOUtils.java Fri Mar 26 10:34:41
2010
@@ -0,0 +1,64 @@
+package org.apache.lucene.util;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.Closeable;
+import java.io.IOException;
+
+/** @lucene.internal */
+public class IOUtils {
+  /**
+   * <p>Closes all given <tt>Closeable</tt>s, suppressing all thrown exceptions.
Some of the <tt>Closeable</tt>s
+   * may be null, they are ignored. After everything is closed, method either throws <tt>priorException</tt>,
+   * if one is supplied, or the first of suppressed exceptions, or completes normally.</p>
+   * <p>Sample usage:<br/>
+   * <pre>
+   * Closeable resource1 = null, resource2 = null, resource3 = null;
+   * ExpectedException priorE = null;
+   * try {
+   *   resource1 = ...; resource2 = ...; resource3 = ...; // Aquisition may throw ExpectedException
+   *   ..do..stuff.. // May throw ExpectedException
+   * } catch (ExpectedException e) {
+   *   priorE = e;
+   * } finally {
+   *   closeSafely(priorE, resource1, resource2, resource3);
+   * }
+   * </pre>
+   * </p>
+   * @param priorException  <tt>null</tt> or an exception that will be rethrown
after method completion
+   * @param objects         objects to call <tt>close()</tt> on
+   */
+  public static <E extends Exception> void closeSafely(E priorException, Closeable...
objects) throws E, IOException {
+    IOException firstIOE = null;
+
+    for (Closeable object : objects) {
+      try {
+        if (object != null)
+          object.close();
+      } catch (IOException ioe) {
+        if (firstIOE == null)
+          firstIOE = ioe;
+      }
+    }
+
+    if (priorException != null)
+      throw priorException;
+    else if (firstIOE != null)
+      throw firstIOE;
+  }
+}

Propchange: lucene/dev/trunk/lucene/src/java/org/apache/lucene/util/IOUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/core/RefCntRamDirectory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/core/RefCntRamDirectory.java?rev=927761&r1=927760&r2=927761&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/core/RefCntRamDirectory.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/core/RefCntRamDirectory.java Fri Mar 26
10:34:41 2010
@@ -17,7 +17,7 @@ public class RefCntRamDirectory extends 
 
   public RefCntRamDirectory(Directory dir) throws IOException {
     this();
-    Directory.copy(dir, this, false);
+    dir.copyTo(this);
   }
 
   public void incRef() {



Mime
View raw message