HBASE-17332 Replace HashMap to Array for DataBlockEncoding.idToEncoding

This commit is contained in:
binlijin 2016-12-20 09:32:28 +08:00
parent d53f012bb7
commit b7bde350a1
2 changed files with 72 additions and 30 deletions

View File

@ -16,15 +16,13 @@
*/
package org.apache.hadoop.hbase.io.encoding;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.hadoop.hbase.classification.InterfaceAudience;
import org.apache.hadoop.hbase.classification.InterfaceStability;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
/**
* Provide access to all data block encoding algorithms. All of the algorithms
* are required to have unique id which should <b>NEVER</b> be changed. If you
@ -54,24 +52,21 @@ public enum DataBlockEncoding {
public static final int ID_SIZE = Bytes.SIZEOF_SHORT;
/** Maps data block encoding ids to enum instances. */
private static Map<Short, DataBlockEncoding> idToEncoding =
new HashMap<Short, DataBlockEncoding>();
private static DataBlockEncoding[] idArray = new DataBlockEncoding[Byte.MAX_VALUE + 1];
static {
for (DataBlockEncoding algo : values()) {
if (idToEncoding.containsKey(algo.id)) {
if (idArray[algo.id] != null) {
throw new RuntimeException(String.format(
"Two data block encoder algorithms '%s' and '%s' have " +
"the same id %d",
idToEncoding.get(algo.id).toString(), algo.toString(),
(int) algo.id));
"Two data block encoder algorithms '%s' and '%s' have " + "the same id %d",
idArray[algo.id].toString(), algo.toString(), (int) algo.id));
}
idToEncoding.put(algo.id, algo);
idArray[algo.id] = algo;
}
}
private DataBlockEncoding(int id, String encoderClsName) {
if (id < Short.MIN_VALUE || id > Short.MAX_VALUE) {
if (id < 0 || id > Byte.MAX_VALUE) {
throw new AssertionError(
"Data block encoding algorithm id is out of range: " + id);
}
@ -139,13 +134,7 @@ public enum DataBlockEncoding {
* @return Newly created data block encoder.
*/
public static DataBlockEncoder getDataBlockEncoderById(short encoderId) {
if (!idToEncoding.containsKey(encoderId)) {
throw new IllegalArgumentException(String.format(
"There is no data block encoder for given id '%d'",
(int) encoderId));
}
return idToEncoding.get(encoderId).getEncoder();
return getEncodingById(encoderId).getEncoder();
}
/**
@ -154,7 +143,7 @@ public enum DataBlockEncoding {
* @return name, same as used in options in column family
*/
public static String getNameFromId(short encoderId) {
return idToEncoding.get(encoderId).toString();
return getEncodingById(encoderId).toString();
}
/**
@ -167,19 +156,22 @@ public enum DataBlockEncoding {
*/
public static boolean isCorrectEncoder(DataBlockEncoder encoder,
short encoderId) {
if (!idToEncoding.containsKey(encoderId)) {
throw new IllegalArgumentException(String.format(
"There is no data block encoder for given id '%d'",
(int) encoderId));
}
DataBlockEncoding algorithm = idToEncoding.get(encoderId);
DataBlockEncoding algorithm = getEncodingById(encoderId);
String encoderCls = encoder.getClass().getName();
return encoderCls.equals(algorithm.encoderCls);
}
public static DataBlockEncoding getEncodingById(short dataBlockEncodingId) {
return idToEncoding.get(dataBlockEncodingId);
DataBlockEncoding algorithm = null;
if (dataBlockEncodingId >= 0 && dataBlockEncodingId <= Byte.MAX_VALUE) {
algorithm = idArray[dataBlockEncodingId];
}
if (algorithm == null) {
throw new IllegalArgumentException(String.format(
"There is no data block encoder for given id '%d'",
(int) dataBlockEncodingId));
}
return algorithm;
}
protected static DataBlockEncoder createEncoder(String fullyQualifiedClassName){

View File

@ -0,0 +1,50 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package org.apache.hadoop.hbase.io.encoding;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.apache.hadoop.hbase.testclassification.SmallTests;
import org.junit.Test;
import org.junit.experimental.categories.Category;
@Category(SmallTests.class)
public class TestDataBlockEncoding {
@Test
public void testGetDataBlockEncoder() throws Exception {
for (DataBlockEncoding algo : DataBlockEncoding.values()) {
DataBlockEncoder encoder = DataBlockEncoding.getDataBlockEncoderById(algo.getId());
if (algo.getId() != 0) {
assertTrue(DataBlockEncoding.isCorrectEncoder(encoder, algo.getId()));
}
}
try {
DataBlockEncoding.getDataBlockEncoderById((short) -1);
fail("Illegal encoderId, should get IllegalArgumentException.");
} catch (IllegalArgumentException ie) {
}
try {
DataBlockEncoding.getDataBlockEncoderById(Byte.MAX_VALUE);
// fail because idArray[Byte.MAX_VALUE] = null
fail("Illegal encoderId, should get IllegalArgumentException.");
} catch (IllegalArgumentException ie) {
}
}
}