diff --git a/common/pom.xml b/common/pom.xml index 42d1c629607..d8c4733e343 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -16,7 +16,8 @@ ~ limitations under the License. --> - + 4.0.0 io.druid druid-common @@ -60,6 +61,10 @@ org.hibernate hibernate-validator + + javax.el + javax.el-api + javax.validation validation-api diff --git a/pom.xml b/pom.xml index de5ccaba3cd..5d5a2b71d56 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,8 @@ ~ limitations under the License. --> - + 4.0.0 io.druid druid @@ -101,12 +102,6 @@ server-metrics 0.0.9 - - - com.davekoelle - alphanum - 1.0.3 - commons-codec commons-codec @@ -264,7 +259,7 @@ org.hibernate hibernate-validator - 5.0.1.Final + 5.1.3.Final javax.validation @@ -276,6 +271,11 @@ javax.inject 1 + + javax.el + javax.el-api + 3.0.0 + org.glassfish javax.el @@ -481,10 +481,10 @@ test - com.carrotsearch - junit-benchmarks - 0.7.2 - test + com.carrotsearch + junit-benchmarks + 0.7.2 + test com.google.caliper diff --git a/processing/pom.xml b/processing/pom.xml index 1c8323ffc4d..9e16db8218d 100644 --- a/processing/pom.xml +++ b/processing/pom.xml @@ -16,126 +16,123 @@ ~ limitations under the License. --> - - 4.0.0 - io.druid - druid-processing - druid-processing - A module that is everything required to understands Druid Segments - - + + 4.0.0 io.druid - druid - 0.7.0-SNAPSHOT - + druid-processing + druid-processing + A module that is everything required to understands Druid Segments - - - io.druid - druid-common - ${project.parent.version} - - - com.metamx - bytebuffer-collections - - - com.metamx - emitter - - - com.ning - compress-lzf - - - org.skife.config - config-magic - - - com.google.protobuf - protobuf-java - - - commons-io - commons-io - - - com.ibm.icu - icu4j - - - org.mozilla - rhino - 1.7R4 - - - com.davekoelle - alphanum - - - net.jpountz.lz4 - lz4 - - - org.mapdb - mapdb - + + io.druid + druid + 0.7.0-SNAPSHOT + - - - junit - junit - test - - - com.carrotsearch - junit-benchmarks - test - - - org.easymock - easymock - test - - - com.google.caliper - caliper - test - - + + + io.druid + druid-common + ${project.parent.version} + + + com.metamx + bytebuffer-collections + + + com.metamx + emitter + + + com.ning + compress-lzf + + + org.skife.config + config-magic + + + com.google.protobuf + protobuf-java + + + commons-io + commons-io + + + com.ibm.icu + icu4j + + + org.mozilla + rhino + 1.7R4 + + + net.jpountz.lz4 + lz4 + + + org.mapdb + mapdb + - - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - - jar - - - - - - maven-jar-plugin - - - - test-jar - - - - - - - true - true - - - - - - + + + junit + junit + test + + + com.carrotsearch + junit-benchmarks + test + + + org.easymock + easymock + test + + + com.google.caliper + caliper + test + + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + maven-jar-plugin + + + + test-jar + + + + + + + true + true + + + + + + diff --git a/processing/src/main/java/io/druid/query/topn/AlphaNumericTopNMetricSpec.java b/processing/src/main/java/io/druid/query/topn/AlphaNumericTopNMetricSpec.java index 6a3d94d88f1..cc31fa0fe5f 100644 --- a/processing/src/main/java/io/druid/query/topn/AlphaNumericTopNMetricSpec.java +++ b/processing/src/main/java/io/druid/query/topn/AlphaNumericTopNMetricSpec.java @@ -17,7 +17,6 @@ package io.druid.query.topn; -import com.davekoelle.alphanum.AlphanumComparator; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.metamx.common.StringUtils; @@ -32,6 +31,154 @@ public class AlphaNumericTopNMetricSpec extends LexicographicTopNMetricSpec { private static final byte CACHE_TYPE_ID = 0x2; + protected static Comparator comparator = new Comparator() + { + // This code is based on the Apache 2.0 licensed java-alphanum library (https://github.com/amjjd/java-alphanum) + public int compare(String str1, String str2) + { + int[] pos = {0, 0}; + + if (str1.length() == 0) { + return str2.length() == 0 ? 0 : -1; + } else if (str2.length() == 0) { + return 1; + } + + while (pos[0] < str1.length() && pos[1] < str2.length()) { + int ch1 = str1.codePointAt(pos[0]); + int ch2 = str2.codePointAt(pos[1]); + + int result = 0; + + if (isDigit(ch1)) { + result = isDigit(ch2) ? compareNumbers(str1, str2, pos) : -1; + } else { + result = isDigit(ch2) ? 1 : compareNonNumeric(str1, str2, pos); + } + + if (result != 0) { + return result; + } + } + + return str1.length() - str2.length(); + } + + private int compareNumbers(String str0, String str1, int[] pos) + { + int delta = 0; + int zeroes0 = 0, zeroes1 = 0; + int ch0 = -1, ch1 = -1; + + // Skip leading zeroes, but keep a count of them. + while (pos[0] < str0.length() && isZero(ch0 = str0.codePointAt(pos[0]))) { + zeroes0++; + pos[0] += Character.charCount(ch0); + } + while (pos[1] < str1.length() && isZero(ch1 = str1.codePointAt(pos[1]))) { + zeroes1++; + pos[1] += Character.charCount(ch1); + } + + // If one sequence contains more significant digits than the + // other, it's a larger number. In case they turn out to have + // equal lengths, we compare digits at each position; the first + // unequal pair determines which is the bigger number. + while (true) { + boolean noMoreDigits0 = (ch0 < 0) || !isDigit(ch0); + boolean noMoreDigits1 = (ch1 < 0) || !isDigit(ch1); + + if (noMoreDigits0 && noMoreDigits1) { + return delta != 0 ? delta : zeroes0 - zeroes1; + } else if (noMoreDigits0) { + return -1; + } else if (noMoreDigits1) { + return 1; + } else if (delta == 0 && ch0 != ch1) { + delta = valueOf(ch0) - valueOf(ch1); + } + + if (pos[0] < str0.length()) { + ch0 = str0.codePointAt(pos[0]); + if (isDigit(ch0)) { + pos[0] += Character.charCount(ch0); + } else { + ch0 = -1; + } + } else { + ch0 = -1; + } + + if (pos[1] < str1.length()) { + ch1 = str1.codePointAt(pos[1]); + if (isDigit(ch1)) { + pos[1] += Character.charCount(ch1); + } else { + ch1 = -1; + } + } else { + ch1 = -1; + } + } + } + + private boolean isDigit(int ch) + { + return (ch >= '0' && ch <= '9') || + (ch >= '\u0660' && ch <= '\u0669') || + (ch >= '\u06F0' && ch <= '\u06F9') || + (ch >= '\u0966' && ch <= '\u096F') || + (ch >= '\uFF10' && ch <= '\uFF19'); + } + + private boolean isZero(int ch) + { + return ch == '0' || ch == '\u0660' || ch == '\u06F0' || ch == '\u0966' || ch == '\uFF10'; + } + + private int valueOf(int digit) + { + if (digit <= '9') { + return digit - '0'; + } + if (digit <= '\u0669') { + return digit - '\u0660'; + } + if (digit <= '\u06F9') { + return digit - '\u06F0'; + } + if (digit <= '\u096F') { + return digit - '\u0966'; + } + if (digit <= '\uFF19') { + return digit - '\uFF10'; + } + + return digit; + } + + private int compareNonNumeric(String str0, String str1, int[] pos) + { + // find the end of both non-numeric substrings + int start0 = pos[0]; + int ch0 = str0.codePointAt(pos[0]); + pos[0] += Character.charCount(ch0); + while (pos[0] < str0.length() && !isDigit(ch0 = str0.codePointAt(pos[0]))) { + pos[0] += Character.charCount(ch0); + } + + int start1 = pos[1]; + int ch1 = str1.codePointAt(pos[1]); + pos[1] += Character.charCount(ch1); + while (pos[1] < str1.length() && !isDigit(ch1 = str1.codePointAt(pos[1]))) { + pos[1] += Character.charCount(ch1); + } + + // compare the substrings + return String.CASE_INSENSITIVE_ORDER.compare(str0.substring(start0, pos[0]), str1.substring(start1, pos[1])); + } + }; + private final String previousStop; @JsonCreator @@ -46,7 +193,7 @@ public class AlphaNumericTopNMetricSpec extends LexicographicTopNMetricSpec @Override public Comparator getComparator(List aggregatorSpecs, List postAggregatorSpecs) { - return new AlphanumComparator(); + return comparator; } @Override diff --git a/processing/src/test/java/io/druid/query/topn/AlphaNumericTopNMetricSpecTest.java b/processing/src/test/java/io/druid/query/topn/AlphaNumericTopNMetricSpecTest.java new file mode 100644 index 00000000000..523c49cf139 --- /dev/null +++ b/processing/src/test/java/io/druid/query/topn/AlphaNumericTopNMetricSpecTest.java @@ -0,0 +1,63 @@ +/* + * Druid - a distributed column store. + * Copyright 2012 - 2015 Metamarkets Group Inc. + * + * Licensed 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 io.druid.query.topn; + +import org.junit.Test; + +import java.util.Comparator; + +import static org.junit.Assert.*; + +public class AlphaNumericTopNMetricSpecTest +{ + // Test derived from sample code listed on Apache 2.0 licensed https://github.com/amjjd/java-alphanum + @Test + public void testComparator() throws Exception + { + final Comparator comparator = AlphaNumericTopNMetricSpec.comparator; + + // equality + assertEquals(0, comparator.compare("", "")); + assertEquals(0, comparator.compare("abc", "abc")); + assertEquals(0, comparator.compare("123", "123")); + assertEquals(0, comparator.compare("abc123", "abc123")); + + // empty strings < non-empty + assertTrue(comparator.compare("", "abc") < 0); + assertTrue(comparator.compare("abc", "") > 0); + + // numbers < non numeric + assertTrue(comparator.compare("123", "abc") < 0); + assertTrue(comparator.compare("abc", "123") > 0); + + // numbers ordered numerically + assertTrue(comparator.compare("2", "11") < 0); + assertTrue(comparator.compare("a2", "a11") < 0); + + // leading zeroes + assertTrue(comparator.compare("02", "11") < 0); + assertTrue(comparator.compare("02", "002") < 0); + + // decimal points ... + assertTrue(comparator.compare("1.3", "1.5") < 0); + + // ... don't work too well + assertTrue(comparator.compare("1.3", "1.15") < 0); + + } +} diff --git a/server/pom.xml b/server/pom.xml index a16e8e60a8e..cef063a70fc 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -16,7 +16,8 @@ ~ limitations under the License. --> - + 4.0.0 io.druid druid-server diff --git a/services/pom.xml b/services/pom.xml index aa5435d026a..6a7d73ee2a2 100644 --- a/services/pom.xml +++ b/services/pom.xml @@ -15,121 +15,136 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - - 4.0.0 - io.druid - druid-services - druid-services - druid-services - - + + 4.0.0 io.druid - druid - 0.7.0-SNAPSHOT - + druid-services + druid-services + druid-services - - - - io.druid - druid-common - ${project.parent.version} - - - io.druid - druid-server - ${project.parent.version} - - - io.druid - druid-indexing-hadoop - ${project.parent.version} - - - io.druid - druid-indexing-service - ${project.parent.version} - - - io.airlift - airline - - + + io.druid + druid + 0.7.0-SNAPSHOT + - - - - maven-jar-plugin - - - - true - true - - - - - - org.apache.maven.plugins - maven-shade-plugin - 2.2 - - - package - - shade - - - - ${project.build.directory}/${project.artifactId}-${project.version}-selfcontained.jar - - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - - - - - - - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - - jar - - - - - - maven-assembly-plugin - - - distro-assembly - package - - assembly - - - - src/assembly/assembly.xml - - - - - - - + + + + io.druid + druid-common + ${project.parent.version} + + + io.druid + druid-server + ${project.parent.version} + + + io.druid + druid-indexing-hadoop + ${project.parent.version} + + + io.druid + druid-indexing-service + ${project.parent.version} + + + io.airlift + airline + + + + + + + maven-jar-plugin + + + + true + true + + + + + + org.apache.maven.plugins + maven-shade-plugin + 2.2 + + + package + + shade + + + + ${project.build.directory}/${project.artifactId}-${project.version}-selfcontained.jar + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + maven-assembly-plugin + + + distro-assembly + package + + assembly + + + + src/assembly/assembly.xml + + + + + + + org.codehaus.mojo + license-maven-plugin + 1.8 + + + download-licenses + + download-licenses + + + + + +