diff --git a/CHANGES.txt b/CHANGES.txt index 682b89a6f5..23ef8d7b38 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4463,6 +4463,9 @@ Release 0.17.0 - 2008-05-18 exponentially increasing number of records (up to 10,000 records/log). (Zheng Shao via omalley) + HADOOP-6180. NameNode slowed down when many files with same filename + were moved to Trash. (Boris Shkolnik via hairong) + BUG FIXES HADOOP-2195. '-mkdir' behaviour is now closer to Linux shell in case of diff --git a/src/java/org/apache/hadoop/fs/Trash.java b/src/java/org/apache/hadoop/fs/Trash.java index 5b062a1ece..fbcf151479 100644 --- a/src/java/org/apache/hadoop/fs/Trash.java +++ b/src/java/org/apache/hadoop/fs/Trash.java @@ -17,14 +17,19 @@ */ package org.apache.hadoop.fs; -import java.text.*; -import java.io.*; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.Date; -import org.apache.commons.logging.*; - -import org.apache.hadoop.conf.*; -import org.apache.hadoop.fs.permission.*; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.conf.Configured; +import org.apache.hadoop.fs.permission.FsAction; +import org.apache.hadoop.fs.permission.FsPermission; import org.apache.hadoop.util.StringUtils; /** Provides a trash feature. Files are moved to a user's trash @@ -128,12 +133,14 @@ public boolean moveToTrash(Path path) throws IOException { try { // // if the target path in Trash already exists, then append with - // a number. Start from 1. + // a current time in millisecs. // String orig = trashPath.toString(); - for (int j = 1; fs.exists(trashPath); j++) { - trashPath = new Path(orig + "." + j); + + while(fs.exists(trashPath)) { + trashPath = new Path(orig + System.currentTimeMillis()); } + if (fs.rename(path, trashPath)) // move to current trash return true; } catch (IOException e) { diff --git a/src/test/core/org/apache/hadoop/fs/TestTrash.java b/src/test/core/org/apache/hadoop/fs/TestTrash.java index 6093a39c3a..7da3eb3bc3 100644 --- a/src/test/core/org/apache/hadoop/fs/TestTrash.java +++ b/src/test/core/org/apache/hadoop/fs/TestTrash.java @@ -18,18 +18,15 @@ package org.apache.hadoop.fs; -import junit.framework.TestCase; -import java.io.File; -import java.io.IOException; import java.io.DataOutputStream; +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; import java.net.URI; +import junit.framework.TestCase; + import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.fs.FileSystem; -import org.apache.hadoop.fs.FsShell; -import org.apache.hadoop.fs.Path; -import org.apache.hadoop.fs.Trash; -import org.apache.hadoop.fs.LocalFileSystem; /** * This class tests commands from Trash. @@ -61,6 +58,22 @@ protected static void checkTrash(FileSystem fs, Path trashRoot, Path p = new Path(trashRoot+"/"+ path.toUri().getPath()); assertTrue(fs.exists(p)); } + + // counts how many instances of the file are in the Trash + // they all are in format fileName* + protected static int countSameDeletedFiles(FileSystem fs, final File trashDir, + final String fileName) throws IOException { + System.out.println("Counting " + fileName + " in " + trashDir.getAbsolutePath()); + String [] res = trashDir.list( + new FilenameFilter() { + public boolean accept(File dir, String name) { + return name.startsWith(fileName); + } + } + ); + + return res.length; + } // check that the specified file is not in Trash static void checkNotInTrash(FileSystem fs, Path trashRoot, String pathname) @@ -313,6 +326,45 @@ protected static void trashShell(final FileSystem fs, final Path base) assertFalse(fs.exists(myFile)); assertTrue(val == 0); } + + // deleting same file multiple times + { + int val = -1; + mkdir(fs, myPath); + + try { + assertEquals(0, shell.run(new String [] { "-expunge" } )); + } catch (Exception e) { + System.err.println("Exception raised from fs expunge " + + e.getLocalizedMessage()); + } + + // create a file in that directory. + myFile = new Path(base, "test/mkdirs/myFile"); + String [] args = new String[] {"-rm", myFile.toString()}; + int num_runs = 10; + for(int i=0;i10) { + if((i%print_freq) == 0) + System.out.println("iteration="+i+";res =" + retVal + "; start=" + start + + "; iterTime = " + iterTime + " vs. firstTime=" + first); + long factoredTime = first*factor; + assertTrue(iterTime