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 019package org.apache.hadoop.record.meta; 020 021import java.io.IOException; 022import java.util.*; 023 024import org.apache.hadoop.classification.InterfaceAudience; 025import org.apache.hadoop.classification.InterfaceStability; 026import org.apache.hadoop.record.RecordInput; 027import org.apache.hadoop.record.RecordOutput; 028 029/** 030 * Represents typeID for a struct 031 * 032 * @deprecated Replaced by <a href="https://hadoop.apache.org/avro/">Avro</a>. 033 */ 034@Deprecated 035@InterfaceAudience.Public 036@InterfaceStability.Stable 037public 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}