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