PageRenderTime 27ms CodeModel.GetById 12ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/release-0.1-rc2/hive/external/serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/ObjectInspectorConverters.java

#
Java | 313 lines | 209 code | 42 blank | 62 comment | 20 complexity | 14a024c414d42874623962b2579ea71d MD5 | raw file
  1/**
  2 * Licensed to the Apache Software Foundation (ASF) under one
  3 * or more contributor license agreements.  See the NOTICE file
  4 * distributed with this work for additional information
  5 * regarding copyright ownership.  The ASF licenses this file
  6 * to you under the Apache License, Version 2.0 (the
  7 * "License"); you may not use this file except in compliance
  8 * with the License.  You may obtain a copy of the License at
  9 *
 10 *     http://www.apache.org/licenses/LICENSE-2.0
 11 *
 12 * Unless required by applicable law or agreed to in writing, software
 13 * distributed under the License is distributed on an "AS IS" BASIS,
 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15 * See the License for the specific language governing permissions and
 16 * limitations under the License.
 17 */
 18
 19package org.apache.hadoop.hive.serde2.objectinspector;
 20
 21import java.util.ArrayList;
 22import java.util.List;
 23import java.util.Map;
 24
 25import org.apache.hadoop.hive.serde2.objectinspector.primitive.JavaStringObjectInspector;
 26import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorConverter;
 27import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableBooleanObjectInspector;
 28import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableByteObjectInspector;
 29import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableDoubleObjectInspector;
 30import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableFloatObjectInspector;
 31import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableIntObjectInspector;
 32import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableLongObjectInspector;
 33import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableShortObjectInspector;
 34import org.apache.hadoop.hive.serde2.objectinspector.primitive.WritableStringObjectInspector;
 35
 36/**
 37 * ObjectInspectorConverters.
 38 *
 39 */
 40public final class ObjectInspectorConverters {
 41
 42  /**
 43   * A converter which will convert objects with one ObjectInspector to another.
 44   */
 45  public static interface Converter {
 46    Object convert(Object input);
 47  }
 48
 49  /**
 50   * IdentityConverter.
 51   *
 52   */
 53  public static class IdentityConverter implements Converter {
 54    public Object convert(Object input) {
 55      return input;
 56    }
 57  }
 58
 59  /**
 60   * Returns a converter that converts objects from one OI to another OI. The
 61   * returned (converted) object belongs to this converter, so that it can be
 62   * reused across different calls.
 63   */
 64  public static Converter getConverter(ObjectInspector inputOI,
 65      ObjectInspector outputOI) {
 66    // If the inputOI is the same as the outputOI, just return an
 67    // IdentityConverter.
 68    if (inputOI == outputOI) {
 69      return new IdentityConverter();
 70    }
 71    switch (outputOI.getCategory()) {
 72    case PRIMITIVE:
 73      switch (((PrimitiveObjectInspector) outputOI).getPrimitiveCategory()) {
 74      case BOOLEAN:
 75        return new PrimitiveObjectInspectorConverter.BooleanConverter(
 76            (PrimitiveObjectInspector) inputOI,
 77            (SettableBooleanObjectInspector) outputOI);
 78      case BYTE:
 79        return new PrimitiveObjectInspectorConverter.ByteConverter(
 80            (PrimitiveObjectInspector) inputOI,
 81            (SettableByteObjectInspector) outputOI);
 82      case SHORT:
 83        return new PrimitiveObjectInspectorConverter.ShortConverter(
 84            (PrimitiveObjectInspector) inputOI,
 85            (SettableShortObjectInspector) outputOI);
 86      case INT:
 87        return new PrimitiveObjectInspectorConverter.IntConverter(
 88            (PrimitiveObjectInspector) inputOI,
 89            (SettableIntObjectInspector) outputOI);
 90      case LONG:
 91        return new PrimitiveObjectInspectorConverter.LongConverter(
 92            (PrimitiveObjectInspector) inputOI,
 93            (SettableLongObjectInspector) outputOI);
 94      case FLOAT:
 95        return new PrimitiveObjectInspectorConverter.FloatConverter(
 96            (PrimitiveObjectInspector) inputOI,
 97            (SettableFloatObjectInspector) outputOI);
 98      case DOUBLE:
 99        return new PrimitiveObjectInspectorConverter.DoubleConverter(
100            (PrimitiveObjectInspector) inputOI,
101            (SettableDoubleObjectInspector) outputOI);
102      case STRING:
103        if (outputOI instanceof WritableStringObjectInspector) {
104          return new PrimitiveObjectInspectorConverter.TextConverter(
105              (PrimitiveObjectInspector) inputOI);
106        } else if (outputOI instanceof JavaStringObjectInspector) {
107          return new PrimitiveObjectInspectorConverter.StringConverter(
108              (PrimitiveObjectInspector) inputOI);
109        }
110      default:
111        throw new RuntimeException("Hive internal error: conversion of "
112            + inputOI.getTypeName() + " to " + outputOI.getTypeName()
113            + " not supported yet.");
114      }
115    case STRUCT:
116      return new StructConverter((StructObjectInspector) inputOI,
117          (SettableStructObjectInspector) outputOI);
118    case LIST:
119      return new ListConverter((ListObjectInspector) inputOI,
120          (SettableListObjectInspector) outputOI);
121    case MAP:
122      return new MapConverter((MapObjectInspector) inputOI,
123          (SettableMapObjectInspector) outputOI);
124    default:
125      throw new RuntimeException("Hive internal error: conversion of "
126          + inputOI.getTypeName() + " to " + outputOI.getTypeName()
127          + " not supported yet.");
128    }
129  }
130
131  /**
132   * A converter class for List.
133   */
134  public static class ListConverter implements Converter {
135
136    ListObjectInspector inputOI;
137    SettableListObjectInspector outputOI;
138
139    ObjectInspector inputElementOI;
140    ObjectInspector outputElementOI;
141
142    ArrayList<Converter> elementConverters;
143
144    Object output;
145
146    public ListConverter(ListObjectInspector inputOI,
147        SettableListObjectInspector outputOI) {
148      this.inputOI = inputOI;
149      this.outputOI = outputOI;
150      inputElementOI = inputOI.getListElementObjectInspector();
151      outputElementOI = outputOI.getListElementObjectInspector();
152      output = outputOI.create(0);
153      elementConverters = new ArrayList<Converter>();
154    }
155
156    @Override
157    public Object convert(Object input) {
158      if (input == null) {
159        return null;
160      }
161      // Create enough elementConverters
162      // NOTE: we have to have a separate elementConverter for each element,
163      // because the elementConverters can reuse the internal object.
164      // So it's not safe to use the same elementConverter to convert multiple
165      // elements.
166      int size = inputOI.getListLength(input);
167      while (elementConverters.size() < size) {
168        elementConverters.add(getConverter(inputElementOI, outputElementOI));
169      }
170
171      // Convert the elements
172      outputOI.resize(output, size);
173      for (int index = 0; index < size; index++) {
174        Object inputElement = inputOI.getListElement(input, index);
175        Object outputElement = elementConverters.get(index).convert(
176            inputElement);
177        outputOI.set(output, index, outputElement);
178      }
179      return output;
180    }
181
182  }
183
184  /**
185   * A converter class for Struct.
186   */
187  public static class StructConverter implements Converter {
188
189    StructObjectInspector inputOI;
190    SettableStructObjectInspector outputOI;
191
192    List<? extends StructField> inputFields;
193    List<? extends StructField> outputFields;
194
195    ArrayList<Converter> fieldConverters;
196
197    Object output;
198
199    public StructConverter(StructObjectInspector inputOI,
200        SettableStructObjectInspector outputOI) {
201
202      this.inputOI = inputOI;
203      this.outputOI = outputOI;
204      inputFields = inputOI.getAllStructFieldRefs();
205      outputFields = outputOI.getAllStructFieldRefs();
206      assert (inputFields.size() == outputFields.size());
207
208      fieldConverters = new ArrayList<Converter>(inputFields.size());
209      for (int f = 0; f < inputFields.size(); f++) {
210        fieldConverters.add(getConverter(inputFields.get(f)
211            .getFieldObjectInspector(), outputFields.get(f)
212            .getFieldObjectInspector()));
213      }
214      output = outputOI.create();
215    }
216
217    @Override
218    public Object convert(Object input) {
219      if (input == null) {
220        return null;
221      }
222
223      // Convert the fields
224      for (int f = 0; f < inputFields.size(); f++) {
225        Object inputFieldValue = inputOI.getStructFieldData(input, inputFields
226            .get(f));
227        Object outputFieldValue = fieldConverters.get(f).convert(
228            inputFieldValue);
229        outputOI.setStructFieldData(output, outputFields.get(f),
230            outputFieldValue);
231      }
232      return output;
233    }
234  }
235
236  /**
237   * A converter class for Map.
238   */
239  public static class MapConverter implements Converter {
240
241    MapObjectInspector inputOI;
242    SettableMapObjectInspector outputOI;
243
244    ObjectInspector inputKeyOI;
245    ObjectInspector outputKeyOI;
246
247    ObjectInspector inputValueOI;
248    ObjectInspector outputValueOI;
249
250    ArrayList<Converter> keyConverters;
251    ArrayList<Converter> valueConverters;
252
253    Object output;
254
255    public MapConverter(MapObjectInspector inputOI,
256        SettableMapObjectInspector outputOI) {
257      this.inputOI = inputOI;
258      this.outputOI = outputOI;
259      inputKeyOI = inputOI.getMapKeyObjectInspector();
260      outputKeyOI = outputOI.getMapKeyObjectInspector();
261      inputValueOI = inputOI.getMapValueObjectInspector();
262      outputValueOI = outputOI.getMapValueObjectInspector();
263      keyConverters = new ArrayList<Converter>();
264      valueConverters = new ArrayList<Converter>();
265      output = outputOI.create();
266    }
267
268    @Override
269    public Object convert(Object input) {
270      if (input == null) {
271        return null;
272      }
273      // Create enough keyConverters/valueConverters
274      // NOTE: we have to have a separate key/valueConverter for each key/value,
275      // because the key/valueConverters can reuse the internal object.
276      // So it's not safe to use the same key/valueConverter to convert multiple
277      // key/values.
278
279      // NOTE: This code tries to get all key-value pairs out of the map.
280      // It's not very efficient. The more efficient way should be to let MapOI
281      // return an Iterator. This is currently not supported by MapOI yet.
282
283      Map<?, ?> map = inputOI.getMap(input);
284      int size = map.size();
285
286      while (keyConverters.size() < size) {
287        keyConverters.add(getConverter(inputKeyOI, outputKeyOI));
288        valueConverters.add(getConverter(inputValueOI, outputValueOI));
289      }
290
291      // CLear the output
292      outputOI.clear(output);
293
294      // Convert the key/value pairs
295      int entryID = 0;
296      for (Map.Entry<?, ?> entry : map.entrySet()) {
297        Object inputKey = entry.getKey();
298        Object inputValue = entry.getValue();
299        Object outputKey = keyConverters.get(entryID).convert(inputKey);
300        Object outputValue = valueConverters.get(entryID).convert(inputValue);
301        entryID++;
302        outputOI.put(output, outputKey, outputValue);
303      }
304      return output;
305    }
306
307  }
308
309  private ObjectInspectorConverters() {
310    // prevent instantiation
311  }
312
313}