1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase;
21
22 import java.util.ArrayList;
23 import java.util.Iterator;
24 import java.util.List;
25
26 import org.apache.hadoop.hbase.classification.InterfaceAudience;
27 import org.apache.hadoop.hbase.classification.InterfaceStability;
28 import org.apache.hadoop.hbase.util.Bytes;
29
30
31
32
33 @InterfaceAudience.Private
34 @InterfaceStability.Evolving
35 public class Tag {
36 public final static int TYPE_LENGTH_SIZE = Bytes.SIZEOF_BYTE;
37 public final static int TAG_LENGTH_SIZE = Bytes.SIZEOF_SHORT;
38 public final static int INFRASTRUCTURE_SIZE = TYPE_LENGTH_SIZE + TAG_LENGTH_SIZE;
39 public static final int MAX_TAG_LENGTH = (2 * Short.MAX_VALUE) + 1 - TAG_LENGTH_SIZE;
40
41 private final byte type;
42 private final byte[] bytes;
43 private int offset = 0;
44 private int length = 0;
45
46
47
48
49
50 public Tag(byte tagType, String tag) {
51 this(tagType, Bytes.toBytes(tag));
52 }
53
54
55
56
57
58 public Tag(byte tagType, byte[] tag) {
59
60
61
62
63
64 int tagLength = tag.length + TYPE_LENGTH_SIZE;
65 if (tagLength > MAX_TAG_LENGTH) {
66 throw new IllegalArgumentException(
67 "Invalid tag data being passed. Its length can not exceed " + MAX_TAG_LENGTH);
68 }
69 length = TAG_LENGTH_SIZE + tagLength;
70 bytes = new byte[length];
71 int pos = Bytes.putAsShort(bytes, 0, tagLength);
72 pos = Bytes.putByte(bytes, pos, tagType);
73 Bytes.putBytes(bytes, pos, tag, 0, tag.length);
74 this.type = tagType;
75 }
76
77
78
79
80
81
82
83
84
85
86
87 public Tag(byte[] bytes, int offset) {
88 this(bytes, offset, getLength(bytes, offset));
89 }
90
91 private static int getLength(byte[] bytes, int offset) {
92 return TAG_LENGTH_SIZE + Bytes.readAsInt(bytes, offset, TAG_LENGTH_SIZE);
93 }
94
95
96
97
98
99
100
101
102
103
104
105
106 public Tag(byte[] bytes, int offset, int length) {
107 if (length > MAX_TAG_LENGTH) {
108 throw new IllegalArgumentException(
109 "Invalid tag data being passed. Its length can not exceed " + MAX_TAG_LENGTH);
110 }
111 this.bytes = bytes;
112 this.offset = offset;
113 this.length = length;
114 this.type = bytes[offset + TAG_LENGTH_SIZE];
115 }
116
117
118
119
120 public byte[] getBuffer() {
121 return this.bytes;
122 }
123
124
125
126
127 public byte getType() {
128 return this.type;
129 }
130
131
132
133
134 public int getTagLength() {
135 return this.length - INFRASTRUCTURE_SIZE;
136 }
137
138
139
140
141 public int getTagOffset() {
142 return this.offset + INFRASTRUCTURE_SIZE;
143 }
144
145
146
147
148
149
150
151
152 public byte[] getValue() {
153 int tagLength = getTagLength();
154 byte[] tag = new byte[tagLength];
155 Bytes.putBytes(tag, 0, bytes, getTagOffset(), tagLength);
156 return tag;
157 }
158
159
160
161
162
163
164
165
166
167 public static List<Tag> asList(byte[] b, int offset, int length) {
168 List<Tag> tags = new ArrayList<Tag>();
169 int pos = offset;
170 while (pos < offset + length) {
171 int tagLen = Bytes.readAsInt(b, pos, TAG_LENGTH_SIZE);
172 tags.add(new Tag(b, pos, tagLen + TAG_LENGTH_SIZE));
173 pos += TAG_LENGTH_SIZE + tagLen;
174 }
175 return tags;
176 }
177
178
179
180
181
182
183 public static byte[] fromList(List<Tag> tags) {
184 if (tags == null || tags.size() <= 0) return null;
185 int length = 0;
186 for (Tag tag: tags) {
187 length += tag.length;
188 }
189 byte[] b = new byte[length];
190 int pos = 0;
191 for (Tag tag: tags) {
192 System.arraycopy(tag.bytes, tag.offset, b, pos, tag.length);
193 pos += tag.length;
194 }
195 return b;
196 }
197
198
199
200
201
202
203
204
205
206 public static Tag getTag(byte[] b, int offset, int length, byte type) {
207 int pos = offset;
208 while (pos < offset + length) {
209 int tagLen = Bytes.readAsInt(b, pos, TAG_LENGTH_SIZE);
210 if(b[pos + TAG_LENGTH_SIZE] == type) {
211 return new Tag(b, pos, tagLen + TAG_LENGTH_SIZE);
212 }
213 pos += TAG_LENGTH_SIZE + tagLen;
214 }
215 return null;
216 }
217
218
219
220
221 int getLength() {
222 return this.length;
223 }
224
225
226
227
228 int getOffset() {
229 return this.offset;
230 }
231
232
233
234
235
236 public static List<Tag> carryForwardTags(final Cell cell) {
237 return carryForwardTags(null, cell);
238 }
239
240
241
242
243
244
245 public static List<Tag> carryForwardTags(final List<Tag> tagsOrNull, final Cell cell) {
246 List<Tag> tags = tagsOrNull;
247 if (cell.getTagsLength() <= 0) return tags;
248 Iterator<Tag> itr =
249 CellUtil.tagsIterator(cell.getTagsArray(), cell.getTagsOffset(), cell.getTagsLength());
250 if (tags == null) tags = new ArrayList<Tag>();
251 while (itr.hasNext()) {
252 tags.add(itr.next());
253 }
254 return tags;
255 }
256 }