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 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25
26 import org.apache.hadoop.hbase.util.Bytes;
27
28
29
30
31
32
33
34 public enum DataBlockEncoding {
35
36
37 NONE(0, null),
38
39 PREFIX(2, new PrefixKeyDeltaEncoder()),
40 DIFF(3, new DiffKeyDeltaEncoder()),
41 FAST_DIFF(4, new FastDiffDeltaEncoder());
42
43 private final short id;
44 private final byte[] idInBytes;
45 private final DataBlockEncoder encoder;
46
47 public static final int ID_SIZE = Bytes.SIZEOF_SHORT;
48
49
50 private static Map<Short, DataBlockEncoding> idToEncoding =
51 new HashMap<Short, DataBlockEncoding>();
52
53 static {
54 for (DataBlockEncoding algo : values()) {
55 if (idToEncoding.containsKey(algo.id)) {
56 throw new RuntimeException(String.format(
57 "Two data block encoder algorithms '%s' and '%s' have " +
58 "the same id %d",
59 idToEncoding.get(algo.id).toString(), algo.toString(),
60 (int) algo.id));
61 }
62 idToEncoding.put(algo.id, algo);
63 }
64 }
65
66 private DataBlockEncoding(int id, DataBlockEncoder encoder) {
67 if (id < Short.MIN_VALUE || id > Short.MAX_VALUE) {
68 throw new AssertionError(
69 "Data block encoding algorithm id is out of range: " + id);
70 }
71 this.id = (short) id;
72 this.idInBytes = Bytes.toBytes(this.id);
73 if (idInBytes.length != ID_SIZE) {
74
75
76 throw new RuntimeException("Unexpected length of encoder ID byte " +
77 "representation: " + Bytes.toStringBinary(idInBytes));
78 }
79 this.encoder = encoder;
80 }
81
82
83
84
85 public byte[] getNameInBytes() {
86 return Bytes.toBytes(toString());
87 }
88
89
90
91
92 public short getId() {
93 return id;
94 }
95
96
97
98
99
100 public void writeIdInBytes(OutputStream stream) throws IOException {
101 stream.write(idInBytes);
102 }
103
104
105
106
107
108
109 public DataBlockEncoder getEncoder() {
110 return encoder;
111 }
112
113
114
115
116
117
118 public static List<DataBlockEncoder> getAllEncoders() {
119 ArrayList<DataBlockEncoder> encoders = new ArrayList<DataBlockEncoder>();
120 for (DataBlockEncoding algo : values()) {
121 DataBlockEncoder encoder = algo.getEncoder();
122 if (encoder != null) {
123 encoders.add(encoder);
124 }
125 }
126
127
128 encoders.add(new CopyKeyDataBlockEncoder());
129 return encoders;
130 }
131
132
133
134
135
136
137 public static DataBlockEncoder getDataBlockEncoderById(short encoderId) {
138 if (!idToEncoding.containsKey(encoderId)) {
139 throw new IllegalArgumentException(String.format(
140 "There is no data block encoder for given id '%d'",
141 (int) encoderId));
142 }
143
144 return idToEncoding.get(encoderId).getEncoder();
145 }
146
147
148
149
150
151
152 public static String getNameFromId(short encoderId) {
153 return idToEncoding.get(encoderId).toString();
154 }
155
156
157
158
159
160
161
162
163
164 public static boolean isCorrectEncoder(DataBlockEncoder encoder,
165 short encoderId) {
166 if (!idToEncoding.containsKey(encoderId)) {
167 throw new IllegalArgumentException(String.format(
168 "There is no data block encoder for given id '%d'",
169 (int) encoderId));
170 }
171
172 DataBlockEncoding algorithm = idToEncoding.get(encoderId);
173 return algorithm.getClass().equals(encoder.getClass());
174 }
175
176 public static DataBlockEncoding getEncodingById(short dataBlockEncodingId) {
177 return idToEncoding.get(dataBlockEncodingId);
178 }
179
180 }