From 4c7f0f24369f4237111290d1f09ff2ec258b5199 Mon Sep 17 00:00:00 2001 From: binlijin Date: Tue, 20 Dec 2016 12:28:04 +0800 Subject: [PATCH] HBASE-17332 Replace HashMap to Array for DataBlockEncoding.idToEncoding --- .../hbase/io/encoding/DataBlockEncoding.java | 46 +++++++---------- .../io/encoding/TestDataBlockEncoding.java | 50 +++++++++++++++++++ 2 files changed, 69 insertions(+), 27 deletions(-) create mode 100644 hbase-server/src/test/java/org/apache/hadoop/hbase/io/encoding/TestDataBlockEncoding.java diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/DataBlockEncoding.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/DataBlockEncoding.java index 71b55e2db18..d7535e58cea 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/DataBlockEncoding.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/DataBlockEncoding.java @@ -18,8 +18,6 @@ package org.apache.hadoop.hbase.io.encoding; import java.io.IOException; import java.io.OutputStream; -import java.util.HashMap; -import java.util.Map; import org.apache.hadoop.hbase.classification.InterfaceAudience; import org.apache.hadoop.hbase.classification.InterfaceStability; @@ -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 idToEncoding = - new HashMap(); + 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){ diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/io/encoding/TestDataBlockEncoding.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/io/encoding/TestDataBlockEncoding.java new file mode 100644 index 00000000000..58865c948b8 --- /dev/null +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/io/encoding/TestDataBlockEncoding.java @@ -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) { + } + } + +}