1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.types;
19
20 import java.util.Iterator;
21
22 import org.apache.hadoop.classification.InterfaceAudience;
23 import org.apache.hadoop.classification.InterfaceStability;
24 import org.apache.hadoop.hbase.util.Order;
25 import org.apache.hadoop.hbase.util.PositionedByteRange;
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 @InterfaceAudience.Public
55 @InterfaceStability.Evolving
56 public class Struct implements DataType<Object[]> {
57
58 @SuppressWarnings("rawtypes")
59 protected final DataType[] fields;
60 protected final boolean isOrderPreserving;
61 protected final boolean isSkippable;
62
63
64
65
66
67
68
69
70
71
72 @SuppressWarnings("rawtypes")
73 public Struct(DataType[] memberTypes) {
74 this.fields = memberTypes;
75
76 boolean preservesOrder = true;
77
78 boolean skippable = true;
79 for (int i = 0; i < this.fields.length; i++) {
80 DataType dt = this.fields[i];
81 if (!dt.isOrderPreserving()) preservesOrder = false;
82 if (i < this.fields.length - 2 && !dt.isSkippable()) {
83 throw new IllegalArgumentException("Field in position " + i
84 + " is not skippable. Non-right-most struct fields must be skippable.");
85 }
86 if (!dt.isSkippable()) skippable = false;
87 }
88 this.isOrderPreserving = preservesOrder;
89 this.isSkippable = skippable;
90 }
91
92 @Override
93 public boolean isOrderPreserving() { return isOrderPreserving; }
94
95 @Override
96 public Order getOrder() { return null; }
97
98 @Override
99 public boolean isNullable() { return false; }
100
101 @Override
102 public boolean isSkippable() { return isSkippable; }
103
104 @SuppressWarnings("unchecked")
105 @Override
106 public int encodedLength(Object[] val) {
107 assert fields.length == val.length;
108 int sum = 0;
109 for (int i = 0; i < fields.length; i++)
110 sum += fields[i].encodedLength(val[i]);
111 return sum;
112 }
113
114 @Override
115 public Class<Object[]> encodedClass() { return Object[].class; }
116
117
118
119
120
121 public StructIterator iterator(PositionedByteRange src) {
122 return new StructIterator(src, fields);
123 }
124
125 @Override
126 public int skip(PositionedByteRange src) {
127 StructIterator it = iterator(src);
128 int skipped = 0;
129 while (it.hasNext())
130 skipped += it.skip();
131 return skipped;
132 }
133
134 @Override
135 public Object[] decode(PositionedByteRange src) {
136 int i = 0;
137 Object[] ret = new Object[fields.length];
138 Iterator<Object> it = iterator(src);
139 while (it.hasNext())
140 ret[i++] = it.next();
141 return ret;
142 }
143
144
145
146
147 public Object decode(PositionedByteRange src, int index) {
148 assert index >= 0;
149 StructIterator it = iterator(src.shallowCopy());
150 for (; index > 0; index--)
151 it.skip();
152 return it.next();
153 }
154
155 @SuppressWarnings("unchecked")
156 @Override
157 public int encode(PositionedByteRange dst, Object[] val) {
158 assert fields.length == val.length;
159 int written = 0;
160 for (int i = 0; i < fields.length; i++) {
161 written += fields[i].encode(dst, val[i]);
162 }
163 return written;
164 }
165 }