HDFS-10691. FileDistribution fails in hdfs oiv command due to ArrayIndexOutOfBoundsException. Contributed by Yiqun Lin.
This commit is contained in:
parent
8ebf2e95d2
commit
204a2055b1
|
@ -128,6 +128,12 @@ final class FileDistributionCalculator {
|
||||||
|
|
||||||
int bucket = fileSize > maxSize ? distribution.length - 1 : (int) Math
|
int bucket = fileSize > maxSize ? distribution.length - 1 : (int) Math
|
||||||
.ceil((double)fileSize / steps);
|
.ceil((double)fileSize / steps);
|
||||||
|
// Compare the bucket value with distribution's length again,
|
||||||
|
// because sometimes the bucket value will be equal to
|
||||||
|
// the length when maxSize can't be divided completely by step.
|
||||||
|
if (bucket >= distribution.length) {
|
||||||
|
bucket = distribution.length - 1;
|
||||||
|
}
|
||||||
++distribution[bucket];
|
++distribution[bucket];
|
||||||
|
|
||||||
} else if (p.getType() == INodeSection.INode.Type.DIRECTORY) {
|
} else if (p.getType() == INodeSection.INode.Type.DIRECTORY) {
|
||||||
|
|
|
@ -145,6 +145,10 @@ class FileDistributionVisitor extends TextWriterImageVisitor {
|
||||||
high = distribution.length-1;
|
high = distribution.length-1;
|
||||||
else
|
else
|
||||||
high = (int)Math.ceil((double)current.fileSize / step);
|
high = (int)Math.ceil((double)current.fileSize / step);
|
||||||
|
|
||||||
|
if (high >= distribution.length) {
|
||||||
|
high = distribution.length - 1;
|
||||||
|
}
|
||||||
distribution[high]++;
|
distribution[high]++;
|
||||||
if(totalFiles % 1000000 == 1)
|
if(totalFiles % 1000000 == 1)
|
||||||
System.out.println("Files processed: " + totalFiles
|
System.out.println("Files processed: " + totalFiles
|
||||||
|
|
|
@ -70,6 +70,7 @@ import org.apache.hadoop.fs.FileSystem;
|
||||||
import org.apache.hadoop.fs.FileSystemTestHelper;
|
import org.apache.hadoop.fs.FileSystemTestHelper;
|
||||||
import org.apache.hadoop.fs.Path;
|
import org.apache.hadoop.fs.Path;
|
||||||
import org.apache.hadoop.hdfs.DFSConfigKeys;
|
import org.apache.hadoop.hdfs.DFSConfigKeys;
|
||||||
|
import org.apache.hadoop.hdfs.DFSTestUtil;
|
||||||
import org.apache.hadoop.hdfs.DistributedFileSystem;
|
import org.apache.hadoop.hdfs.DistributedFileSystem;
|
||||||
import org.apache.hadoop.hdfs.MiniDFSCluster;
|
import org.apache.hadoop.hdfs.MiniDFSCluster;
|
||||||
import org.apache.hadoop.hdfs.protocol.HdfsConstants.SafeModeAction;
|
import org.apache.hadoop.hdfs.protocol.HdfsConstants.SafeModeAction;
|
||||||
|
@ -552,4 +553,52 @@ public class TestOfflineImageViewer {
|
||||||
GenericTestUtils.assertExceptionContains("Layout version mismatch.", t);
|
GenericTestUtils.assertExceptionContains("Layout version mismatch.", t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFileDistributionCalculatorForException() throws Exception {
|
||||||
|
File fsimageFile = null;
|
||||||
|
Configuration conf = new Configuration();
|
||||||
|
HashMap<String, FileStatus> files = Maps.newHashMap();
|
||||||
|
|
||||||
|
// Create a initial fsimage file
|
||||||
|
try (MiniDFSCluster cluster =
|
||||||
|
new MiniDFSCluster.Builder(conf).numDataNodes(1).build()) {
|
||||||
|
cluster.waitActive();
|
||||||
|
DistributedFileSystem hdfs = cluster.getFileSystem();
|
||||||
|
|
||||||
|
// Create a reasonable namespace
|
||||||
|
Path dir = new Path("/dir");
|
||||||
|
hdfs.mkdirs(dir);
|
||||||
|
files.put(dir.toString(), pathToFileEntry(hdfs, dir.toString()));
|
||||||
|
// Create files with byte size that can't be divided by step size,
|
||||||
|
// the byte size for here are 3, 9, 15, 21.
|
||||||
|
for (int i = 0; i < FILES_PER_DIR; i++) {
|
||||||
|
Path file = new Path(dir, "file" + i);
|
||||||
|
DFSTestUtil.createFile(hdfs, file, 6 * i + 3, (short) 1, 0);
|
||||||
|
|
||||||
|
files.put(file.toString(),
|
||||||
|
pathToFileEntry(hdfs, file.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write results to the fsimage file
|
||||||
|
hdfs.setSafeMode(SafeModeAction.SAFEMODE_ENTER, false);
|
||||||
|
hdfs.saveNamespace();
|
||||||
|
// Determine location of fsimage file
|
||||||
|
fsimageFile =
|
||||||
|
FSImageTestUtil.findLatestImageFile(FSImageTestUtil
|
||||||
|
.getFSImage(cluster.getNameNode()).getStorage().getStorageDir(0));
|
||||||
|
if (fsimageFile == null) {
|
||||||
|
throw new RuntimeException("Didn't generate or can't find fsimage");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the test with params -maxSize 23 and -step 4, it will not throw
|
||||||
|
// ArrayIndexOutOfBoundsException with index 6 when deals with
|
||||||
|
// 21 byte size file.
|
||||||
|
int status =
|
||||||
|
OfflineImageViewerPB.run(new String[] {"-i",
|
||||||
|
fsimageFile.getAbsolutePath(), "-o", "-", "-p",
|
||||||
|
"FileDistribution", "-maxSize", "23", "-step", "4"});
|
||||||
|
assertEquals(0, status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue