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.io.hfile;
21
22 import java.io.DataInputStream;
23 import java.io.DataOutput;
24 import java.io.IOException;
25 import java.io.OutputStream;
26 import java.nio.ByteBuffer;
27
28 import org.apache.hadoop.classification.InterfaceAudience;
29 import org.apache.hadoop.hbase.util.Bytes;
30
31
32
33
34
35 @InterfaceAudience.Private
36 public enum BlockType {
37
38
39
40
41 DATA("DATABLK*", BlockCategory.DATA),
42
43
44 ENCODED_DATA("DATABLKE", BlockCategory.DATA) {
45 @Override
46 public int getId() {
47 return DATA.ordinal();
48 }
49 },
50
51
52 LEAF_INDEX("IDXLEAF2", BlockCategory.INDEX),
53
54
55 BLOOM_CHUNK("BLMFBLK2", BlockCategory.BLOOM),
56
57
58
59
60 META("METABLKc", BlockCategory.META),
61
62
63 INTERMEDIATE_INDEX("IDXINTE2", BlockCategory.INDEX),
64
65
66
67
68 ROOT_INDEX("IDXROOT2", BlockCategory.INDEX),
69
70
71 FILE_INFO("FILEINF2", BlockCategory.META),
72
73
74 GENERAL_BLOOM_META("BLMFMET2", BlockCategory.BLOOM),
75
76
77 DELETE_FAMILY_BLOOM_META("DFBLMET2", BlockCategory.BLOOM),
78
79
80
81
82 TRAILER("TRABLK\"$", BlockCategory.META),
83
84
85
86
87 INDEX_V1("IDXBLK)+", BlockCategory.INDEX);
88
89 public enum BlockCategory {
90 DATA, META, INDEX, BLOOM, ALL_CATEGORIES, UNKNOWN;
91
92
93
94
95
96 public void expectSpecific() {
97 if (this == ALL_CATEGORIES) {
98 throw new IllegalArgumentException("Expected a specific block " +
99 "category but got " + this);
100 }
101 }
102 }
103
104 public static final int MAGIC_LENGTH = 8;
105
106 private final byte[] magic;
107 private final BlockCategory metricCat;
108
109 private BlockType(String magicStr, BlockCategory metricCat) {
110 magic = Bytes.toBytes(magicStr);
111 this.metricCat = metricCat;
112 assert magic.length == MAGIC_LENGTH;
113 }
114
115
116
117
118
119
120
121 public int getId() {
122
123 return ordinal();
124 }
125
126 public void writeToStream(OutputStream out) throws IOException {
127 out.write(magic);
128 }
129
130 public void write(DataOutput out) throws IOException {
131 out.write(magic);
132 }
133
134 public void write(ByteBuffer buf) {
135 buf.put(magic);
136 }
137
138 public BlockCategory getCategory() {
139 return metricCat;
140 }
141
142 public static BlockType parse(byte[] buf, int offset, int length)
143 throws IOException {
144 if (length != MAGIC_LENGTH) {
145 throw new IOException("Magic record of invalid length: "
146 + Bytes.toStringBinary(buf, offset, length));
147 }
148
149 for (BlockType blockType : values())
150 if (Bytes.compareTo(blockType.magic, 0, MAGIC_LENGTH, buf, offset,
151 MAGIC_LENGTH) == 0)
152 return blockType;
153
154 throw new IOException("Invalid HFile block magic: "
155 + Bytes.toStringBinary(buf, offset, MAGIC_LENGTH));
156 }
157
158 public static BlockType read(DataInputStream in) throws IOException {
159 byte[] buf = new byte[MAGIC_LENGTH];
160 in.readFully(buf);
161 return parse(buf, 0, buf.length);
162 }
163
164 public static BlockType read(ByteBuffer buf) throws IOException {
165 BlockType blockType = parse(buf.array(),
166 buf.arrayOffset() + buf.position(),
167 Math.min(buf.limit() - buf.position(), MAGIC_LENGTH));
168
169
170 buf.position(buf.position() + MAGIC_LENGTH);
171 return blockType;
172 }
173
174
175
176
177
178
179
180
181 public int put(byte[] bytes, int offset) {
182 System.arraycopy(magic, 0, bytes, offset, MAGIC_LENGTH);
183 return offset + MAGIC_LENGTH;
184 }
185
186
187
188
189
190 public void readAndCheck(DataInputStream in) throws IOException {
191 byte[] buf = new byte[MAGIC_LENGTH];
192 in.readFully(buf);
193 if (Bytes.compareTo(buf, magic) != 0) {
194 throw new IOException("Invalid magic: expected "
195 + Bytes.toStringBinary(magic) + ", got " + Bytes.toStringBinary(buf));
196 }
197 }
198
199
200
201
202
203 public void readAndCheck(ByteBuffer in) throws IOException {
204 byte[] buf = new byte[MAGIC_LENGTH];
205 in.get(buf);
206 if (Bytes.compareTo(buf, magic) != 0) {
207 throw new IOException("Invalid magic: expected "
208 + Bytes.toStringBinary(magic) + ", got " + Bytes.toStringBinary(buf));
209 }
210 }
211
212
213
214
215 public final boolean isData() {
216 return this == DATA || this == ENCODED_DATA;
217 }
218
219 }