001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 package org.apache.hadoop.hdfs.server.datanode; 019 020 import java.io.File; 021 022 import org.apache.hadoop.hdfs.server.common.HdfsServerConstants.ReplicaState; 023 import org.apache.hadoop.hdfs.server.datanode.fsdataset.FsVolumeSpi; 024 import org.apache.hadoop.hdfs.server.protocol.ReplicaRecoveryInfo; 025 026 /** 027 * This class represents replicas that are under block recovery 028 * It has a recovery id that is equal to the generation stamp 029 * that the replica will be bumped to after recovery 030 * The recovery id is used to handle multiple concurrent block recoveries. 031 * A recovery with higher recovery id preempts recoveries with a lower id. 032 * 033 */ 034 public class ReplicaUnderRecovery extends ReplicaInfo { 035 private ReplicaInfo original; // the original replica that needs to be recovered 036 private long recoveryId; // recovery id; it is also the generation stamp 037 // that the replica will be bumped to after recovery 038 039 public ReplicaUnderRecovery(ReplicaInfo replica, long recoveryId) { 040 super(replica, replica.getVolume(), replica.getDir()); 041 if ( replica.getState() != ReplicaState.FINALIZED && 042 replica.getState() != ReplicaState.RBW && 043 replica.getState() != ReplicaState.RWR ) { 044 throw new IllegalArgumentException("Cannot recover replica: " + replica); 045 } 046 this.original = replica; 047 this.recoveryId = recoveryId; 048 } 049 050 /** 051 * Copy constructor. 052 * @param from where to copy from 053 */ 054 public ReplicaUnderRecovery(ReplicaUnderRecovery from) { 055 super(from); 056 this.original = from.getOriginalReplica(); 057 this.recoveryId = from.getRecoveryID(); 058 } 059 060 /** 061 * Get the recovery id 062 * @return the generation stamp that the replica will be bumped to 063 */ 064 public long getRecoveryID() { 065 return recoveryId; 066 } 067 068 /** 069 * Set the recovery id 070 * @param recoveryId the new recoveryId 071 */ 072 public void setRecoveryID(long recoveryId) { 073 if (recoveryId > this.recoveryId) { 074 this.recoveryId = recoveryId; 075 } else { 076 throw new IllegalArgumentException("The new rcovery id: " + recoveryId 077 + " must be greater than the current one: " + this.recoveryId); 078 } 079 } 080 081 /** 082 * Get the original replica that's under recovery 083 * @return the original replica under recovery 084 */ 085 public ReplicaInfo getOriginalReplica() { 086 return original; 087 } 088 089 @Override //ReplicaInfo 090 public boolean isUnlinked() { 091 return original.isUnlinked(); 092 } 093 094 @Override //ReplicaInfo 095 public void setUnlinked() { 096 original.setUnlinked(); 097 } 098 099 @Override //ReplicaInfo 100 public ReplicaState getState() { 101 return ReplicaState.RUR; 102 } 103 104 @Override 105 public long getVisibleLength() { 106 return original.getVisibleLength(); 107 } 108 109 @Override 110 public long getBytesOnDisk() { 111 return original.getBytesOnDisk(); 112 } 113 114 @Override //org.apache.hadoop.hdfs.protocol.Block 115 public void setBlockId(long blockId) { 116 super.setBlockId(blockId); 117 original.setBlockId(blockId); 118 } 119 120 @Override //org.apache.hadoop.hdfs.protocol.Block 121 public void setGenerationStamp(long gs) { 122 super.setGenerationStamp(gs); 123 original.setGenerationStamp(gs); 124 } 125 126 @Override //org.apache.hadoop.hdfs.protocol.Block 127 public void setNumBytes(long numBytes) { 128 super.setNumBytes(numBytes); 129 original.setNumBytes(numBytes); 130 } 131 132 @Override //ReplicaInfo 133 public void setDir(File dir) { 134 super.setDir(dir); 135 original.setDir(dir); 136 } 137 138 @Override //ReplicaInfo 139 void setVolume(FsVolumeSpi vol) { 140 super.setVolume(vol); 141 original.setVolume(vol); 142 } 143 144 @Override // Object 145 public boolean equals(Object o) { 146 return super.equals(o); 147 } 148 149 @Override // Object 150 public int hashCode() { 151 return super.hashCode(); 152 } 153 154 @Override 155 public String toString() { 156 return super.toString() 157 + "\n recoveryId=" + recoveryId 158 + "\n original=" + original; 159 } 160 161 public ReplicaRecoveryInfo createInfo() { 162 return new ReplicaRecoveryInfo(original.getBlockId(), 163 original.getBytesOnDisk(), original.getGenerationStamp(), 164 original.getState()); 165 } 166 }