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.util.Bytes;
29
30
31
32
33
34
35 public enum BlockType {
36
37
38
39
40 DATA("DATABLK*", BlockCategory.DATA),
41
42
43 ENCODED_DATA("DATABLKE", BlockCategory.DATA) {
44 @Override
45 public int getId() {
46 return DATA.ordinal();
47 }
48 },
49
50
51 LEAF_INDEX("IDXLEAF2", BlockCategory.INDEX),
52
53
54 BLOOM_CHUNK("BLMFBLK2", BlockCategory.BLOOM),
55
56
57
58
59 META("METABLKc", BlockCategory.META),
60
61
62 INTERMEDIATE_INDEX("IDXINTE2", BlockCategory.INDEX),
63
64
65
66
67 ROOT_INDEX("IDXROOT2", BlockCategory.INDEX),
68
69
70 FILE_INFO("FILEINF2", BlockCategory.META),
71
72
73 GENERAL_BLOOM_META("BLMFMET2", BlockCategory.BLOOM),
74
75
76 DELETE_FAMILY_BLOOM_META("DFBLMET2", BlockCategory.BLOOM),
77
78
79
80
81 TRAILER("TRABLK\"$", BlockCategory.META),
82
83
84
85
86 INDEX_V1("IDXBLK)+", BlockCategory.INDEX);
87
88 public enum BlockCategory {
89 DATA, META, INDEX, BLOOM, ALL_CATEGORIES, UNKNOWN;
90
91
92
93
94
95 public void expectSpecific() {
96 if (this == ALL_CATEGORIES) {
97 throw new IllegalArgumentException("Expected a specific block " +
98 "category but got " + this);
99 }
100 }
101 }
102
103 public static final int MAGIC_LENGTH = 8;
104
105 private final byte[] magic;
106 private final BlockCategory metricCat;
107
108 private BlockType(String magicStr, BlockCategory metricCat) {
109 magic = Bytes.toBytes(magicStr);
110 this.metricCat = metricCat;
111 assert magic.length == MAGIC_LENGTH;
112 }
113
114
115
116
117
118
119
120 public int getId() {
121
122 return ordinal();
123 }
124
125 public void writeToStream(OutputStream out) throws IOException {
126 out.write(magic);
127 }
128
129 public void write(DataOutput out) throws IOException {
130 out.write(magic);
131 }
132
133 public void write(ByteBuffer buf) {
134 buf.put(magic);
135 }
136
137 public BlockCategory getCategory() {
138 return metricCat;
139 }
140
141 public static BlockType parse(byte[] buf, int offset, int length)
142 throws IOException {
143 if (length != MAGIC_LENGTH) {
144 throw new IOException("Magic record of invalid length: "
145 + Bytes.toStringBinary(buf, offset, length));
146 }
147
148 for (BlockType blockType : values())
149 if (Bytes.compareTo(blockType.magic, 0, MAGIC_LENGTH, buf, offset,
150 MAGIC_LENGTH) == 0)
151 return blockType;
152
153 throw new IOException("Invalid HFile block magic: "
154 + Bytes.toStringBinary(buf, offset, MAGIC_LENGTH));
155 }
156
157 public static BlockType read(DataInputStream in) throws IOException {
158 byte[] buf = new byte[MAGIC_LENGTH];
159 in.readFully(buf);
160 return parse(buf, 0, buf.length);
161 }
162
163 public static BlockType read(ByteBuffer buf) throws IOException {
164 BlockType blockType = parse(buf.array(),
165 buf.arrayOffset() + buf.position(),
166 Math.min(buf.limit() - buf.position(), MAGIC_LENGTH));
167
168
169 buf.position(buf.position() + MAGIC_LENGTH);
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 }