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