1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.hadoop.hbase.io.encoding;
18
19 import java.io.IOException;
20 import java.io.OutputStream;
21
22 import org.apache.hadoop.hbase.classification.InterfaceAudience;
23 import org.apache.hadoop.hbase.classification.InterfaceStability;
24 import org.apache.hadoop.hbase.util.Bytes;
25
26
27
28
29
30
31
32 @InterfaceAudience.Public
33 @InterfaceStability.Evolving
34 public enum DataBlockEncoding {
35
36
37 NONE(0, null),
38
39 PREFIX(2, "org.apache.hadoop.hbase.io.encoding.PrefixKeyDeltaEncoder"),
40 DIFF(3, "org.apache.hadoop.hbase.io.encoding.DiffKeyDeltaEncoder"),
41 FAST_DIFF(4, "org.apache.hadoop.hbase.io.encoding.FastDiffDeltaEncoder"),
42
43
44 PREFIX_TREE(6, "org.apache.hadoop.hbase.codec.prefixtree.PrefixTreeCodec"),
45 ROW_INDEX_V1(7, "org.apache.hadoop.hbase.io.encoding.RowIndexCodecV1");
46
47 private final short id;
48 private final byte[] idInBytes;
49 private DataBlockEncoder encoder;
50 private final String encoderCls;
51
52 public static final int ID_SIZE = Bytes.SIZEOF_SHORT;
53
54
55 private static DataBlockEncoding[] idArray = new DataBlockEncoding[Byte.MAX_VALUE + 1];
56
57 static {
58 for (DataBlockEncoding algo : values()) {
59 if (idArray[algo.id] != null) {
60 throw new RuntimeException(String.format(
61 "Two data block encoder algorithms '%s' and '%s' have " + "the same id %d",
62 idArray[algo.id].toString(), algo.toString(), (int) algo.id));
63 }
64 idArray[algo.id] = algo;
65 }
66 }
67
68 private DataBlockEncoding(int id, String encoderClsName) {
69 if (id < 0 || id > Byte.MAX_VALUE) {
70 throw new AssertionError(
71 "Data block encoding algorithm id is out of range: " + id);
72 }
73 this.id = (short) id;
74 this.idInBytes = Bytes.toBytes(this.id);
75 if (idInBytes.length != ID_SIZE) {
76
77
78 throw new RuntimeException("Unexpected length of encoder ID byte " +
79 "representation: " + Bytes.toStringBinary(idInBytes));
80 }
81 this.encoderCls = encoderClsName;
82 }
83
84
85
86
87 public byte[] getNameInBytes() {
88 return Bytes.toBytes(toString());
89 }
90
91
92
93
94 public short getId() {
95 return id;
96 }
97
98
99
100
101
102 public void writeIdInBytes(OutputStream stream) throws IOException {
103 stream.write(idInBytes);
104 }
105
106
107
108
109
110
111
112
113
114 public void writeIdInBytes(byte[] dest, int offset) throws IOException {
115 System.arraycopy(idInBytes, 0, dest, offset, ID_SIZE);
116 }
117
118
119
120
121
122
123 public DataBlockEncoder getEncoder() {
124 if (encoder == null && id != 0) {
125
126 encoder = createEncoder(encoderCls);
127 }
128 return encoder;
129 }
130
131
132
133
134
135
136 public static DataBlockEncoder getDataBlockEncoderById(short encoderId) {
137 return getEncodingById(encoderId).getEncoder();
138 }
139
140
141
142
143
144
145 public static String getNameFromId(short encoderId) {
146 return getEncodingById(encoderId).toString();
147 }
148
149
150
151
152
153
154
155
156
157 public static boolean isCorrectEncoder(DataBlockEncoder encoder,
158 short encoderId) {
159 DataBlockEncoding algorithm = getEncodingById(encoderId);
160 String encoderCls = encoder.getClass().getName();
161 return encoderCls.equals(algorithm.encoderCls);
162 }
163
164 public static DataBlockEncoding getEncodingById(short dataBlockEncodingId) {
165 DataBlockEncoding algorithm = null;
166 if (dataBlockEncodingId >= 0 && dataBlockEncodingId <= Byte.MAX_VALUE) {
167 algorithm = idArray[dataBlockEncodingId];
168 }
169 if (algorithm == null) {
170 throw new IllegalArgumentException(String.format(
171 "There is no data block encoder for given id '%d'",
172 (int) dataBlockEncodingId));
173 }
174 return algorithm;
175 }
176
177 protected static DataBlockEncoder createEncoder(String fullyQualifiedClassName){
178 try {
179 return (DataBlockEncoder)Class.forName(fullyQualifiedClassName)
180 .getDeclaredConstructor().newInstance();
181 } catch (Exception e) {
182 throw new RuntimeException(e);
183 }
184 }
185
186 }