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 }