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 @Override
076 void write(RecordOutput rout, String tag) throws IOException {
077 rout.writeByte(typeVal, tag);
078 writeRest(rout, tag);
079 }
080
081 /*
082 * Writes rest of the struct (excluding type value).
083 * As an optimization, this method is directly called by RTI
084 * for the top level record so that we don't write out the byte
085 * indicating that this is a struct (since top level records are
086 * always structs).
087 */
088 void writeRest(RecordOutput rout, String tag) throws IOException {
089 rout.writeInt(typeInfos.size(), tag);
090 for (FieldTypeInfo ti : typeInfos) {
091 ti.write(rout, tag);
092 }
093 }
094
095 /*
096 * deserialize ourselves. Called by RTI.
097 */
098 void read(RecordInput rin, String tag) throws IOException {
099 // number of elements
100 int numElems = rin.readInt(tag);
101 for (int i=0; i<numElems; i++) {
102 typeInfos.add(genericReadTypeInfo(rin, tag));
103 }
104 }
105
106 // generic reader: reads the next TypeInfo object from stream and returns it
107 private FieldTypeInfo genericReadTypeInfo(RecordInput rin, String tag) throws IOException {
108 String fieldName = rin.readString(tag);
109 TypeID id = genericReadTypeID(rin, tag);
110 return new FieldTypeInfo(fieldName, id);
111 }
112
113 // generic reader: reads the next TypeID object from stream and returns it
114 private TypeID genericReadTypeID(RecordInput rin, String tag) throws IOException {
115 byte typeVal = rin.readByte(tag);
116 switch (typeVal) {
117 case TypeID.RIOType.BOOL:
118 return TypeID.BoolTypeID;
119 case TypeID.RIOType.BUFFER:
120 return TypeID.BufferTypeID;
121 case TypeID.RIOType.BYTE:
122 return TypeID.ByteTypeID;
123 case TypeID.RIOType.DOUBLE:
124 return TypeID.DoubleTypeID;
125 case TypeID.RIOType.FLOAT:
126 return TypeID.FloatTypeID;
127 case TypeID.RIOType.INT:
128 return TypeID.IntTypeID;
129 case TypeID.RIOType.LONG:
130 return TypeID.LongTypeID;
131 case TypeID.RIOType.MAP:
132 {
133 TypeID tIDKey = genericReadTypeID(rin, tag);
134 TypeID tIDValue = genericReadTypeID(rin, tag);
135 return new MapTypeID(tIDKey, tIDValue);
136 }
137 case TypeID.RIOType.STRING:
138 return TypeID.StringTypeID;
139 case TypeID.RIOType.STRUCT:
140 {
141 StructTypeID stID = new StructTypeID();
142 int numElems = rin.readInt(tag);
143 for (int i=0; i<numElems; i++) {
144 stID.add(genericReadTypeInfo(rin, tag));
145 }
146 return stID;
147 }
148 case TypeID.RIOType.VECTOR:
149 {
150 TypeID tID = genericReadTypeID(rin, tag);
151 return new VectorTypeID(tID);
152 }
153 default:
154 // shouldn't be here
155 throw new IOException("Unknown type read");
156 }
157 }
158
159 @Override
160 public boolean equals(Object o) {
161 return super.equals(o);
162 }
163
164 @Override
165 public int hashCode() { return super.hashCode(); }
166 }