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