From f2810406468cf09405648f5c4439d1a29dd7d0e3 Mon Sep 17 00:00:00 2001 From: maoling Date: Mon, 14 May 2018 21:14:45 +0800 Subject: [PATCH] HBASE-20444:Improve version comparison logic for HBase specific version string and add unit tests --- .../org/apache/hadoop/hbase/util/VersionInfo.java | 67 +++++++++++----------- .../apache/hadoop/hbase/util/TestVersionInfo.java | 15 ++++- 2 files changed, 49 insertions(+), 33 deletions(-) diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/VersionInfo.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/VersionInfo.java index 86ac06540e..e2a54c35ed 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/VersionInfo.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/VersionInfo.java @@ -21,6 +21,7 @@ package org.apache.hadoop.hbase.util; import java.io.PrintStream; import java.io.PrintWriter; +import java.util.regex.Pattern; import org.apache.hadoop.hbase.Version; import org.apache.yetus.audience.InterfaceAudience; import org.slf4j.Logger; @@ -117,50 +118,47 @@ public class VersionInfo { if (v1.equals(v2)) { return 0; } - - Object[] v1Comps = getVersionComponents(v1); //1.2.3-hotfix -> [1, 2, 3, hotfix] - Object[] v2Comps = getVersionComponents(v2); - int index = 0; - while (index < v1Comps.length && index < v2Comps.length) { - int va = v1Comps[index] instanceof Integer ? (Integer)v1Comps[index] : VERY_LARGE_NUMBER; - int vb = v2Comps[index] instanceof Integer ? (Integer)v2Comps[index] : VERY_LARGE_NUMBER; - - if (va != vb) { - return va - vb; - } - if (va == VERY_LARGE_NUMBER) { - // here, va and vb components must be same and Strings, compare as String - int c = ((String)v1Comps[index]).compareTo((String)v2Comps[index]); - if (c != 0) { - return c; - } + String[] v1Comps = getVersionComponents(v1); + String[] v2Comps = getVersionComponents(v2); + + int length = Math.max(v1Comps.length, v2Comps.length); + for (int i = 0; i < length; i++) { + Integer va = i < v1Comps.length ? Integer.parseInt(v1Comps[i]) : 0; + Integer vb = i < v2Comps.length ? Integer.parseInt(v2Comps[i]) : 0; + int compare = va.compareTo(vb); + if (compare != 0) { + return compare; } - index++; } - if (index < v1Comps.length) { - // v1 is longer - return 1; - } - //v2 is longer - return -1; + return 0; } /** - * Returns the version components as Integer and String objects - * Examples: "1.2.3" returns [1, 2, 3], "4.5.6-SNAPSHOT" returns [4, 5, 6, "SNAPSHOT"] + * Returns the version components as String objects + * Examples: "1.2.3" returns ["1", "2", "3"], "4.5.6-SNAPSHOT" returns ["4", "5", "6", "-1"] + * "4.5.6-beta" returns ["4", "5", "6", "-2"], "4.5.6-alpha" returns ["4", "5", "6", "-3"] + * "4.5.6-UNKNOW" returns ["4", "5", "6", "VERY_LARGE_NUMBER"] * @return the components of the version string */ - static Object[] getVersionComponents(final String version) { + static String[] getVersionComponents(final String version) { assert(version != null); - Object[] strComps = version.split("[\\.-]"); + String[] strComps = version.split("[\\.-]"); assert(strComps.length > 0); - Object[] comps = new Object[strComps.length]; + String[] comps = new String[strComps.length]; for (int i = 0; i < strComps.length; ++i) { - try { - comps[i] = Integer.parseInt((String) strComps[i]); - } catch (NumberFormatException e) { + if (isNumeric(strComps[i])) { comps[i] = strComps[i]; + } else { + if("SNAPSHOT".equals(strComps[i])) { + comps[i] = "-1"; + } else if("beta".equals(strComps[i])) { + comps[i] = "-2"; + } else if("alpha".equals(strComps[i])) { + comps[i] = "-3"; + } else { + comps[i] = String.valueOf(VERY_LARGE_NUMBER); + } } } return comps; @@ -169,4 +167,9 @@ public class VersionInfo { public static void main(String[] args) { writeTo(System.out); } + + private static boolean isNumeric(String str) { + Pattern pattern = Pattern.compile("[0-9]*"); + return pattern.matcher(str).matches(); + } } diff --git a/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestVersionInfo.java b/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestVersionInfo.java index 325ad089e2..0edf8a86f8 100644 --- a/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestVersionInfo.java +++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestVersionInfo.java @@ -37,6 +37,19 @@ public class TestVersionInfo { assertTrue(VersionInfo.compareVersion("1.0.0", "0.98.11") > 0); assertTrue(VersionInfo.compareVersion("0.98.11", "1.0.1") < 0); assertTrue(VersionInfo.compareVersion("2.0.0", "1.4.0") > 0); - assertTrue(VersionInfo.compareVersion("2.0.0", "2.0.0-SNAPSHOT") < 0); + assertTrue(VersionInfo.compareVersion("2.0.0", "2.0.0-SNAPSHOT") > 0); + assertTrue(VersionInfo.compareVersion("2.0.0", "2.0.0") == 0); + assertTrue(VersionInfo.compareVersion("2.0.0", "2.0.0.0") == 0); + assertTrue(VersionInfo.compareVersion("0.98.11", "0.99.11") < 0); + assertTrue(VersionInfo.compareVersion("0.99.11", "0.99.14") < 0); + assertTrue(VersionInfo.compareVersion("0.99.14", "1.99.14") < 0); + assertTrue(VersionInfo.compareVersion("1.99.14", "2.0.0-alpha-1") < 0); + assertTrue(VersionInfo.compareVersion("2.0.0-alpha-1", "2.0.0-beta-3") < 0); + assertTrue(VersionInfo.compareVersion("2.0.0-beta-3", "2.0.0-SNAPSHOT") < 0); + assertTrue(VersionInfo.compareVersion("2.0.0-SNAPSHOT", "2.0") < 0); + assertTrue(VersionInfo.compareVersion("2.0", "2.0.0.1") < 0); + assertTrue(VersionInfo.compareVersion("2.0.0.1", "2.0.1") < 0); + assertTrue(VersionInfo.compareVersion("2.0.0.1", "2.0.0-fuck") < 0); + assertTrue(VersionInfo.compareVersion("2.0.0-ooxx", "2.0.0.1") > 0); } } -- 2.14.1.windows.1