Skip to content

Commit

Permalink
fix version compare to support revision strings in version
Browse files Browse the repository at this point in the history
  • Loading branch information
varjoranta authored and Bj0rnen committed Feb 3, 2015
1 parent 8847701 commit d4532f0
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 10 deletions.
36 changes: 26 additions & 10 deletions src/main/java/com/spotify/reaper/cassandra/JmxProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.io.IOException;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.text.NumberFormat;
import java.util.AbstractMap;
import java.util.Collection;
import java.util.HashSet;
Expand Down Expand Up @@ -385,7 +386,7 @@ public void close() throws ReaperException {
}

/**
* NOTICE: This code is copied from StackOverflow answer:
* NOTICE: This code is loosely based on StackOverflow answer:
* http://stackoverflow.com/questions/6701948/efficient-way-to-compare-version-strings-in-java
*
* Compares two version strings.
Expand All @@ -402,24 +403,39 @@ public void close() throws ReaperException {
*/
public static Integer versionCompare(String str1, String str2) throws ReaperException {
try {
str1 = str1.split(" ")[0].replaceAll("[^0-9.]", "");
str2 = str2.split(" ")[0].replaceAll("[^0-9.]", "");;
String[] vals1 = str1.split("\\.");
String[] vals2 = str2.split("\\.");
str1 = str1.split(" ")[0].replaceAll("[-_~]", ".");
str2 = str2.split(" ")[0].replaceAll("[-_~]", ".");
String[] parts1 = str1.split("\\.");
String[] parts2 = str2.split("\\.");
int i = 0;
// set index to first non-equal ordinal or length of shortest version string
while (i < vals1.length && i < vals2.length && vals1[i].equals(vals2[i])) {
i++;
while (i < parts1.length && i < parts2.length) {
try {
Integer.parseInt(parts1[i]);
Integer.parseInt(parts2[i]);
} catch (NumberFormatException ex) {
if (i == 0) {
throw ex; // just comparing two non-version strings should fail
}
// first non integer part, so let's just stop comparison here and ignore this part
i--;
break;
}
if (parts1[i].equals(parts2[i])) {
i++;
continue;
}
break;
}
// compare first non-equal ordinal number
if (i < vals1.length && i < vals2.length) {
int diff = Integer.valueOf(vals1[i]).compareTo(Integer.valueOf(vals2[i]));
if (i < parts1.length && i < parts2.length) {
int diff = Integer.valueOf(parts1[i]).compareTo(Integer.valueOf(parts2[i]));
return Integer.signum(diff);
}
// the strings are equal or one string is a substring of the other
// e.g. "1.2.3" = "1.2.3" or "1.2.3" < "1.2.3.4"
else {
return Integer.signum(vals1.length - vals2.length);
return Integer.signum(parts1.length - parts2.length);
}
} catch (Exception ex) {
LOG.error("failed comparing strings for versions: '{}' '{}'", str1, str2);
Expand Down
2 changes: 2 additions & 0 deletions src/test/java/com/spotify/reaper/cassandra/JmxProxyTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public void testVersionCompare() throws ReaperException {
assertEquals(Integer.valueOf(1), JmxProxy.versionCompare("99.0.0", "9.0"));
assertEquals(Integer.valueOf(1), JmxProxy.versionCompare("99.0.10", "99.0.1"));
assertEquals(Integer.valueOf(-1), JmxProxy.versionCompare("99.0.10~1", "99.0.10~2"));
assertEquals(Integer.valueOf(0), JmxProxy.versionCompare("1.2.18-1~1.2.15.219.gec18fb4.9",
"1.2.18-1~1.2.15.219.gec17fb4.10"));
}

}

0 comments on commit d4532f0

Please sign in to comment.