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.getBlockId(), replica.getNumBytes(), replica.getGenerationStamp(),
041 replica.getVolume(), replica.getDir());
042 if ( replica.getState() != ReplicaState.FINALIZED &&
043 replica.getState() != ReplicaState.RBW &&
044 replica.getState() != ReplicaState.RWR ) {
045 throw new IllegalArgumentException("Cannot recover replica: " + replica);
046 }
047 this.original = replica;
048 this.recoveryId = recoveryId;
049 }
050
051 /**
052 * Copy constructor.
053 * @param from
054 */
055 public ReplicaUnderRecovery(ReplicaUnderRecovery from) {
056 super(from);
057 this.original = from.getOriginalReplica();
058 this.recoveryId = from.getRecoveryID();
059 }
060
061 /**
062 * Get the recovery id
063 * @return the generation stamp that the replica will be bumped to
064 */
065 public long getRecoveryID() {
066 return recoveryId;
067 }
068
069 /**
070 * Set the recovery id
071 * @param recoveryId the new recoveryId
072 */
073 public void setRecoveryID(long recoveryId) {
074 if (recoveryId > this.recoveryId) {
075 this.recoveryId = recoveryId;
076 } else {
077 throw new IllegalArgumentException("The new rcovery id: " + recoveryId
078 + " must be greater than the current one: " + this.recoveryId);
079 }
080 }
081
082 /**
083 * Get the original replica that's under recovery
084 * @return the original replica under recovery
085 */
086 public ReplicaInfo getOriginalReplica() {
087 return original;
088 }
089
090 @Override //ReplicaInfo
091 public boolean isUnlinked() {
092 return original.isUnlinked();
093 }
094
095 @Override //ReplicaInfo
096 public void setUnlinked() {
097 original.setUnlinked();
098 }
099
100 @Override //ReplicaInfo
101 public ReplicaState getState() {
102 return ReplicaState.RUR;
103 }
104
105 @Override
106 public long getVisibleLength() {
107 return original.getVisibleLength();
108 }
109
110 @Override
111 public long getBytesOnDisk() {
112 return original.getBytesOnDisk();
113 }
114
115 @Override //org.apache.hadoop.hdfs.protocol.Block
116 public void setBlockId(long blockId) {
117 super.setBlockId(blockId);
118 original.setBlockId(blockId);
119 }
120
121 @Override //org.apache.hadoop.hdfs.protocol.Block
122 public void setGenerationStamp(long gs) {
123 super.setGenerationStamp(gs);
124 original.setGenerationStamp(gs);
125 }
126
127 @Override //org.apache.hadoop.hdfs.protocol.Block
128 public void setNumBytes(long numBytes) {
129 super.setNumBytes(numBytes);
130 original.setNumBytes(numBytes);
131 }
132
133 @Override //ReplicaInfo
134 public void setDir(File dir) {
135 super.setDir(dir);
136 original.setDir(dir);
137 }
138
139 @Override //ReplicaInfo
140 void setVolume(FsVolumeSpi vol) {
141 super.setVolume(vol);
142 original.setVolume(vol);
143 }
144
145 @Override // Object
146 public boolean equals(Object o) {
147 return super.equals(o);
148 }
149
150 @Override // Object
151 public int hashCode() {
152 return super.hashCode();
153 }
154
155 @Override
156 public String toString() {
157 return super.toString()
158 + "\n recoveryId=" + recoveryId
159 + "\n original=" + original;
160 }
161
162 public ReplicaRecoveryInfo createInfo() {
163 return new ReplicaRecoveryInfo(original.getBlockId(),
164 original.getBytesOnDisk(), original.getGenerationStamp(),
165 original.getState());
166 }
167 }