Avoid regex in QueryId.*
This function's regex matching and splitting was responsible for ~1.8%
of allocations in one Presto run according to allocation profiling.
@@ -22,7 +22,6 @@ import com.fasterxml.jackson.annotation.JsonValue;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
-import java.util.regex.Pattern;
import static java.lang.String.format;
import static java.util.Collections.unmodifiableList;
@@ -34,8 +33,8 @@ public final class QueryId
@JsonCreator
public static QueryId valueOf(String queryId)
{
- List<String> ids = parseDottedId(queryId, 1, "queryId");
- return new QueryId(ids.get(0));
+ // ID is verified in the constructor
+ return new QueryId(queryId);
}
private final String id;
@@ -82,13 +81,27 @@ public final class QueryId
// Id helper methods
//
- private static final Pattern ID_PATTERN = Pattern.compile("[_a-z0-9]+");
+ // Check if the string matches [_a-z0-9]+ , but without the overhead of regex
+ private static final boolean isIdMatchPattern(String id)
+ {
+ if (id.length() == 0) {
+ return false;
+ }
+
+ for (int i = 0; i < id.length(); i++) {
+ char c = id.charAt(i);
+ if (!(c == '_' || c >= 'a' && c <= 'z' || c >= '0' && c <= '9')) {
+ return false;
+ }
+ }
+ return true;
+ }
public static String validateId(String id)
{
requireNonNull(id, "id is null");
checkArgument(!id.isEmpty(), "id is empty");
- checkArgument(ID_PATTERN.matcher(id).matches(), "Invalid id %s", id);
+ checkArgument(isIdMatchPattern(id), "Invalid id %s", id);
return id;
}
@@ -103,7 +116,7 @@ public final class QueryId
for (String part : ids) {
checkArgument(!part.isEmpty(), "Invalid id %s", id);
- checkArgument(ID_PATTERN.matcher(part).matches(), "Invalid id %s", id);
+ checkArgument(isIdMatchPattern(part), "Invalid id %s", id);
}
return ids;
}
