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