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