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