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 long offset;  // Offset of the block in the file
038  private long length;
039  private boolean corrupt;
040
041  private static final String[] EMPTY_STR_ARRAY = new String[0];
042
043  /**
044   * Default Constructor
045   */
046  public BlockLocation() {
047    this(EMPTY_STR_ARRAY, EMPTY_STR_ARRAY, 0L, 0L);
048  }
049
050  /**
051   * Copy constructor
052   */
053  public BlockLocation(BlockLocation that) {
054    this.hosts = that.hosts;
055    this.cachedHosts = that.cachedHosts;
056    this.names = that.names;
057    this.topologyPaths = that.topologyPaths;
058    this.offset = that.offset;
059    this.length = that.length;
060    this.corrupt = that.corrupt;
061  }
062
063  /**
064   * Constructor with host, name, offset and length
065   */
066  public BlockLocation(String[] names, String[] hosts, long offset, 
067                       long length) {
068    this(names, hosts, offset, length, false);
069  }
070
071  /**
072   * Constructor with host, name, offset, length and corrupt flag
073   */
074  public BlockLocation(String[] names, String[] hosts, long offset, 
075                       long length, boolean corrupt) {
076    this(names, hosts, null, offset, length, corrupt);
077  }
078
079  /**
080   * Constructor with host, name, network topology, offset and length
081   */
082  public BlockLocation(String[] names, String[] hosts, String[] topologyPaths,
083                       long offset, long length) {
084    this(names, hosts, topologyPaths, offset, length, false);
085  }
086
087  /**
088   * Constructor with host, name, network topology, offset, length 
089   * and corrupt flag
090   */
091  public BlockLocation(String[] names, String[] hosts, String[] topologyPaths,
092                       long offset, long length, boolean corrupt) {
093    this(names, hosts, null, topologyPaths, offset, length, corrupt);
094  }
095
096  public BlockLocation(String[] names, String[] hosts, String[] cachedHosts,
097      String[] topologyPaths, long offset, long length, boolean corrupt) {
098    if (names == null) {
099      this.names = EMPTY_STR_ARRAY;
100    } else {
101      this.names = names;
102    }
103    if (hosts == null) {
104      this.hosts = EMPTY_STR_ARRAY;
105    } else {
106      this.hosts = hosts;
107    }
108    if (cachedHosts == null) {
109      this.cachedHosts = EMPTY_STR_ARRAY;
110    } else {
111      this.cachedHosts = cachedHosts;
112    }
113    if (topologyPaths == null) {
114      this.topologyPaths = EMPTY_STR_ARRAY;
115    } else {
116      this.topologyPaths = topologyPaths;
117    }
118    this.offset = offset;
119    this.length = length;
120    this.corrupt = corrupt;
121  }
122
123  /**
124   * Get the list of hosts (hostname) hosting this block
125   */
126  public String[] getHosts() throws IOException {
127    return hosts;
128  }
129
130  /**
131   * Get the list of hosts (hostname) hosting a cached replica of the block
132   */
133  public String[] getCachedHosts() {
134   return cachedHosts;
135  }
136
137  /**
138   * Get the list of names (IP:xferPort) hosting this block
139   */
140  public String[] getNames() throws IOException {
141    return names;
142  }
143
144  /**
145   * Get the list of network topology paths for each of the hosts.
146   * The last component of the path is the "name" (IP:xferPort).
147   */
148  public String[] getTopologyPaths() throws IOException {
149    return topologyPaths;
150  }
151  
152  /**
153   * Get the start offset of file associated with this block
154   */
155  public long getOffset() {
156    return offset;
157  }
158  
159  /**
160   * Get the length of the block
161   */
162  public long getLength() {
163    return length;
164  }
165
166  /**
167   * Get the corrupt flag.
168   */
169  public boolean isCorrupt() {
170    return corrupt;
171  }
172
173  /**
174   * Set the start offset of file associated with this block
175   */
176  public void setOffset(long offset) {
177    this.offset = offset;
178  }
179
180  /**
181   * Set the length of block
182   */
183  public void setLength(long length) {
184    this.length = length;
185  }
186
187  /**
188   * Set the corrupt flag.
189   */
190  public void setCorrupt(boolean corrupt) {
191    this.corrupt = corrupt;
192  }
193
194  /**
195   * Set the hosts hosting this block
196   */
197  public void setHosts(String[] hosts) throws IOException {
198    if (hosts == null) {
199      this.hosts = EMPTY_STR_ARRAY;
200    } else {
201      this.hosts = hosts;
202    }
203  }
204
205  /**
206   * Set the hosts hosting a cached replica of this block
207   */
208  public void setCachedHosts(String[] cachedHosts) {
209    if (cachedHosts == null) {
210      this.cachedHosts = EMPTY_STR_ARRAY;
211    } else {
212      this.cachedHosts = cachedHosts;
213    }
214  }
215
216  /**
217   * Set the names (host:port) hosting this block
218   */
219  public void setNames(String[] names) throws IOException {
220    if (names == null) {
221      this.names = EMPTY_STR_ARRAY;
222    } else {
223      this.names = names;
224    }
225  }
226
227  /**
228   * Set the network topology paths of the hosts
229   */
230  public void setTopologyPaths(String[] topologyPaths) throws IOException {
231    if (topologyPaths == null) {
232      this.topologyPaths = EMPTY_STR_ARRAY;
233    } else {
234      this.topologyPaths = topologyPaths;
235    }
236  }
237
238  @Override
239  public String toString() {
240    StringBuilder result = new StringBuilder();
241    result.append(offset);
242    result.append(',');
243    result.append(length);
244    if (corrupt) {
245      result.append("(corrupt)");
246    }
247    for(String h: hosts) {
248      result.append(',');
249      result.append(h);
250    }
251    return result.toString();
252  }
253}