optimize breaking strings based on commas, and small optimization to resolving routing values

This commit is contained in:
kimchy 2011-07-22 19:20:14 +03:00
parent 8c49da12ff
commit 8c9dffc235
10 changed files with 108 additions and 76 deletions

View File

@ -28,6 +28,7 @@ import org.elasticsearch.action.search.ShardSearchFailure;
import org.elasticsearch.cluster.routing.ShardRouting; import org.elasticsearch.cluster.routing.ShardRouting;
import org.elasticsearch.common.Base64; import org.elasticsearch.common.Base64;
import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.Unicode; import org.elasticsearch.common.Unicode;
import org.elasticsearch.common.collect.ImmutableMap; import org.elasticsearch.common.collect.ImmutableMap;
import org.elasticsearch.common.collect.Maps; import org.elasticsearch.common.collect.Maps;
@ -39,7 +40,6 @@ import org.elasticsearch.search.internal.InternalSearchRequest;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.regex.Pattern;
/** /**
* @author kimchy (Shay Banon) * @author kimchy (Shay Banon)
@ -47,12 +47,6 @@ import java.util.regex.Pattern;
public abstract class TransportSearchHelper { public abstract class TransportSearchHelper {
private final static Pattern scrollIdPattern;
static {
scrollIdPattern = Pattern.compile(";");
}
/** /**
* Builds the shard failures, and releases the cache (meaning this should only be called once!). * Builds the shard failures, and releases the cache (meaning this should only be called once!).
*/ */
@ -119,7 +113,7 @@ public abstract class TransportSearchHelper {
} catch (IOException e) { } catch (IOException e) {
throw new ElasticSearchIllegalArgumentException("Failed to decode scrollId", e); throw new ElasticSearchIllegalArgumentException("Failed to decode scrollId", e);
} }
String[] elements = scrollIdPattern.split(scrollId); String[] elements = Strings.splitStringToArray(scrollId, ';');
int index = 0; int index = 0;
String type = elements[index++]; String type = elements[index++];
int contextSize = Integer.parseInt(elements[index++]); int contextSize = Integer.parseInt(elements[index++]);

View File

@ -46,7 +46,6 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern;
import static org.elasticsearch.common.collect.Lists.*; import static org.elasticsearch.common.collect.Lists.*;
import static org.elasticsearch.common.collect.MapBuilder.*; import static org.elasticsearch.common.collect.MapBuilder.*;
@ -64,8 +63,6 @@ public class MetaData implements Iterable<IndexMetaData> {
private final long version; private final long version;
public final static Pattern routingPattern = Pattern.compile(",");
private final ImmutableMap<String, IndexMetaData> indices; private final ImmutableMap<String, IndexMetaData> indices;
private final ImmutableMap<String, IndexTemplateMetaData> templates; private final ImmutableMap<String, IndexTemplateMetaData> templates;
@ -137,7 +134,7 @@ public class MetaData implements Iterable<IndexMetaData> {
tmpAliasToIndexToSearchRoutingMap.put(aliasMd.alias(), indexToSearchRoutingMap); tmpAliasToIndexToSearchRoutingMap.put(aliasMd.alias(), indexToSearchRoutingMap);
} }
if (aliasMd.searchRouting() != null) { if (aliasMd.searchRouting() != null) {
indexToSearchRoutingMap.put(indexMetaData.index(), ImmutableSet.copyOf(routingPattern.split(aliasMd.searchRouting()))); indexToSearchRoutingMap.put(indexMetaData.index(), ImmutableSet.copyOf(Strings.splitStringByCommaToSet(aliasMd.searchRouting())));
} else { } else {
indexToSearchRoutingMap.put(indexMetaData.index(), ImmutableSet.<String>of()); indexToSearchRoutingMap.put(indexMetaData.index(), ImmutableSet.<String>of());
} }
@ -272,7 +269,7 @@ public class MetaData implements Iterable<IndexMetaData> {
*/ */
private Map<String, Set<String>> resolveSearchRoutingAllIndices(String routing) { private Map<String, Set<String>> resolveSearchRoutingAllIndices(String routing) {
if (routing != null) { if (routing != null) {
THashSet<String> r = new THashSet<String>(Arrays.asList(routingPattern.split(routing))); Set<String> r = Strings.splitStringByCommaToSet(routing);
Map<String, Set<String>> routings = newHashMap(); Map<String, Set<String>> routings = newHashMap();
String[] concreteIndices = concreteAllIndices(); String[] concreteIndices = concreteAllIndices();
for (String index : concreteIndices) { for (String index : concreteIndices) {
@ -285,9 +282,9 @@ public class MetaData implements Iterable<IndexMetaData> {
public Map<String, Set<String>> resolveSearchRouting(@Nullable String routing, String aliasOrIndex) { public Map<String, Set<String>> resolveSearchRouting(@Nullable String routing, String aliasOrIndex) {
Map<String, Set<String>> routings = null; Map<String, Set<String>> routings = null;
List<String> paramRouting = null; Set<String> paramRouting = null;
if (routing != null) { if (routing != null) {
paramRouting = Arrays.asList(routingPattern.split(routing)); paramRouting = Strings.splitStringByCommaToSet(routing);
} }
ImmutableMap<String, ImmutableSet<String>> indexToRoutingMap = aliasToIndexToSearchRoutingMap.get(aliasOrIndex); ImmutableMap<String, ImmutableSet<String>> indexToRoutingMap = aliasToIndexToSearchRoutingMap.get(aliasOrIndex);
@ -320,11 +317,7 @@ public class MetaData implements Iterable<IndexMetaData> {
} else { } else {
// It's an index // It's an index
if (paramRouting != null) { if (paramRouting != null) {
Set<String> r = new THashSet<String>(paramRouting); routings = ImmutableMap.of(aliasOrIndex, paramRouting);
if (routings == null) {
routings = newHashMap();
}
routings.put(aliasOrIndex, r);
} }
} }
return routings; return routings;
@ -336,14 +329,6 @@ public class MetaData implements Iterable<IndexMetaData> {
return resolveSearchRoutingAllIndices(routing); return resolveSearchRoutingAllIndices(routing);
} }
Map<String, Set<String>> routings = null;
List<String> paramRouting = null;
// List of indices that don't require any routing
Set<String> norouting = newHashSet();
if (routing != null) {
paramRouting = Arrays.asList(routingPattern.split(routing));
}
if (aliasesOrIndices.length == 1) { if (aliasesOrIndices.length == 1) {
if (aliasesOrIndices[0].equals("_all")) { if (aliasesOrIndices[0].equals("_all")) {
return resolveSearchRoutingAllIndices(routing); return resolveSearchRoutingAllIndices(routing);
@ -352,6 +337,14 @@ public class MetaData implements Iterable<IndexMetaData> {
} }
} }
Map<String, Set<String>> routings = null;
Set<String> paramRouting = null;
// List of indices that don't require any routing
Set<String> norouting = newHashSet();
if (routing != null) {
paramRouting = Strings.splitStringByCommaToSet(routing);
}
for (String aliasOrIndex : aliasesOrIndices) { for (String aliasOrIndex : aliasesOrIndices) {
ImmutableMap<String, ImmutableSet<String>> indexToRoutingMap = aliasToIndexToSearchRoutingMap.get(aliasOrIndex); ImmutableMap<String, ImmutableSet<String>> indexToRoutingMap = aliasToIndexToSearchRoutingMap.get(aliasOrIndex);
if (indexToRoutingMap != null && !indexToRoutingMap.isEmpty()) { if (indexToRoutingMap != null && !indexToRoutingMap.isEmpty()) {

View File

@ -106,7 +106,7 @@ public class PlainShardsIterator implements ShardsIterator {
return shardRouting; return shardRouting;
} }
@Override public ShardRouting nextActiveOrNull() throws NoSuchElementException { @Override public ShardRouting nextActiveOrNull() {
int counter = this.counter; int counter = this.counter;
int index = this.index; int index = this.index;
while (counter++ < size()) { while (counter++ < size()) {

View File

@ -42,15 +42,12 @@ import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern;
/** /**
* @author kimchy (shay.banon) * @author kimchy (shay.banon)
*/ */
public class PlainOperationRouting extends AbstractComponent implements OperationRouting { public class PlainOperationRouting extends AbstractComponent implements OperationRouting {
public final static Pattern routingPattern = Pattern.compile(",");
private final HashFunction hashFunction; private final HashFunction hashFunction;
private final boolean useType; private final boolean useType;

View File

@ -21,6 +21,7 @@ package org.elasticsearch.common;
import org.elasticsearch.common.collect.ImmutableSet; import org.elasticsearch.common.collect.ImmutableSet;
import org.elasticsearch.common.collect.Iterables; import org.elasticsearch.common.collect.Iterables;
import org.elasticsearch.common.trove.set.hash.THashSet;
import java.util.*; import java.util.*;
@ -968,6 +969,78 @@ public class Strings {
return toStringArray(set); return toStringArray(set);
} }
public static Set<String> splitStringByCommaToSet(final String s) {
return splitStringToSet(s, ',');
}
public static String[] splitStringByCommaToArray(final String s) {
return splitStringToArray(s, ',');
}
public static Set<String> splitStringToSet(final String s, final char c) {
final char[] chars = s.toCharArray();
int count = 1;
for (final char x : chars) {
if (x == c) {
count++;
}
}
final THashSet<String> result = new THashSet<String>(count);
final int len = chars.length;
int start = 0; // starting index in chars of the current substring.
int pos = 0; // current index in chars.
int i = 0; // number of the current substring.
for (; pos < len; pos++) {
if (chars[pos] == c) {
int size = pos - start;
if (size > 0) { // only add non empty strings
result.add(new String(chars, start, size));
}
start = pos + 1;
}
}
int size = pos - start;
if (size > 0) {
result.add(new String(chars, start, size));
}
return result;
}
public static String[] splitStringToArray(final String s, final char c) {
final char[] chars = s.toCharArray();
int count = 1;
for (final char x : chars) {
if (x == c) {
count++;
}
}
final String[] result = new String[count];
final int len = chars.length;
int start = 0; // starting index in chars of the current substring.
int pos = 0; // current index in chars.
int i = 0; // number of the current substring.
for (; pos < len; pos++) {
if (chars[pos] == c) {
int size = pos - start;
if (size > 0) {
result[i++] = new String(chars, start, size);
}
start = pos + 1;
}
}
int size = pos - start;
if (size > 0) {
result[i++] = new String(chars, start, size);
}
if (i != count) {
// we have empty strings, copy over to a new array
String[] result1 = new String[i];
System.arraycopy(result, 0, result1, 0, i);
return result1;
}
return result;
}
/** /**
* Split a String at the first occurrence of the delimiter. * Split a String at the first occurrence of the delimiter.
* Does not include the delimiter in the result. * Does not include the delimiter in the result.

View File

@ -19,10 +19,10 @@
package org.elasticsearch.common.path; package org.elasticsearch.common.path;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.ImmutableMap; import org.elasticsearch.common.collect.ImmutableMap;
import java.util.Map; import java.util.Map;
import java.util.regex.Pattern;
import static org.elasticsearch.common.collect.MapBuilder.*; import static org.elasticsearch.common.collect.MapBuilder.*;
@ -43,21 +43,21 @@ public class PathTrie<T> {
private final Decoder decoder; private final Decoder decoder;
private final TrieNode<T> root; private final TrieNode<T> root;
private final Pattern pattern; private final char separator;
private T rootValue; private T rootValue;
public PathTrie() { public PathTrie() {
this("/", "*", NO_DECODER); this('/', "*", NO_DECODER);
} }
public PathTrie(Decoder decoder) { public PathTrie(Decoder decoder) {
this("/", "*", decoder); this('/', "*", decoder);
} }
public PathTrie(String separator, String wildcard, Decoder decoder) { public PathTrie(char separator, String wildcard, Decoder decoder) {
this.decoder = decoder; this.decoder = decoder;
pattern = Pattern.compile(separator); this.separator = separator;
root = new TrieNode<T>(separator, null, null, wildcard); root = new TrieNode<T>(new String(new char[]{separator}), null, null, wildcard);
} }
public class TrieNode<T> { public class TrieNode<T> {
@ -193,7 +193,7 @@ public class PathTrie<T> {
} }
public void insert(String path, T value) { public void insert(String path, T value) {
String[] strings = pattern.split(path); String[] strings = Strings.splitStringToArray(path, separator);
if (strings.length == 0) { if (strings.length == 0) {
rootValue = value; rootValue = value;
return; return;
@ -214,7 +214,7 @@ public class PathTrie<T> {
if (path.length() == 0) { if (path.length() == 0) {
return rootValue; return rootValue;
} }
String[] strings = pattern.split(path); String[] strings = Strings.splitStringToArray(path, separator);
if (strings.length == 0) { if (strings.length == 0) {
return rootValue; return rootValue;
} }

View File

@ -23,6 +23,7 @@ import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.client.Client; import org.elasticsearch.client.Client;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
@ -34,7 +35,6 @@ import org.elasticsearch.rest.XContentRestResponse;
import org.elasticsearch.rest.XContentThrowableRestResponse; import org.elasticsearch.rest.XContentThrowableRestResponse;
import java.io.IOException; import java.io.IOException;
import java.util.regex.Pattern;
import static org.elasticsearch.rest.RestRequest.Method.*; import static org.elasticsearch.rest.RestRequest.Method.*;
import static org.elasticsearch.rest.RestStatus.*; import static org.elasticsearch.rest.RestStatus.*;
@ -45,12 +45,6 @@ import static org.elasticsearch.rest.action.support.RestXContentBuilder.*;
*/ */
public class RestGetAction extends BaseRestHandler { public class RestGetAction extends BaseRestHandler {
private final static Pattern fieldsPattern;
static {
fieldsPattern = Pattern.compile(",");
}
@Inject public RestGetAction(Settings settings, Client client, RestController controller) { @Inject public RestGetAction(Settings settings, Client client, RestController controller) {
super(settings, client); super(settings, client);
controller.registerHandler(GET, "/{index}/{type}/{id}", this); controller.registerHandler(GET, "/{index}/{type}/{id}", this);
@ -69,7 +63,7 @@ public class RestGetAction extends BaseRestHandler {
String sField = request.param("fields"); String sField = request.param("fields");
if (sField != null) { if (sField != null) {
String[] sFields = fieldsPattern.split(sField); String[] sFields = Strings.splitStringByCommaToArray(sField);
if (sFields != null) { if (sFields != null) {
getRequest.fields(sFields); getRequest.fields(sFields);
} }

View File

@ -43,7 +43,6 @@ import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder; import org.elasticsearch.search.sort.SortOrder;
import java.io.IOException; import java.io.IOException;
import java.util.regex.Pattern;
import static org.elasticsearch.common.unit.TimeValue.*; import static org.elasticsearch.common.unit.TimeValue.*;
import static org.elasticsearch.rest.RestRequest.Method.*; import static org.elasticsearch.rest.RestRequest.Method.*;
@ -55,15 +54,6 @@ import static org.elasticsearch.rest.action.support.RestXContentBuilder.*;
*/ */
public class RestSearchAction extends BaseRestHandler { public class RestSearchAction extends BaseRestHandler {
private final static Pattern fieldsPattern;
private final static Pattern indicesBoostPattern;
static {
fieldsPattern = Pattern.compile(",");
indicesBoostPattern = Pattern.compile(",");
}
@Inject public RestSearchAction(Settings settings, Client client, RestController controller) { @Inject public RestSearchAction(Settings settings, Client client, RestController controller) {
super(settings, client); super(settings, client);
controller.registerHandler(GET, "/_search", this); controller.registerHandler(GET, "/_search", this);
@ -192,7 +182,7 @@ public class RestSearchAction extends BaseRestHandler {
if (!Strings.hasText(sField)) { if (!Strings.hasText(sField)) {
searchSourceBuilder.noFields(); searchSourceBuilder.noFields();
} else { } else {
String[] sFields = fieldsPattern.split(sField); String[] sFields = Strings.splitStringByCommaToArray(sField);
if (sFields != null) { if (sFields != null) {
for (String field : sFields) { for (String field : sFields) {
searchSourceBuilder.field(field); searchSourceBuilder.field(field);
@ -203,7 +193,7 @@ public class RestSearchAction extends BaseRestHandler {
String sSorts = request.param("sort"); String sSorts = request.param("sort");
if (sSorts != null) { if (sSorts != null) {
String[] sorts = fieldsPattern.split(sSorts); String[] sorts = Strings.splitStringByCommaToArray(sSorts);
for (String sort : sorts) { for (String sort : sorts) {
int delimiter = sort.lastIndexOf(":"); int delimiter = sort.lastIndexOf(":");
if (delimiter != -1) { if (delimiter != -1) {
@ -222,7 +212,7 @@ public class RestSearchAction extends BaseRestHandler {
String sIndicesBoost = request.param("indices_boost"); String sIndicesBoost = request.param("indices_boost");
if (sIndicesBoost != null) { if (sIndicesBoost != null) {
String[] indicesBoost = indicesBoostPattern.split(sIndicesBoost); String[] indicesBoost = Strings.splitStringByCommaToArray(sIndicesBoost);
for (String indexBoost : indicesBoost) { for (String indexBoost : indicesBoost) {
int divisor = indexBoost.indexOf(','); int divisor = indexBoost.indexOf(',');
if (divisor == -1) { if (divisor == -1) {

View File

@ -29,18 +29,12 @@ import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.elasticsearch.rest.RestRequest; import org.elasticsearch.rest.RestRequest;
import java.io.IOException; import java.io.IOException;
import java.util.regex.Pattern;
/** /**
* @author kimchy (Shay Banon) * @author kimchy (Shay Banon)
*/ */
public class RestActions { public class RestActions {
public final static Pattern indicesPattern = Pattern.compile(",");
public final static Pattern typesPattern = Pattern.compile(",");
public final static Pattern nodesIdsPattern = Pattern.compile(",");
public final static Pattern genericPattern = Pattern.compile(",");
public static long parseVersion(RestRequest request) { public static long parseVersion(RestRequest request) {
if (request.hasParam("version")) { if (request.hasParam("version")) {
return request.paramAsLong("version", 0); return request.paramAsLong("version", 0);
@ -100,20 +94,20 @@ public class RestActions {
if (indices == null) { if (indices == null) {
return Strings.EMPTY_ARRAY; return Strings.EMPTY_ARRAY;
} }
return indicesPattern.split(indices); return Strings.splitStringByCommaToArray(indices);
} }
public static String[] splitTypes(String typeNames) { public static String[] splitTypes(String typeNames) {
if (typeNames == null) { if (typeNames == null) {
return Strings.EMPTY_ARRAY; return Strings.EMPTY_ARRAY;
} }
return typesPattern.split(typeNames); return Strings.splitStringByCommaToArray(typeNames);
} }
public static String[] splitNodes(String nodes) { public static String[] splitNodes(String nodes) {
if (nodes == null) { if (nodes == null) {
return Strings.EMPTY_ARRAY; return Strings.EMPTY_ARRAY;
} }
return nodesIdsPattern.split(nodes); return Strings.splitStringByCommaToArray(nodes);
} }
} }

View File

@ -21,12 +21,11 @@ package org.elasticsearch.rest.support;
import org.elasticsearch.ElasticSearchIllegalArgumentException; import org.elasticsearch.ElasticSearchIllegalArgumentException;
import org.elasticsearch.common.Booleans; import org.elasticsearch.common.Booleans;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.rest.RestRequest; import org.elasticsearch.rest.RestRequest;
import java.util.regex.Pattern;
import static org.elasticsearch.common.unit.ByteSizeValue.*; import static org.elasticsearch.common.unit.ByteSizeValue.*;
import static org.elasticsearch.common.unit.TimeValue.*; import static org.elasticsearch.common.unit.TimeValue.*;
@ -35,8 +34,6 @@ import static org.elasticsearch.common.unit.TimeValue.*;
*/ */
public abstract class AbstractRestRequest implements RestRequest { public abstract class AbstractRestRequest implements RestRequest {
private static final Pattern commaPattern = Pattern.compile(",");
@Override public final String path() { @Override public final String path() {
return RestUtils.decodeComponent(rawPath()); return RestUtils.decodeComponent(rawPath());
} }
@ -102,6 +99,6 @@ public abstract class AbstractRestRequest implements RestRequest {
if (value == null) { if (value == null) {
return defaultValue; return defaultValue;
} }
return commaPattern.split(value); return Strings.splitStringByCommaToArray(value);
} }
} }