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 }