You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by sa...@apache.org on 2014/07/19 19:48:53 UTC
svn commit: r1611934 - in /lucene/dev/trunk/solr: CHANGES.txt
core/src/test/org/apache/solr/cloud/TestHashPartitioner.java
solrj/src/java/org/apache/solr/common/cloud/CompositeIdRouter.java
Author: sarowe
Date: Sat Jul 19 17:48:53 2014
New Revision: 1611934
URL: http://svn.apache.org/r1611934
Log:
SOLR-6257: More than two "!"-s in a doc ID throws an ArrayIndexOutOfBoundsException when using the composite id router.
Modified:
lucene/dev/trunk/solr/CHANGES.txt
lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestHashPartitioner.java
lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/cloud/CompositeIdRouter.java
Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=1611934&r1=1611933&r2=1611934&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Sat Jul 19 17:48:53 2014
@@ -196,6 +196,10 @@ Bug Fixes
* SOLR-6136: ConcurrentUpdateSolrServer includes a Spin Lock (Brandon Chapman, Timothy Potter)
+* SOLR-6257: More than two "!"-s in a doc ID throws an
+ ArrayIndexOutOfBoundsException when using the composite id router.
+ (Steve Rowe)
+
Optimizations
---------------------
Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestHashPartitioner.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestHashPartitioner.java?rev=1611934&r1=1611933&r2=1611934&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestHashPartitioner.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestHashPartitioner.java Sat Jul 19 17:48:53 2014
@@ -23,6 +23,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import org.apache.lucene.util.TestUtil;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.cloud.CompositeIdRouter;
import org.apache.solr.common.cloud.DocCollection;
@@ -197,25 +198,73 @@ public class TestHashPartitioner extends
doQuery(coll, "d/1!", "shard3,shard4"); // top bit of hash(b)==0, so shard3 and shard4
}
- /***
- public void testPrintHashCodes() throws Exception {
- // from negative to positive, the upper bits of the hash ranges should be
- // shard1: 11
- // shard2: 10
- // shard3: 00
- // shard4: 01
-
- String[] highBitsToShard = {"shard3","shard4","shard1","shard2"};
-
+ /** Make sure CompositeIdRouter doesn't throw exceptions for non-conforming IDs */
+ public void testNonConformingCompositeIds() throws Exception {
+ DocRouter router = DocRouter.getDocRouter(CompositeIdRouter.NAME);
+ DocCollection coll = createCollection(4, router);
+ String[] ids = { "A!B!C!D", "!!!!!!", "A!!!!B", "A!!B!!C", "A/59!B", "A/8/!B/19/",
+ "A!B/-5", "!/130!", "!!A/1000", "A//8!B///10!C////" };
+ for (int i = 0 ; i < ids.length ; ++i) {
+ try {
+ Slice targetSlice = coll.getRouter().getTargetSlice(ids[i], null, null, coll);
+ assertNotNull(targetSlice);
+ } catch (Exception e) {
+ throw new Exception("Exception routing id '" + ids[i] + "'", e);
+ }
+ }
+ }
- for (int i = 0; i<26; i++) {
- String id = new String(Character.toChars('a'+i));
- int hash = hash(id);
- System.out.println("hash of " + id + " is " + Integer.toHexString(hash) + " high bits=" + (hash>>>30)
- + " shard="+highBitsToShard[hash>>>30]);
+ /** Make sure CompositeIdRouter can route random IDs without throwing exceptions */
+ public void testRandomCompositeIds() throws Exception {
+ DocRouter router = DocRouter.getDocRouter(CompositeIdRouter.NAME);
+ DocCollection coll = createCollection(TestUtil.nextInt(random(), 1, 10), router);
+ StringBuilder idBuilder = new StringBuilder();
+ for (int i = 0 ; i < 10000 ; ++i) {
+ idBuilder.setLength(0);
+ int numParts = TestUtil.nextInt(random(), 1, 30);
+ for (int part = 0; part < numParts; ++part) {
+ switch (random().nextInt(5)) {
+ case 0: idBuilder.append('!'); break;
+ case 1: idBuilder.append('/'); break;
+ case 2: idBuilder.append(TestUtil.nextInt(random(),-100, 1000)); break;
+ default: {
+ int length = TestUtil.nextInt(random(), 1, 10);
+ char[] str = new char[length];
+ TestUtil.randomFixedLengthUnicodeString(random(), str, 0, length);
+ idBuilder.append(str);
+ break;
+ }
+ }
+ }
+ String id = idBuilder.toString();
+ try {
+ Slice targetSlice = router.getTargetSlice(id, null, null, coll);
+ assertNotNull(targetSlice);
+ } catch (Exception e) {
+ throw new Exception("Exception routing id '" + id + "'", e);
+ }
}
}
- ***/
+
+ /***
+ public void testPrintHashCodes() throws Exception {
+ // from negative to positive, the upper bits of the hash ranges should be
+ // shard1: 11
+ // shard2: 10
+ // shard3: 00
+ // shard4: 01
+
+ String[] highBitsToShard = {"shard3","shard4","shard1","shard2"};
+
+
+ for (int i = 0; i<26; i++) {
+ String id = new String(Character.toChars('a'+i));
+ int hash = hash(id);
+ System.out.println("hash of " + id + " is " + Integer.toHexString(hash) + " high bits=" + (hash>>>30)
+ + " shard="+highBitsToShard[hash>>>30]);
+ }
+ }
+ ***/
Modified: lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/cloud/CompositeIdRouter.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/cloud/CompositeIdRouter.java?rev=1611934&r1=1611933&r2=1611934&view=diff
==============================================================================
--- lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/cloud/CompositeIdRouter.java (original)
+++ lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/cloud/CompositeIdRouter.java Sat Jul 19 17:48:53 2014
@@ -187,10 +187,36 @@ public class CompositeIdRouter extends H
boolean triLevel;
int pieces;
- public KeyParser(String key) {
- String[] parts = key.split(SEPARATOR);
+ public KeyParser(final String key) {
this.key = key;
- pieces = parts.length;
+ List<String> partsList = new ArrayList<>(3);
+ int firstSeparatorPos = key.indexOf(SEPARATOR);
+ if (-1 == firstSeparatorPos) {
+ partsList.add(key);
+ } else {
+ partsList.add(key.substring(0, firstSeparatorPos));
+ int lastPos = key.length() - 1;
+ // Don't make any more parts if the first separator is the last char
+ if (firstSeparatorPos < lastPos) {
+ int secondSeparatorPos = key.indexOf(SEPARATOR, firstSeparatorPos + 1);
+ if (-1 == secondSeparatorPos) {
+ partsList.add(key.substring(firstSeparatorPos + 1));
+ } else if (secondSeparatorPos == lastPos) {
+ // Don't make any more parts if the key has exactly two separators and
+ // they're the last two chars - back-compatibility with the behavior of
+ // String.split() - see SOLR-6257.
+ if (firstSeparatorPos < secondSeparatorPos - 1) {
+ partsList.add(key.substring(firstSeparatorPos + 1, secondSeparatorPos));
+ }
+ } else { // The second separator is not the last char
+ partsList.add(key.substring(firstSeparatorPos + 1, secondSeparatorPos));
+ partsList.add(key.substring(secondSeparatorPos + 1));
+ }
+ // Ignore any further separators beyond the first two
+ }
+ }
+ pieces = partsList.size();
+ String[] parts = partsList.toArray(new String[pieces]);
numBits = new int[2];
if (key.endsWith("!") && pieces < 3)
pieces++;