BlockInfoUnderConstruction extends BlockInfo { public void initializeBlockRecovery(long recoveryId) { setBlockUCState(BlockUCState.UNDER_RECOVERY); blockRecoveryId = recoveryId; if (replicas.size() == 0) { NameNode.blockStateChangeLog.warn("BLOCK*" + " BlockInfoUnderConstruction.initLeaseRecovery:" + " No blocks found, lease removed."); } boolean allLiveReplicasTriedAsPrimary = true; for (int i = 0; i < replicas.size(); i++) { if (replicas.get(i).isAlive()) { allLiveReplicasTriedAsPrimary = (allLiveReplicasTriedAsPrimary && replicas.get(i).getChosenAsPrimary()); } } if (allLiveReplicasTriedAsPrimary) { for (int i = 0; i < replicas.size(); i++) { replicas.get(i).setChosenAsPrimary(false); } } long mostRecentLastUpdate = 0; ReplicaUnderConstruction primary = null; primaryNodeIndex = -1; for(int i = 0; i < replicas.size(); i++) { if (!(replicas.get(i).isAlive() && !replicas.get(i).getChosenAsPrimary())) { continue; } final ReplicaUnderConstruction ruc = replicas.get(i); final long lastUpdate = ruc.getExpectedStorageLocation().getDatanodeDescriptor().getLastUpdate(); if (lastUpdate > mostRecentLastUpdate) { primaryNodeIndex = i; primary = ruc; mostRecentLastUpdate = lastUpdate; } } if (primary != null) { primary.getExpectedStorageLocation().getDatanodeDescriptor().addBlockToBeRecovered(this); primary.setChosenAsPrimary(true); NameNode.blockStateChangeLog.info("BLOCK* " + this + " recovery started, primary=" + primary); } } BlockInfoUnderConstruction(Block blk, int replication);  BlockInfoUnderConstruction(Block blk, int replication,
                             BlockUCState state,
                             DatanodeStorageInfo[] targets); void setExpectedLocations(DatanodeStorageInfo[] targets); DatanodeStorageInfo[] getExpectedStorageLocations(); int getNumExpectedLocations(); @Override // BlockInfo BlockUCState getBlockUCState(); long getBlockRecoveryId(); void setGenerationStampAndVerifyReplicas(long genStamp); void initializeBlockRecovery(long recoveryId); @Override // BlockInfo // BlockInfoUnderConstruction participates in maps the same way as BlockInfo int hashCode(); @Override // BlockInfo boolean equals(Object obj); @Override String toString(); @Override void appendStringTo(StringBuilder sb); @Override BlockInfo clone();  }
@Test public void testInitializeBlockRecovery() throws Exception { DatanodeStorageInfo s1 = DFSTestUtil.createDatanodeStorageInfo("10.10.1.1", "s1"); DatanodeDescriptor dd1 = s1.getDatanodeDescriptor(); DatanodeStorageInfo s2 = DFSTestUtil.createDatanodeStorageInfo("10.10.1.2", "s2"); DatanodeDescriptor dd2 = s2.getDatanodeDescriptor(); DatanodeStorageInfo s3 = DFSTestUtil.createDatanodeStorageInfo("10.10.1.3", "s3"); DatanodeDescriptor dd3 = s3.getDatanodeDescriptor(); dd1.isAlive = dd2.isAlive = dd3.isAlive = true; BlockInfoUnderConstruction blockInfo = new BlockInfoUnderConstruction( new Block(0, 0, GenerationStamp.LAST_RESERVED_STAMP), 3, BlockUCState.UNDER_CONSTRUCTION, new DatanodeStorageInfo[] {s1, s2, s3}); long currentTime = System.currentTimeMillis(); dd1.setLastUpdate(currentTime - 3 * 1000); dd2.setLastUpdate(currentTime - 1 * 1000); dd3.setLastUpdate(currentTime - 2 * 1000); blockInfo.initializeBlockRecovery(1); BlockInfoUnderConstruction[] blockInfoRecovery = dd2.getLeaseRecoveryCommand(1); assertEquals(blockInfoRecovery[0], blockInfo); currentTime = System.currentTimeMillis(); dd1.setLastUpdate(currentTime - 2 * 1000); dd2.setLastUpdate(currentTime - 1 * 1000); dd3.setLastUpdate(currentTime - 3 * 1000); blockInfo.initializeBlockRecovery(2); blockInfoRecovery = dd1.getLeaseRecoveryCommand(1); assertEquals(blockInfoRecovery[0], blockInfo); currentTime = System.currentTimeMillis(); dd1.setLastUpdate(currentTime - 2 * 1000); dd2.setLastUpdate(currentTime - 1 * 1000); dd3.setLastUpdate(currentTime - 3 * 1000); currentTime = System.currentTimeMillis(); blockInfo.initializeBlockRecovery(3); blockInfoRecovery = dd3.getLeaseRecoveryCommand(1); assertEquals(blockInfoRecovery[0], blockInfo); currentTime = System.currentTimeMillis(); dd1.setLastUpdate(currentTime - 2 * 1000); dd2.setLastUpdate(currentTime - 1 * 1000); dd3.setLastUpdate(currentTime); currentTime = System.currentTimeMillis(); blockInfo.initializeBlockRecovery(3); blockInfoRecovery = dd3.getLeaseRecoveryCommand(1); assertEquals(blockInfoRecovery[0], blockInfo); }