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 019 package org.apache.hadoop.mapred.join; 020 021 import java.io.DataInput; 022 import java.io.DataOutput; 023 import java.io.IOException; 024 import java.util.HashSet; 025 026 import org.apache.hadoop.classification.InterfaceAudience; 027 import org.apache.hadoop.classification.InterfaceStability; 028 import org.apache.hadoop.io.Text; 029 import org.apache.hadoop.io.WritableUtils; 030 import org.apache.hadoop.mapred.InputSplit; 031 import org.apache.hadoop.util.ReflectionUtils; 032 033 /** 034 * This InputSplit contains a set of child InputSplits. Any InputSplit inserted 035 * into this collection must have a public default constructor. 036 * 037 * @deprecated Use 038 * {@link org.apache.hadoop.mapreduce.lib.join.CompositeInputSplit} instead 039 */ 040 @Deprecated 041 @InterfaceAudience.Public 042 @InterfaceStability.Stable 043 public class CompositeInputSplit implements InputSplit { 044 045 private int fill = 0; 046 private long totsize = 0L; 047 private InputSplit[] splits; 048 049 public CompositeInputSplit() { } 050 051 public CompositeInputSplit(int capacity) { 052 splits = new InputSplit[capacity]; 053 } 054 055 /** 056 * Add an InputSplit to this collection. 057 * @throws IOException If capacity was not specified during construction 058 * or if capacity has been reached. 059 */ 060 public void add(InputSplit s) throws IOException { 061 if (null == splits) { 062 throw new IOException("Uninitialized InputSplit"); 063 } 064 if (fill == splits.length) { 065 throw new IOException("Too many splits"); 066 } 067 splits[fill++] = s; 068 totsize += s.getLength(); 069 } 070 071 /** 072 * Get ith child InputSplit. 073 */ 074 public InputSplit get(int i) { 075 return splits[i]; 076 } 077 078 /** 079 * Return the aggregate length of all child InputSplits currently added. 080 */ 081 public long getLength() throws IOException { 082 return totsize; 083 } 084 085 /** 086 * Get the length of ith child InputSplit. 087 */ 088 public long getLength(int i) throws IOException { 089 return splits[i].getLength(); 090 } 091 092 /** 093 * Collect a set of hosts from all child InputSplits. 094 */ 095 public String[] getLocations() throws IOException { 096 HashSet<String> hosts = new HashSet<String>(); 097 for (InputSplit s : splits) { 098 String[] hints = s.getLocations(); 099 if (hints != null && hints.length > 0) { 100 for (String host : hints) { 101 hosts.add(host); 102 } 103 } 104 } 105 return hosts.toArray(new String[hosts.size()]); 106 } 107 108 /** 109 * getLocations from ith InputSplit. 110 */ 111 public String[] getLocation(int i) throws IOException { 112 return splits[i].getLocations(); 113 } 114 115 /** 116 * Write splits in the following format. 117 * {@code 118 * <count><class1><class2>...<classn><split1><split2>...<splitn> 119 * } 120 */ 121 public void write(DataOutput out) throws IOException { 122 WritableUtils.writeVInt(out, splits.length); 123 for (InputSplit s : splits) { 124 Text.writeString(out, s.getClass().getName()); 125 } 126 for (InputSplit s : splits) { 127 s.write(out); 128 } 129 } 130 131 /** 132 * {@inheritDoc} 133 * @throws IOException If the child InputSplit cannot be read, typically 134 * for faliing access checks. 135 */ 136 @SuppressWarnings("unchecked") // Generic array assignment 137 public void readFields(DataInput in) throws IOException { 138 int card = WritableUtils.readVInt(in); 139 if (splits == null || splits.length != card) { 140 splits = new InputSplit[card]; 141 } 142 Class<? extends InputSplit>[] cls = new Class[card]; 143 try { 144 for (int i = 0; i < card; ++i) { 145 cls[i] = 146 Class.forName(Text.readString(in)).asSubclass(InputSplit.class); 147 } 148 for (int i = 0; i < card; ++i) { 149 splits[i] = ReflectionUtils.newInstance(cls[i], null); 150 splits[i].readFields(in); 151 } 152 } catch (ClassNotFoundException e) { 153 throw (IOException)new IOException("Failed split init").initCause(e); 154 } 155 } 156 157 }