PageRenderTime 23ms CodeModel.GetById 11ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/release-0.0.0-rc0/hive/external/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyUnion.java

#
Java | 165 lines | 83 code | 16 blank | 66 comment | 19 complexity | e122e3f1b6b0cdb25fcef66ba1b166e7 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 */
 18package org.apache.hadoop.hive.serde2.lazy;
 19
 20import org.apache.hadoop.hive.serde2.lazy.objectinspector.LazyUnionObjectInspector;
 21import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
 22import org.apache.hadoop.io.Text;
 23
 24/**
 25 * LazyObject for storing a union. The field of a union can be primitive or
 26 * non-primitive.
 27 *
 28 */
 29public class LazyUnion extends
 30    LazyNonPrimitive<LazyUnionObjectInspector> {
 31  /**
 32   * Whether the data is already parsed or not.
 33   */
 34  private boolean parsed;
 35
 36  /**
 37   * The start position of union field. Only valid when the data is parsed.
 38   */
 39  private int startPosition;
 40
 41  /**
 42   * The object of the union.
 43   */
 44  private LazyObject<? extends ObjectInspector> field;
 45
 46  /**
 47   * Tag of the Union
 48   */
 49  private byte tag;
 50
 51  /**
 52   * Whether init() has been called on the field or not.
 53   */
 54  private boolean fieldInited = false;
 55
 56  /**
 57   * Construct a LazyUnion object with the ObjectInspector.
 58   */
 59  public LazyUnion(LazyUnionObjectInspector oi) {
 60    super(oi);
 61  }
 62
 63  /**
 64   * Set the row data for this LazyUnion.
 65   *
 66   * @see LazyObject#init(ByteArrayRef, int, int)
 67   */
 68  @Override
 69  public void init(ByteArrayRef bytes, int start, int length) {
 70    super.init(bytes, start, length);
 71    parsed = false;
 72  }
 73
 74  /**
 75   * Parse the byte[] and fill each field.
 76   */
 77  @SuppressWarnings("unchecked")
 78  private void parse() {
 79
 80    byte separator = oi.getSeparator();
 81    boolean isEscaped = oi.isEscaped();
 82    byte escapeChar = oi.getEscapeChar();
 83    boolean tagStarted = false;
 84    boolean tagParsed = false;
 85    int tagStart = -1;
 86    int tagEnd = -1;
 87
 88    int unionByteEnd = start + length;
 89    int fieldByteEnd = start;
 90    byte[] bytes = this.bytes.getData();
 91    // Go through all bytes in the byte[]
 92    while (fieldByteEnd < unionByteEnd) {
 93      if (bytes[fieldByteEnd] != separator) {
 94        if (isEscaped && bytes[fieldByteEnd] == escapeChar
 95            && fieldByteEnd + 1 < unionByteEnd) {
 96          // ignore the char after escape_char
 97          fieldByteEnd += 1;
 98        } else {
 99          if (!tagStarted) {
100            tagStart = fieldByteEnd;
101            tagStarted = true;
102          }
103        }
104      } else { // (bytes[fieldByteEnd] == separator)
105        if (!tagParsed) {
106          // Reached the end of the tag
107          tagEnd = fieldByteEnd - 1;
108          startPosition = fieldByteEnd + 1;
109          tagParsed = true;
110        }
111      }
112      fieldByteEnd++;
113    }
114
115    tag = LazyByte.parseByte(bytes, tagStart, (tagEnd - tagStart) + 1);
116    field = LazyFactory.createLazyObject(oi.getObjectInspectors().get(tag));
117    fieldInited = false;
118    parsed = true;
119  }
120
121  /**
122   * Get the field out of the row without checking parsed.
123   *
124   * @return The value of the field
125   */
126  private Object uncheckedGetField() {
127    Text nullSequence = oi.getNullSequence();
128    int fieldLength = start + length - startPosition;
129    if (fieldLength != 0 && fieldLength == nullSequence.getLength() &&
130        LazyUtils.compare(bytes.getData(), startPosition, fieldLength,
131        nullSequence.getBytes(), 0, nullSequence.getLength()) == 0) {
132      return null;
133    }
134
135    if (!fieldInited) {
136      fieldInited = true;
137      field.init(bytes, startPosition, fieldLength);
138    }
139    return field.getObject();
140  }
141
142  /**
143   * Get the field out of the union.
144   *
145   * @return The field as a LazyObject
146   */
147  public Object getField() {
148    if (!parsed) {
149      parse();
150    }
151    return uncheckedGetField();
152  }
153
154  /**
155   * Get the tag of the union
156   *
157   * @return The tag byte
158   */
159  public byte getTag() {
160    if (!parsed) {
161      parse();
162    }
163    return tag;
164  }
165}