This is an automated email from the ASF dual-hosted git repository. rfscholte pushed a commit to branch MNG-6572 in repository https://gitbox.apache.org/repos/asf/maven.git
commit 07baa5b899a9a23471a4de44d0cef92c32bb06b3 Author: Gabriel Belingueres <belingue...@gmail.com> AuthorDate: Sat Jan 26 05:23:54 2019 -0300 use int or long instead of BigIntegers for little numbers in ComparableVersion - Added class IntItem and LongItem for handling numbers lower than 2^31 and 2^63. - Renamed IntegerItem to BigIntegerItem for handling larger numbers. - Changed old Stack implementation to LinkedList. --- .../artifact/versioning/ComparableVersion.java | 195 ++++++++++++++++++--- .../artifact/versioning/ComparableVersionTest.java | 22 ++- 2 files changed, 194 insertions(+), 23 deletions(-) diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java b/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java index 4c64d2b..ad71ed0 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java @@ -23,10 +23,10 @@ import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Properties; -import java.util.Stack; /** * <p> @@ -70,7 +70,9 @@ public class ComparableVersion private interface Item { - int INTEGER_ITEM = 0; + int INT_ITEM = 3; + int LONG_ITEM = 4; + int BIGINTEGER_ITEM = 0; int STRING_ITEM = 1; int LIST_ITEM = 2; @@ -82,48 +84,181 @@ public class ComparableVersion } /** - * Represents a numeric item in the version item list. + * Represents a numeric item in the version item list that can be represented with an int. */ - private static class IntegerItem + private static class IntItem implements Item { - private static final BigInteger BIG_INTEGER_ZERO = new BigInteger( "0" ); + private final int value; - private final BigInteger value; + public static final IntItem ZERO = new IntItem(); + + private IntItem() + { + this.value = 0; + } + + IntItem( String str ) + { + this.value = Integer.parseInt( str ); + } + + public int getType() + { + return INT_ITEM; + } + + public boolean isNull() + { + return value == 0; + } + + public int compareTo( Item item ) + { + if ( item == null ) + { + return ( value == 0 ) ? 0 : 1; // 1.0 == 1, 1.1 > 1 + } + + switch ( item.getType() ) + { + case INT_ITEM: + { + int itemValue = ( (IntItem) item ).value; + return ( value < itemValue ) ? -1 : ( ( value == itemValue ) ? 0 : 1 ); + } + case LONG_ITEM: + { + long itemValue = ( (LongItem) item ).value; + return ( value < itemValue ) ? -1 : ( ( value == itemValue ) ? 0 : 1 ); + } + case BIGINTEGER_ITEM: + return BigInteger.valueOf( value ).compareTo( ( (BigIntegerItem) item ).value ); + + case STRING_ITEM: + return 1; // 1.1 > 1-sp + + case LIST_ITEM: + return 1; // 1.1 > 1-1 + + default: + throw new RuntimeException( "invalid item: " + item.getClass() ); + } + } + + public String toString() + { + return Integer.toString( value ); + } + } + + /** + * Represents a numeric item in the version item list that can be represented with a long. + */ + private static class LongItem + implements Item + { + private final long value; + + LongItem( String str ) + { + this.value = Long.parseLong( str ); + } + + public int getType() + { + return LONG_ITEM; + } + + public boolean isNull() + { + return value == 0; + } + + public int compareTo( Item item ) + { + if ( item == null ) + { + return ( value == 0 ) ? 0 : 1; // 1.0 == 1, 1.1 > 1 + } + + switch ( item.getType() ) + { + case INT_ITEM: + { + int itemValue = ( (IntItem) item ).value; + return ( value < itemValue ) ? -1 : ( ( value == itemValue ) ? 0 : 1 ); + } + case LONG_ITEM: + { + long itemValue = ( (LongItem) item ).value; + return ( value < itemValue ) ? -1 : ( ( value == itemValue ) ? 0 : 1 ); + } + case BIGINTEGER_ITEM: + return BigInteger.valueOf( value ).compareTo( ( (BigIntegerItem) item ).value ); + + case STRING_ITEM: + return 1; // 1.1 > 1-sp + + case LIST_ITEM: + return 1; // 1.1 > 1-1 - public static final IntegerItem ZERO = new IntegerItem(); + default: + throw new RuntimeException( "invalid item: " + item.getClass() ); + } + } - private IntegerItem() + public String toString() { - this.value = BIG_INTEGER_ZERO; + return Long.toString( value ); } + } + + /** + * Represents a numeric item in the version item list. + */ + private static class BigIntegerItem + implements Item + { + private final BigInteger value; - IntegerItem( String str ) + BigIntegerItem( String str ) { this.value = new BigInteger( str ); } public int getType() { - return INTEGER_ITEM; + return BIGINTEGER_ITEM; } public boolean isNull() { - return BIG_INTEGER_ZERO.equals( value ); + return BigInteger.ZERO.equals( value ); } public int compareTo( Item item ) { if ( item == null ) { - return BIG_INTEGER_ZERO.equals( value ) ? 0 : 1; // 1.0 == 1, 1.1 > 1 + return BigInteger.ZERO.equals( value ) ? 0 : 1; // 1.0 == 1, 1.1 > 1 } switch ( item.getType() ) { - case INTEGER_ITEM: - return value.compareTo( ( (IntegerItem) item ).value ); + case INT_ITEM: + { + int itemValue = ( (IntItem) item ).value; + return value.compareTo( BigInteger.valueOf( itemValue ) ); + } + case LONG_ITEM: + { + long itemValue = ( (LongItem) item ).value; + return value.compareTo( BigInteger.valueOf( itemValue ) ); + } + + case BIGINTEGER_ITEM: + return value.compareTo( ( (BigIntegerItem) item ).value ); case STRING_ITEM: return 1; // 1.1 > 1-sp @@ -228,7 +363,9 @@ public class ComparableVersion } switch ( item.getType() ) { - case INTEGER_ITEM: + case INT_ITEM: + case LONG_ITEM: + case BIGINTEGER_ITEM: return -1; // 1.any < 1.1 ? case STRING_ITEM: @@ -297,7 +434,9 @@ public class ComparableVersion } switch ( item.getType() ) { - case INTEGER_ITEM: + case INT_ITEM: + case LONG_ITEM: + case BIGINTEGER_ITEM: return -1; // 1-1 < 1.0.x case STRING_ITEM: @@ -359,7 +498,7 @@ public class ComparableVersion ListItem list = items; - Stack<Item> stack = new Stack<>(); + LinkedList<Item> stack = new LinkedList<>(); stack.push( list ); boolean isDigit = false; @@ -374,7 +513,7 @@ public class ComparableVersion { if ( i == startIndex ) { - list.add( IntegerItem.ZERO ); + list.add( IntItem.ZERO ); } else { @@ -386,7 +525,7 @@ public class ComparableVersion { if ( i == startIndex ) { - list.add( IntegerItem.ZERO ); + list.add( IntItem.ZERO ); } else { @@ -441,7 +580,21 @@ public class ComparableVersion private static Item parseItem( boolean isDigit, String buf ) { - return isDigit ? new IntegerItem( buf ) : new StringItem( buf, false ); + if ( isDigit ) + { + if ( buf.length() <= 9 ) + { + // lower than 2^31 + return new IntItem( buf ); + } + else if ( buf.length() <= 18 ) + { + // lower than 2^63 + return new LongItem( buf ); + } + return new BigIntegerItem( buf ); + } + return new StringItem( buf, false ); } public int compareTo( ComparableVersion o ) diff --git a/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java b/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java index 875b43e..a5a2588 100644 --- a/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java +++ b/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java @@ -1,5 +1,7 @@ package org.apache.maven.artifact.versioning; +import junit.framework.TestCase; + /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -21,8 +23,6 @@ package org.apache.maven.artifact.versioning; import java.util.Locale; -import junit.framework.TestCase; - /** * Test ComparableVersion. * @@ -201,6 +201,24 @@ public class ComparableVersionTest checkVersionsOrder( a, c ); } + /** + * Test <a href="https://jira.apache.org/jira/browse/MNG-6572">MNG-6572</a> optimization. + */ + public void testMng6572() + { + String a = "20190126.230843"; // resembles a SNAPSHOT + String b = "1234567890.12345"; // 10 digit number + String c = "123456789012345.1H.5-beta"; // 15 digit number + String d = "12345678901234567890.1H.5-beta"; // 20 digit number + + checkVersionsOrder( a, b ); + checkVersionsOrder( b, c ); + checkVersionsOrder( a, c ); + checkVersionsOrder( c, d ); + checkVersionsOrder( b, d ); + checkVersionsOrder( a, d ); + } + public void testLocaleIndependent() { Locale orig = Locale.getDefault();