Skip to content

Commit f4ed9f3

Browse files
committed
HDFS-15574. Remove unnecessary sort of block list in DirectoryScanner. Contributed by Stephen O'Donnell.
1 parent 9249590 commit f4ed9f3

File tree

8 files changed

+49
-12
lines changed

8 files changed

+49
-12
lines changed

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DirectoryScanner.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -482,8 +482,7 @@ private void scan() {
482482
Collection<ScanInfo> diffRecord = new ArrayList<>();
483483

484484
statsRecord.totalBlocks = blockpoolReport.size();
485-
final List<ReplicaInfo> bl = dataset.getFinalizedBlocks(bpid);
486-
Collections.sort(bl); // Sort based on blockId
485+
final List<ReplicaInfo> bl = dataset.getSortedFinalizedBlocks(bpid);
487486

488487
int d = 0; // index for blockpoolReport
489488
int m = 0; // index for memReprot

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/FsDatasetSpi.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -237,16 +237,17 @@ StorageReport[] getStorageReports(String bpid)
237237
VolumeFailureSummary getVolumeFailureSummary();
238238

239239
/**
240-
* Gets a list of references to the finalized blocks for the given block pool.
240+
* Gets a sorted list of references to the finalized blocks for the given
241+
* block pool. The list is sorted by blockID.
241242
* <p>
242243
* Callers of this function should call
243244
* {@link FsDatasetSpi#acquireDatasetLock} to avoid blocks' status being
244245
* changed during list iteration.
245246
* </p>
246247
* @return a list of references to the finalized blocks for the given block
247-
* pool.
248+
* pool. The list is sorted by blockID.
248249
*/
249-
List<ReplicaInfo> getFinalizedBlocks(String bpid);
250+
List<ReplicaInfo> getSortedFinalizedBlocks(String bpid);
250251

251252
/**
252253
* Check whether the in-memory block record matches the block on the disk,

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsDatasetImpl.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1992,17 +1992,18 @@ public Map<DatanodeStorage, BlockListAsLongs> getBlockReports(String bpid) {
19921992
}
19931993

19941994
/**
1995-
* Gets a list of references to the finalized blocks for the given block pool.
1995+
* Gets a list of references to the finalized blocks for the given block pool,
1996+
* sorted by blockID.
19961997
* <p>
19971998
* Callers of this function should call
19981999
* {@link FsDatasetSpi#acquireDatasetLock()} to avoid blocks' status being
19992000
* changed during list iteration.
20002001
* </p>
20012002
* @return a list of references to the finalized blocks for the given block
2002-
* pool.
2003+
* pool. The list is sorted by blockID.
20032004
*/
20042005
@Override
2005-
public List<ReplicaInfo> getFinalizedBlocks(String bpid) {
2006+
public List<ReplicaInfo> getSortedFinalizedBlocks(String bpid) {
20062007
try (AutoCloseableLock lock = datasetReadLock.acquire()) {
20072008
final List<ReplicaInfo> finalized = new ArrayList<ReplicaInfo>(
20082009
volumeMap.size(bpid));

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestCrcCorruption.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ private void thistest(Configuration conf, DFSTestUtil util) throws Exception {
173173
final DataNode dn = cluster.getDataNodes().get(dnIdx);
174174
final String bpid = cluster.getNamesystem().getBlockPoolId();
175175
List<ReplicaInfo> replicas =
176-
dn.getFSDataset().getFinalizedBlocks(bpid);
176+
dn.getFSDataset().getSortedFinalizedBlocks(bpid);
177177
assertTrue("Replicas do not exist", !replicas.isEmpty());
178178

179179
for (int idx = 0; idx < replicas.size(); idx++) {

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestReconstructStripedFile.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ private void testErasureCodingWorkerXmitsWeight(
540540
writeFile(fs, "/ec-xmits-weight", fileLen);
541541

542542
DataNode dn = cluster.getDataNodes().get(0);
543-
int corruptBlocks = dn.getFSDataset().getFinalizedBlocks(
543+
int corruptBlocks = dn.getFSDataset().getSortedFinalizedBlocks(
544544
cluster.getNameNode().getNamesystem().getBlockPoolId()).size();
545545
int expectedXmits = corruptBlocks * expectedWeight;
546546

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/SimulatedFSDataset.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1510,7 +1510,7 @@ public StorageReport[] getStorageReports(String bpid) {
15101510
}
15111511

15121512
@Override
1513-
public List<ReplicaInfo> getFinalizedBlocks(String bpid) {
1513+
public List<ReplicaInfo> getSortedFinalizedBlocks(String bpid) {
15141514
throw new UnsupportedOperationException();
15151515
}
15161516

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/extdataset/ExternalDatasetImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public Map<String, Object> getVolumeInfoMap() {
9090
}
9191

9292
@Override
93-
public List<ReplicaInfo> getFinalizedBlocks(String bpid) {
93+
public List<ReplicaInfo> getSortedFinalizedBlocks(String bpid) {
9494
return null;
9595
}
9696

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/TestFsDatasetImpl.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
import java.io.Writer;
8181
import java.nio.charset.StandardCharsets;
8282
import java.util.ArrayList;
83+
import java.util.Random;
8384
import java.util.concurrent.CountDownLatch;
8485
import java.util.HashSet;
8586
import java.util.List;
@@ -569,6 +570,41 @@ public void testAddVolumeFailureReleasesInUseLock() throws IOException {
569570

570571
FsDatasetTestUtil.assertFileLockReleased(badDir.toString());
571572
}
573+
574+
@Test
575+
/**
576+
* This test is here primarily to catch any case where the datanode replica
577+
* map structure is changed to a new structure which is not sorted and hence
578+
* reading the blocks from it directly would not be sorted.
579+
*/
580+
public void testSortedFinalizedBlocksAreSorted() throws IOException {
581+
this.conf = new HdfsConfiguration();
582+
MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf).build();
583+
try {
584+
cluster.waitActive();
585+
DataNode dn = cluster.getDataNodes().get(0);
586+
587+
FsDatasetSpi<?> ds = DataNodeTestUtils.getFSDataset(dn);
588+
ds.addBlockPool(BLOCKPOOL, conf);
589+
590+
// Load 1000 blocks with random blockIDs
591+
for (int i=0; i<=1000; i++) {
592+
ExtendedBlock eb = new ExtendedBlock(
593+
BLOCKPOOL, new Random().nextInt(), 1000, 1000 + i);
594+
cluster.getFsDatasetTestUtils(0).createFinalizedReplica(eb);
595+
}
596+
// Get the sorted blocks and validate the arrayList is sorted
597+
List<ReplicaInfo> replicaList = ds.getSortedFinalizedBlocks(BLOCKPOOL);
598+
for (int i=0; i<replicaList.size() - 1; i++) {
599+
if (replicaList.get(i).compareTo(replicaList.get(i+1)) > 0) {
600+
// Not sorted so fail the test
601+
fail("ArrayList is not sorted, and it should be");
602+
}
603+
}
604+
} finally {
605+
cluster.shutdown();
606+
}
607+
}
572608

573609
@Test
574610
public void testDeletingBlocks() throws IOException {

0 commit comments

Comments
 (0)