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