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.IOException;
021    
022    import org.apache.hadoop.classification.InterfaceAudience;
023    import 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
032    public 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    }