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.fs;
019
020 import java.io.DataInput;
021 import java.io.DataOutput;
022 import java.io.IOException;
023
024 import org.apache.hadoop.classification.InterfaceAudience;
025 import org.apache.hadoop.classification.InterfaceStability;
026 import org.apache.hadoop.io.Text;
027 import org.apache.hadoop.io.Writable;
028 import org.apache.hadoop.io.WritableFactories;
029 import org.apache.hadoop.io.WritableFactory;
030
031 /*
032 * A BlockLocation lists hosts, offset and length
033 * of block.
034 *
035 */
036 @InterfaceAudience.Public
037 @InterfaceStability.Stable
038 public class BlockLocation implements Writable {
039
040 static { // register a ctor
041 WritableFactories.setFactory
042 (BlockLocation.class,
043 new WritableFactory() {
044 public Writable newInstance() { return new BlockLocation(); }
045 });
046 }
047
048 private String[] hosts; //hostnames of datanodes
049 private String[] names; //hostname:portNumber of datanodes
050 private String[] topologyPaths; // full path name in network topology
051 private long offset; //offset of the of the block in the file
052 private long length;
053 private boolean corrupt;
054
055 /**
056 * Default Constructor
057 */
058 public BlockLocation() {
059 this(new String[0], new String[0], 0L, 0L);
060 }
061
062 /**
063 * Constructor with host, name, offset and length
064 */
065 public BlockLocation(String[] names, String[] hosts, long offset,
066 long length) {
067 this(names, hosts, offset, length, false);
068 }
069
070 /**
071 * Constructor with host, name, offset, length and corrupt flag
072 */
073 public BlockLocation(String[] names, String[] hosts, long offset,
074 long length, boolean corrupt) {
075 if (names == null) {
076 this.names = new String[0];
077 } else {
078 this.names = names;
079 }
080 if (hosts == null) {
081 this.hosts = new String[0];
082 } else {
083 this.hosts = hosts;
084 }
085 this.offset = offset;
086 this.length = length;
087 this.topologyPaths = new String[0];
088 this.corrupt = corrupt;
089 }
090
091 /**
092 * Constructor with host, name, network topology, offset and length
093 */
094 public BlockLocation(String[] names, String[] hosts, String[] topologyPaths,
095 long offset, long length) {
096 this(names, hosts, topologyPaths, offset, length, false);
097 }
098
099 /**
100 * Constructor with host, name, network topology, offset, length
101 * and corrupt flag
102 */
103 public BlockLocation(String[] names, String[] hosts, String[] topologyPaths,
104 long offset, long length, boolean corrupt) {
105 this(names, hosts, offset, length, corrupt);
106 if (topologyPaths == null) {
107 this.topologyPaths = new String[0];
108 } else {
109 this.topologyPaths = topologyPaths;
110 }
111 }
112
113 /**
114 * Get the list of hosts (hostname) hosting this block
115 */
116 public String[] getHosts() throws IOException {
117 if ((hosts == null) || (hosts.length == 0)) {
118 return new String[0];
119 } else {
120 return hosts;
121 }
122 }
123
124 /**
125 * Get the list of names (hostname:port) hosting this block
126 */
127 public String[] getNames() throws IOException {
128 if ((names == null) || (names.length == 0)) {
129 return new String[0];
130 } else {
131 return this.names;
132 }
133 }
134
135 /**
136 * Get the list of network topology paths for each of the hosts.
137 * The last component of the path is the host.
138 */
139 public String[] getTopologyPaths() throws IOException {
140 if ((topologyPaths == null) || (topologyPaths.length == 0)) {
141 return new String[0];
142 } else {
143 return this.topologyPaths;
144 }
145 }
146
147 /**
148 * Get the start offset of file associated with this block
149 */
150 public long getOffset() {
151 return offset;
152 }
153
154 /**
155 * Get the length of the block
156 */
157 public long getLength() {
158 return length;
159 }
160
161 /**
162 * Get the corrupt flag.
163 */
164 public boolean isCorrupt() {
165 return corrupt;
166 }
167
168 /**
169 * Set the start offset of file associated with this block
170 */
171 public void setOffset(long offset) {
172 this.offset = offset;
173 }
174
175 /**
176 * Set the length of block
177 */
178 public void setLength(long length) {
179 this.length = length;
180 }
181
182 /**
183 * Set the corrupt flag.
184 */
185 public void setCorrupt(boolean corrupt) {
186 this.corrupt = corrupt;
187 }
188
189 /**
190 * Set the hosts hosting this block
191 */
192 public void setHosts(String[] hosts) throws IOException {
193 if (hosts == null) {
194 this.hosts = new String[0];
195 } else {
196 this.hosts = hosts;
197 }
198 }
199
200 /**
201 * Set the names (host:port) hosting this block
202 */
203 public void setNames(String[] names) throws IOException {
204 if (names == null) {
205 this.names = new String[0];
206 } else {
207 this.names = names;
208 }
209 }
210
211 /**
212 * Set the network topology paths of the hosts
213 */
214 public void setTopologyPaths(String[] topologyPaths) throws IOException {
215 if (topologyPaths == null) {
216 this.topologyPaths = new String[0];
217 } else {
218 this.topologyPaths = topologyPaths;
219 }
220 }
221
222 /**
223 * Implement write of Writable
224 */
225 public void write(DataOutput out) throws IOException {
226 out.writeLong(offset);
227 out.writeLong(length);
228 out.writeBoolean(corrupt);
229 out.writeInt(names.length);
230 for (int i=0; i < names.length; i++) {
231 Text name = new Text(names[i]);
232 name.write(out);
233 }
234 out.writeInt(hosts.length);
235 for (int i=0; i < hosts.length; i++) {
236 Text host = new Text(hosts[i]);
237 host.write(out);
238 }
239 out.writeInt(topologyPaths.length);
240 for (int i=0; i < topologyPaths.length; i++) {
241 Text host = new Text(topologyPaths[i]);
242 host.write(out);
243 }
244 }
245
246 /**
247 * Implement readFields of Writable
248 */
249 public void readFields(DataInput in) throws IOException {
250 this.offset = in.readLong();
251 this.length = in.readLong();
252 this.corrupt = in.readBoolean();
253 int numNames = in.readInt();
254 this.names = new String[numNames];
255 for (int i = 0; i < numNames; i++) {
256 Text name = new Text();
257 name.readFields(in);
258 names[i] = name.toString();
259 }
260
261 int numHosts = in.readInt();
262 this.hosts = new String[numHosts];
263 for (int i = 0; i < numHosts; i++) {
264 Text host = new Text();
265 host.readFields(in);
266 hosts[i] = host.toString();
267 }
268
269 int numTops = in.readInt();
270 topologyPaths = new String[numTops];
271 for (int i = 0; i < numTops; i++) {
272 Text path = new Text();
273 path.readFields(in);
274 topologyPaths[i] = path.toString();
275 }
276 }
277
278 public String toString() {
279 StringBuilder result = new StringBuilder();
280 result.append(offset);
281 result.append(',');
282 result.append(length);
283 if (corrupt) {
284 result.append("(corrupt)");
285 }
286 for(String h: hosts) {
287 result.append(',');
288 result.append(h);
289 }
290 return result.toString();
291 }
292 }