kafka-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject [kafka] branch trunk updated: MINOR: Use statically compiled regular expressions for efficiency (#5168)
Date Tue, 14 Aug 2018 00:31:33 GMT
This is an automated email from the ASF dual-hosted git repository.

jgus pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/kafka.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 9e0e29a  MINOR: Use statically compiled regular expressions for efficiency (#5168)
9e0e29a is described below

commit 9e0e29ac5c354079a4306641bc3a44ff6c4ac041
Author: Koen De Groote <kdg.private@gmail.com>
AuthorDate: Tue Aug 14 02:31:29 2018 +0200

    MINOR: Use statically compiled regular expressions for efficiency (#5168)
    
    Reviewers: Andras Beni <andrasbeni@cloudera.com>, Sriharsha Chintalapani <sriharsha@apache.org>,
Jason Gustafson <jason@confluent.io>
---
 .../java/org/apache/kafka/common/config/ConfigDef.java  |  6 +++++-
 .../OAuthBearerUnsecuredLoginCallbackHandler.java       |  9 ++++++++-
 .../common/security/scram/internals/ScramFormatter.java | 17 +++++++++++++----
 .../main/java/org/apache/kafka/connect/data/Values.java |  8 +++++++-
 .../org/apache/kafka/connect/runtime/WorkerConfig.java  |  5 ++++-
 .../kafka/connect/runtime/isolation/PluginUtils.java    | 11 ++++++-----
 .../kafka/connect/runtime/rest/util/SSLUtils.java       |  6 +++++-
 .../kafka/connect/transforms/TimestampRouter.java       | 10 +++++++++-
 .../streams/processor/internals/StateDirectory.java     |  6 ++++--
 .../kafka/streams/state/internals/OffsetCheckpoint.java |  5 ++++-
 .../kafka/streams/state/internals/RocksDBStore.java     |  5 ++++-
 11 files changed, 69 insertions(+), 19 deletions(-)

diff --git a/clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java b/clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java
index af2f6c4..662909a 100644
--- a/clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java
+++ b/clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java
@@ -32,6 +32,7 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
+import java.util.regex.Pattern;
 
 /**
  * This class is used for specifying the set of expected configurations. For each configuration,
you can specify
@@ -73,6 +74,9 @@ import java.util.Set;
  * functionality for accessing configs.
  */
 public class ConfigDef {
+
+    private static final Pattern COMMA_WITH_WHITESPACE = Pattern.compile("\\s*,\\s*");
+
     /**
      * A unique Java object which represents the lack of a default value.
      */
@@ -703,7 +707,7 @@ public class ConfigDef {
                         if (trimmed.isEmpty())
                             return Collections.emptyList();
                         else
-                            return Arrays.asList(trimmed.split("\\s*,\\s*", -1));
+                            return Arrays.asList(COMMA_WITH_WHITESPACE.split(trimmed, -1));
                     else
                         throw new ConfigException(name, value, "Expected a comma separated
list.");
                 case CLASS:
diff --git a/clients/src/main/java/org/apache/kafka/common/security/oauthbearer/internals/unsecured/OAuthBearerUnsecuredLoginCallbackHandler.java
b/clients/src/main/java/org/apache/kafka/common/security/oauthbearer/internals/unsecured/OAuthBearerUnsecuredLoginCallbackHandler.java
index 88399ac..83b2602 100644
--- a/clients/src/main/java/org/apache/kafka/common/security/oauthbearer/internals/unsecured/OAuthBearerUnsecuredLoginCallbackHandler.java
+++ b/clients/src/main/java/org/apache/kafka/common/security/oauthbearer/internals/unsecured/OAuthBearerUnsecuredLoginCallbackHandler.java
@@ -28,6 +28,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.UnsupportedCallbackException;
@@ -114,6 +116,10 @@ public class OAuthBearerUnsecuredLoginCallbackHandler implements AuthenticateCal
     private Map<String, String> moduleOptions = null;
     private boolean configured = false;
 
+    private static final Pattern DOUBLEQUOTE = Pattern.compile("\"", Pattern.LITERAL);
+
+    private static final Pattern BACKSLASH = Pattern.compile("\\", Pattern.LITERAL);
+
     /**
      * For testing
      * 
@@ -322,7 +328,8 @@ public class OAuthBearerUnsecuredLoginCallbackHandler implements AuthenticateCal
     }
 
     private String escape(String jsonStringValue) {
-        return jsonStringValue.replace("\"", "\\\"").replace("\\", "\\\\");
+        String replace1 = DOUBLEQUOTE.matcher(jsonStringValue).replaceAll(Matcher.quoteReplacement("\\\""));
+        return BACKSLASH.matcher(replace1).replaceAll(Matcher.quoteReplacement("\\\\"));
     }
 
     private String expClaimText(long lifetimeSeconds) {
diff --git a/clients/src/main/java/org/apache/kafka/common/security/scram/internals/ScramFormatter.java
b/clients/src/main/java/org/apache/kafka/common/security/scram/internals/ScramFormatter.java
index 7fcaecc..2a22ff4 100644
--- a/clients/src/main/java/org/apache/kafka/common/security/scram/internals/ScramFormatter.java
+++ b/clients/src/main/java/org/apache/kafka/common/security/scram/internals/ScramFormatter.java
@@ -22,6 +22,8 @@ import java.security.InvalidKeyException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import javax.crypto.Mac;
 import javax.crypto.spec.SecretKeySpec;
@@ -37,6 +39,11 @@ import org.apache.kafka.common.security.scram.internals.ScramMessages.ServerFirs
  */
 public class ScramFormatter {
 
+    private static final Pattern EQUAL = Pattern.compile("=", Pattern.LITERAL);
+    private static final Pattern COMMA = Pattern.compile(",", Pattern.LITERAL);
+    private static final Pattern EQUAL_TWO_C = Pattern.compile("=2C", Pattern.LITERAL);
+    private static final Pattern EQUAL_THREE_D = Pattern.compile("=3D", Pattern.LITERAL);
+
     private final MessageDigest messageDigest;
     private final Mac mac;
     private final SecureRandom random;
@@ -96,14 +103,16 @@ public class ScramFormatter {
     }
 
     public String saslName(String username) {
-        return username.replace("=", "=3D").replace(",", "=2C");
+        String replace1 = EQUAL.matcher(username).replaceAll(Matcher.quoteReplacement("=3D"));
+        return COMMA.matcher(replace1).replaceAll(Matcher.quoteReplacement("=2C"));
     }
 
     public String username(String saslName) {
-        String username = saslName.replace("=2C", ",");
-        if (username.replace("=3D", "").indexOf('=') >= 0)
+        String username = EQUAL_TWO_C.matcher(saslName).replaceAll(Matcher.quoteReplacement(","));
+        if (EQUAL_THREE_D.matcher(username).replaceAll(Matcher.quoteReplacement("")).indexOf('=')
>= 0) {
             throw new IllegalArgumentException("Invalid username: " + saslName);
-        return username.replace("=3D", "=");
+        }
+        return EQUAL_THREE_D.matcher(username).replaceAll(Matcher.quoteReplacement("="));
     }
 
     public String authMessage(String clientFirstMessageBare, String serverFirstMessage, String
clientFinalMessageWithoutProof) {
diff --git a/connect/api/src/main/java/org/apache/kafka/connect/data/Values.java b/connect/api/src/main/java/org/apache/kafka/connect/data/Values.java
index d643aa2..ceb1768 100644
--- a/connect/api/src/main/java/org/apache/kafka/connect/data/Values.java
+++ b/connect/api/src/main/java/org/apache/kafka/connect/data/Values.java
@@ -38,6 +38,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.TimeZone;
+import java.util.regex.Pattern;
 
 /**
  * Utility for converting from one Connect value to a different form. This is useful when
the caller expects a value of a particular type
@@ -84,6 +85,10 @@ public class Values {
     private static final int ISO_8601_TIME_LENGTH = ISO_8601_TIME_FORMAT_PATTERN.length()
- 2; // subtract single quotes
     private static final int ISO_8601_TIMESTAMP_LENGTH = ISO_8601_TIMESTAMP_FORMAT_PATTERN.length()
- 4; // subtract single quotes
 
+    private static final Pattern TWO_BACKSLASHES = Pattern.compile("\\\\");
+
+    private static final Pattern DOUBLEQOUTE = Pattern.compile("\"");
+
     /**
      * Convert the specified value to an {@link Type#BOOLEAN} value. The supplied schema
is required if the value is a logical
      * type when the schema contains critical information that might be necessary for converting
to a boolean.
@@ -704,7 +709,8 @@ public class Values {
     }
 
     protected static String escape(String value) {
-        return value.replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\\\\\"");
+        String replace1 = TWO_BACKSLASHES.matcher(value).replaceAll("\\\\\\\\");
+        return DOUBLEQOUTE.matcher(replace1).replaceAll("\\\\\"");
     }
 
     protected static DateFormat dateFormatFor(java.util.Date value) {
diff --git a/connect/runtime/src/main/java/org/apache/kafka/connect/runtime/WorkerConfig.java
b/connect/runtime/src/main/java/org/apache/kafka/connect/runtime/WorkerConfig.java
index 583953d..c5baaa4 100644
--- a/connect/runtime/src/main/java/org/apache/kafka/connect/runtime/WorkerConfig.java
+++ b/connect/runtime/src/main/java/org/apache/kafka/connect/runtime/WorkerConfig.java
@@ -35,6 +35,7 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Pattern;
 
 import static org.apache.kafka.common.config.ConfigDef.Range.atLeast;
 import static org.apache.kafka.common.config.ConfigDef.ValidString.in;
@@ -45,6 +46,8 @@ import static org.apache.kafka.common.config.ConfigDef.ValidString.in;
 public class WorkerConfig extends AbstractConfig {
     private static final Logger log = LoggerFactory.getLogger(WorkerConfig.class);
 
+    private static final Pattern COMMA_WITH_WHITESPACE = Pattern.compile("\\s*,\\s*");
+
     public static final String BOOTSTRAP_SERVERS_CONFIG = "bootstrap.servers";
     public static final String BOOTSTRAP_SERVERS_DOC
             = "A list of host/port pairs to use for establishing the initial connection to
the Kafka "
@@ -338,7 +341,7 @@ public class WorkerConfig extends AbstractConfig {
         String locationList = props.get(WorkerConfig.PLUGIN_PATH_CONFIG);
         return locationList == null
                          ? new ArrayList<String>()
-                         : Arrays.asList(locationList.trim().split("\\s*,\\s*", -1));
+                         : Arrays.asList(COMMA_WITH_WHITESPACE.split(locationList.trim(),
-1));
     }
 
     public WorkerConfig(ConfigDef definition, Map<String, String> props) {
diff --git a/connect/runtime/src/main/java/org/apache/kafka/connect/runtime/isolation/PluginUtils.java
b/connect/runtime/src/main/java/org/apache/kafka/connect/runtime/isolation/PluginUtils.java
index a9a273e..8d2a3ce 100644
--- a/connect/runtime/src/main/java/org/apache/kafka/connect/runtime/isolation/PluginUtils.java
+++ b/connect/runtime/src/main/java/org/apache/kafka/connect/runtime/isolation/PluginUtils.java
@@ -35,6 +35,7 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Set;
 import java.util.TreeSet;
+import java.util.regex.Pattern;
 
 /**
  * Connect plugin utility methods.
@@ -43,7 +44,7 @@ public class PluginUtils {
     private static final Logger log = LoggerFactory.getLogger(PluginUtils.class);
 
     // Be specific about javax packages and exclude those existing in Java SE and Java EE
libraries.
-    private static final String BLACKLIST = "^(?:"
+    private static final Pattern BLACKLIST = Pattern.compile("^(?:"
             + "java"
             + "|javax\\.accessibility"
             + "|javax\\.activation"
@@ -120,9 +121,9 @@ public class PluginUtils {
             + "|org\\.xml\\.sax"
             + "|org\\.apache\\.kafka"
             + "|org\\.slf4j"
-            + ")\\..*$";
+            + ")\\..*$");
 
-    private static final String WHITELIST = "^org\\.apache\\.kafka\\.(?:connect\\.(?:"
+    private static final Pattern WHITELIST = Pattern.compile("^org\\.apache\\.kafka\\.(?:connect\\.(?:"
             + "transforms\\.(?!Transformation$).*"
             + "|json\\..*"
             + "|file\\..*"
@@ -132,7 +133,7 @@ public class PluginUtils {
             + "|rest\\.basic\\.auth\\.extension\\.BasicAuthSecurityRestExtension"
             + ")"
             + "|common\\.config\\.provider\\.(?!ConfigProvider$).*"
-            + ")$";
+            + ")$");
 
     private static final DirectoryStream.Filter<Path> PLUGIN_PATH_FILTER = new DirectoryStream
             .Filter<Path>() {
@@ -150,7 +151,7 @@ public class PluginUtils {
      * @return true if this class should be loaded in isolation, false otherwise.
      */
     public static boolean shouldLoadInIsolation(String name) {
-        return !(name.matches(BLACKLIST) && !name.matches(WHITELIST));
+        return !(BLACKLIST.matcher(name).matches() && !WHITELIST.matcher(name).matches());
     }
 
     /**
diff --git a/connect/runtime/src/main/java/org/apache/kafka/connect/runtime/rest/util/SSLUtils.java
b/connect/runtime/src/main/java/org/apache/kafka/connect/runtime/rest/util/SSLUtils.java
index f9bac0d..980d7c2 100644
--- a/connect/runtime/src/main/java/org/apache/kafka/connect/runtime/rest/util/SSLUtils.java
+++ b/connect/runtime/src/main/java/org/apache/kafka/connect/runtime/rest/util/SSLUtils.java
@@ -25,11 +25,15 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Pattern;
 
 /**
  * Helper class for setting up SSL for RestServer and RestClient
  */
 public class SSLUtils {
+
+    private static final Pattern COMMA_WITH_WHITESPACE = Pattern.compile("\\s*,\\s*");
+
     /**
      * Configures SSL/TLS for HTTPS Jetty Server / Client
      */
@@ -101,7 +105,7 @@ public class SSLUtils {
      * Configures Protocol, Algorithm and Provider related settings in SslContextFactory
      */
     protected static void configureSslContextFactoryAlgorithms(SslContextFactory ssl, Map<String,
Object> sslConfigValues) {
-        List<String> sslEnabledProtocols = (List<String>) getOrDefault(sslConfigValues,
SslConfigs.SSL_ENABLED_PROTOCOLS_CONFIG, Arrays.asList(SslConfigs.DEFAULT_SSL_ENABLED_PROTOCOLS.split("\\s*,\\s*")));
+        List<String> sslEnabledProtocols = (List<String>) getOrDefault(sslConfigValues,
SslConfigs.SSL_ENABLED_PROTOCOLS_CONFIG, Arrays.asList(COMMA_WITH_WHITESPACE.split(SslConfigs.DEFAULT_SSL_ENABLED_PROTOCOLS)));
         ssl.setIncludeProtocols(sslEnabledProtocols.toArray(new String[sslEnabledProtocols.size()]));
 
         String sslProvider = (String) sslConfigValues.get(SslConfigs.SSL_PROVIDER_CONFIG);
diff --git a/connect/transforms/src/main/java/org/apache/kafka/connect/transforms/TimestampRouter.java
b/connect/transforms/src/main/java/org/apache/kafka/connect/transforms/TimestampRouter.java
index 938ef0f..a0343b8 100644
--- a/connect/transforms/src/main/java/org/apache/kafka/connect/transforms/TimestampRouter.java
+++ b/connect/transforms/src/main/java/org/apache/kafka/connect/transforms/TimestampRouter.java
@@ -25,9 +25,15 @@ import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Map;
 import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 public class TimestampRouter<R extends ConnectRecord<R>> implements Transformation<R>
{
 
+    private static final Pattern TOPIC = Pattern.compile("${topic}", Pattern.LITERAL);
+
+    private static final Pattern TIMESTAMP = Pattern.compile("${timestamp}", Pattern.LITERAL);
+
     public static final String OVERVIEW_DOC =
             "Update the record's topic field as a function of the original topic value and
the record timestamp."
                     + "<p/>"
@@ -72,7 +78,9 @@ public class TimestampRouter<R extends ConnectRecord<R>> implements
Transformati
             throw new DataException("Timestamp missing on record: " + record);
         }
         final String formattedTimestamp = timestampFormat.get().format(new Date(timestamp));
-        final String updatedTopic = topicFormat.replace("${topic}", record.topic()).replace("${timestamp}",
formattedTimestamp);
+
+        final String replace1 = TOPIC.matcher(topicFormat).replaceAll(Matcher.quoteReplacement(record.topic()));
+        final String updatedTopic = TIMESTAMP.matcher(replace1).replaceAll(Matcher.quoteReplacement(formattedTimestamp));
         return record.newRecord(
                 updatedTopic, record.kafkaPartition(),
                 record.keySchema(), record.key(),
diff --git a/streams/src/main/java/org/apache/kafka/streams/processor/internals/StateDirectory.java
b/streams/src/main/java/org/apache/kafka/streams/processor/internals/StateDirectory.java
index 4f12384..a3227ca 100644
--- a/streams/src/main/java/org/apache/kafka/streams/processor/internals/StateDirectory.java
+++ b/streams/src/main/java/org/apache/kafka/streams/processor/internals/StateDirectory.java
@@ -35,6 +35,7 @@ import java.nio.file.NoSuchFileException;
 import java.nio.file.Path;
 import java.nio.file.StandardOpenOption;
 import java.util.HashMap;
+import java.util.regex.Pattern;
 
 /**
  * Manages the directories where the state of Tasks owned by a {@link StreamThread} are
@@ -43,6 +44,8 @@ import java.util.HashMap;
  */
 public class StateDirectory {
 
+    private static final Pattern PATH_NAME = Pattern.compile("\\d+_\\d+");
+
     static final String LOCK_FILE_NAME = ".lock";
     private static final Logger log = LoggerFactory.getLogger(StateDirectory.class);
 
@@ -320,8 +323,7 @@ public class StateDirectory {
         return stateDir.listFiles(new FileFilter() {
             @Override
             public boolean accept(final File pathname) {
-                final String name = pathname.getName();
-                return pathname.isDirectory() && name.matches("\\d+_\\d+");
+                return pathname.isDirectory() && PATH_NAME.matcher(pathname.getName()).matches();
             }
         });
     }
diff --git a/streams/src/main/java/org/apache/kafka/streams/state/internals/OffsetCheckpoint.java
b/streams/src/main/java/org/apache/kafka/streams/state/internals/OffsetCheckpoint.java
index 34e0947..405831a 100644
--- a/streams/src/main/java/org/apache/kafka/streams/state/internals/OffsetCheckpoint.java
+++ b/streams/src/main/java/org/apache/kafka/streams/state/internals/OffsetCheckpoint.java
@@ -32,6 +32,7 @@ import java.nio.file.NoSuchFileException;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.regex.Pattern;
 
 /**
  * This class saves out a map of topic/partition=&gt;offsets to a file. The format of
the file is UTF-8 text containing the following:
@@ -50,6 +51,8 @@ import java.util.Map;
  */
 public class OffsetCheckpoint {
 
+    private static final Pattern WHITESPACE_MINIMUM_ONCE = Pattern.compile("\\s+");
+
     private static final int VERSION = 0;
 
     private final File file;
@@ -129,7 +132,7 @@ public class OffsetCheckpoint {
                         final Map<TopicPartition, Long> offsets = new HashMap<>();
                         String line = reader.readLine();
                         while (line != null) {
-                            final String[] pieces = line.split("\\s+");
+                            final String[] pieces = WHITESPACE_MINIMUM_ONCE.split(line);
                             if (pieces.length != 3) {
                                 throw new IOException(
                                     String.format("Malformed line in offset checkpoint file:
'%s'.", line));
diff --git a/streams/src/main/java/org/apache/kafka/streams/state/internals/RocksDBStore.java
b/streams/src/main/java/org/apache/kafka/streams/state/internals/RocksDBStore.java
index c0e8363..559f4a5 100644
--- a/streams/src/main/java/org/apache/kafka/streams/state/internals/RocksDBStore.java
+++ b/streams/src/main/java/org/apache/kafka/streams/state/internals/RocksDBStore.java
@@ -56,6 +56,7 @@ import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Objects;
 import java.util.Set;
+import java.util.regex.Pattern;
 
 /**
  * A persistent key-value store based on RocksDB.
@@ -66,6 +67,8 @@ import java.util.Set;
  */
 public class RocksDBStore implements KeyValueStore<Bytes, byte[]> {
 
+    private static final Pattern SST_FILE_EXTENSION = Pattern.compile(".*\\.sst");
+
     private static final int TTL_NOT_USED = -1;
 
     private static final CompressionType COMPRESSION_TYPE = CompressionType.NO_COMPRESSION;
@@ -238,7 +241,7 @@ public class RocksDBStore implements KeyValueStore<Bytes, byte[]>
{
             final String[] sstFileNames = dbDir.list(new FilenameFilter() {
                 @Override
                 public boolean accept(final File dir, final String name) {
-                    return name.matches(".*\\.sst");
+                    return SST_FILE_EXTENSION.matcher(name).matches();
                 }
             });
 


Mime
View raw message