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.record.meta;
020    
021    import java.io.IOException;
022    import java.util.*;
023    
024    import org.apache.hadoop.classification.InterfaceAudience;
025    import org.apache.hadoop.classification.InterfaceStability;
026    import org.apache.hadoop.record.RecordInput;
027    import org.apache.hadoop.record.RecordOutput;
028    
029    /** 
030     * Represents typeID for a struct 
031     * 
032     * @deprecated Replaced by <a href="http://hadoop.apache.org/avro/">Avro</a>.
033     */
034    @Deprecated
035    @InterfaceAudience.Public
036    @InterfaceStability.Stable
037    public class StructTypeID extends TypeID {
038      private ArrayList<FieldTypeInfo> typeInfos = new ArrayList<FieldTypeInfo>();
039      
040      StructTypeID() {
041        super(RIOType.STRUCT);
042      }
043      
044      /**
045       * Create a StructTypeID based on the RecordTypeInfo of some record
046       */
047      public StructTypeID(RecordTypeInfo rti) {
048        super(RIOType.STRUCT);
049        typeInfos.addAll(rti.getFieldTypeInfos());
050      }
051    
052      void add (FieldTypeInfo ti) {
053        typeInfos.add(ti);
054      }
055      
056      public Collection<FieldTypeInfo> getFieldTypeInfos() {
057        return typeInfos;
058      }
059      
060      /* 
061       * return the StructTypeiD, if any, of the given field 
062       */
063      StructTypeID findStruct(String name) {
064        // walk through the list, searching. Not the most efficient way, but this
065        // in intended to be used rarely, so we keep it simple. 
066        // As an optimization, we can keep a hashmap of record name to its RTI, for later.
067        for (FieldTypeInfo ti : typeInfos) {
068          if ((0 == ti.getFieldID().compareTo(name)) && (ti.getTypeID().getTypeVal() == RIOType.STRUCT)) {
069            return (StructTypeID) ti.getTypeID();
070          }
071        }
072        return null;
073      }
074      
075      void write(RecordOutput rout, String tag) throws IOException {
076        rout.writeByte(typeVal, tag);
077        writeRest(rout, tag);
078      }
079    
080      /* 
081       * Writes rest of the struct (excluding type value).
082       * As an optimization, this method is directly called by RTI 
083       * for the top level record so that we don't write out the byte
084       * indicating that this is a struct (since top level records are
085       * always structs).
086       */
087      void writeRest(RecordOutput rout, String tag) throws IOException {
088        rout.writeInt(typeInfos.size(), tag);
089        for (FieldTypeInfo ti : typeInfos) {
090          ti.write(rout, tag);
091        }
092      }
093    
094      /* 
095       * deserialize ourselves. Called by RTI. 
096       */
097      void read(RecordInput rin, String tag) throws IOException {
098        // number of elements
099        int numElems = rin.readInt(tag);
100        for (int i=0; i<numElems; i++) {
101          typeInfos.add(genericReadTypeInfo(rin, tag));
102        }
103      }
104      
105      // generic reader: reads the next TypeInfo object from stream and returns it
106      private FieldTypeInfo genericReadTypeInfo(RecordInput rin, String tag) throws IOException {
107        String fieldName = rin.readString(tag);
108        TypeID id = genericReadTypeID(rin, tag);
109        return new FieldTypeInfo(fieldName, id);
110      }
111      
112      // generic reader: reads the next TypeID object from stream and returns it
113      private TypeID genericReadTypeID(RecordInput rin, String tag) throws IOException {
114        byte typeVal = rin.readByte(tag);
115        switch (typeVal) {
116        case TypeID.RIOType.BOOL: 
117          return TypeID.BoolTypeID;
118        case TypeID.RIOType.BUFFER: 
119          return TypeID.BufferTypeID;
120        case TypeID.RIOType.BYTE:
121          return TypeID.ByteTypeID;
122        case TypeID.RIOType.DOUBLE:
123          return TypeID.DoubleTypeID;
124        case TypeID.RIOType.FLOAT:
125          return TypeID.FloatTypeID;
126        case TypeID.RIOType.INT: 
127          return TypeID.IntTypeID;
128        case TypeID.RIOType.LONG:
129          return TypeID.LongTypeID;
130        case TypeID.RIOType.MAP:
131        {
132          TypeID tIDKey = genericReadTypeID(rin, tag);
133          TypeID tIDValue = genericReadTypeID(rin, tag);
134          return new MapTypeID(tIDKey, tIDValue);
135        }
136        case TypeID.RIOType.STRING: 
137          return TypeID.StringTypeID;
138        case TypeID.RIOType.STRUCT: 
139        {
140          StructTypeID stID = new StructTypeID();
141          int numElems = rin.readInt(tag);
142          for (int i=0; i<numElems; i++) {
143            stID.add(genericReadTypeInfo(rin, tag));
144          }
145          return stID;
146        }
147        case TypeID.RIOType.VECTOR: 
148        {
149          TypeID tID = genericReadTypeID(rin, tag);
150          return new VectorTypeID(tID);
151        }
152        default:
153          // shouldn't be here
154          throw new IOException("Unknown type read");
155        }
156      }
157      
158      public boolean equals(Object o) {
159        return super.equals(o);
160      }
161      
162      public int hashCode() { return super.hashCode(); }
163    }