HDFS-10691. FileDistribution fails in hdfs oiv command due to ArrayIndexOutOfBoundsException. Contributed by Yiqun Lin.
(cherry picked from commit204a2055b1
) (cherry picked from commit0cff416c35
)
This commit is contained in:
parent
ac510e5cd0
commit
e467f838bb
|
@ -128,6 +128,12 @@ final class FileDistributionCalculator {
|
|||
|
||||
int bucket = fileSize > maxSize ? distribution.length - 1 : (int) Math
|
||||
.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];
|
||||
|
||||
} else if (p.getType() == INodeSection.INode.Type.DIRECTORY) {
|
||||
|
|
|
@ -145,6 +145,10 @@ class FileDistributionVisitor extends TextWriterImageVisitor {
|
|||
high = distribution.length-1;
|
||||
else
|
||||
high = (int)Math.ceil((double)current.fileSize / step);
|
||||
|
||||
if (high >= distribution.length) {
|
||||
high = distribution.length - 1;
|
||||
}
|
||||
distribution[high]++;
|
||||
if(totalFiles % 1000000 == 1)
|
||||
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.Path;
|
||||
import org.apache.hadoop.hdfs.DFSConfigKeys;
|
||||
import org.apache.hadoop.hdfs.DFSTestUtil;
|
||||
import org.apache.hadoop.hdfs.DistributedFileSystem;
|
||||
import org.apache.hadoop.hdfs.MiniDFSCluster;
|
||||
import org.apache.hadoop.hdfs.protocol.HdfsConstants.SafeModeAction;
|
||||
|
@ -552,4 +553,52 @@ public class TestOfflineImageViewer {
|
|||
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