This is an automated email from the ASF dual-hosted git repository. blerer pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/cassandra.git
The following commit(s) were added to refs/heads/trunk by this push: new 11952fa Avoid unecessary array allocations and initializations when performing query checks 11952fa is described below commit 11952fae774d51d4e268dae506803fef874c8c50 Author: Benjamin Lerer <b.le...@gmail.com> AuthorDate: Wed Dec 15 12:41:29 2021 +0100 Avoid unecessary array allocations and initializations when performing query checks patch by Benjamin Lerer; reviewed by Caleb Rackliffe for CASSANDRA-17209 --- CHANGES.txt | 1 + .../cql3/statements/RequestValidations.java | 265 ++++++++++++++++----- 2 files changed, 210 insertions(+), 56 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 771302e..6208963 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 4.1 + * Avoid unecessary array allocations and initializations when performing query checks (CASSANDRA-17209) * Add guardrail for list operations that require read before write (CASSANDRA-17154) * Migrate thresholds for number of keyspaces and tables to guardrails (CASSANDRA-17195) * Remove self-reference in SSTableTidier (CASSANDRA-17205) diff --git a/src/java/org/apache/cassandra/cql3/statements/RequestValidations.java b/src/java/org/apache/cassandra/cql3/statements/RequestValidations.java index f351788..cdaac98 100644 --- a/src/java/org/apache/cassandra/cql3/statements/RequestValidations.java +++ b/src/java/org/apache/cassandra/cql3/statements/RequestValidations.java @@ -26,42 +26,136 @@ import java.util.List; import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.utils.ByteBufferUtil; -import static org.apache.commons.lang3.ArrayUtils.EMPTY_OBJECT_ARRAY; - /** * Utility methods use to perform request validation. + * + * <p>This class use overloaded methods to allow to specify different numbers of message arguments. While + * this introduces some clutter in the API, it avoids array allocation, initialization, and garbage collection + * overhead that is incurred by varargs calls. </p> + * + * <b>Warning about performance</b> + * + * <p>The goal of this class is to improve readability of code, but in some circumstances this may come at a + * significant performance cost. Remember that argument values for message construction must all be computed eagerly, + * and autoboxing may happen as well, even when the check succeeds. If the message arguments are expensive to create + * you should use the customary form: + * <pre> + * if (value < 0.0) + * throw RequestValidations.invalidRequest("negative value: %s", toReadableText(value)); + * </pre> + * </p> */ public final class RequestValidations { /** - * Checks that the specified expression is <code>true</code>. If not an <code>InvalidRequestException</code> will + * Checks that the specified expression is {@code true}. If not an {@code InvalidRequestException} will * be thrown. * * @param expression the expression to test * @param message the error message - * @throws InvalidRequestException if the specified expression is <code>false</code>. + * @throws InvalidRequestException if the specified expression is {@code false}. */ public static void checkTrue(boolean expression, String message) throws InvalidRequestException { - checkTrue(expression, message, EMPTY_OBJECT_ARRAY); + if (!expression) + throw invalidRequest(message); } /** - * Checks that the specified expression is <code>true</code>. If not an <code>InvalidRequestException</code> will + * Checks that the specified expression is <code>true</code>. If not an {@code InvalidRequestException} will * be thrown. * * @param expression the expression to test * @param messageTemplate the template used to build the error message - * @param messageArgs the message arguments - * @throws InvalidRequestException if the specified expression is <code>false</code>. + * @param messageArg the message argument + * @throws InvalidRequestException if the specified expression is {@code false}. + */ + public static void checkTrue(boolean expression, + String messageTemplate, + Object messageArg) throws InvalidRequestException + { + if (!expression) + throw invalidRequest(messageTemplate, messageArg); + } + + /** + * Checks that the specified expression is <code>true</code>. If not an {@code InvalidRequestException} will + * be thrown. + * + * @param expression the expression to test + * @param messageTemplate the template used to build the error message + * @param arg1 the first message argument + * @param arg2 the second message argument + * @throws InvalidRequestException if the specified expression is {@code false}. + */ + public static void checkTrue(boolean expression, + String messageTemplate, + Object arg1, + Object arg2) throws InvalidRequestException + { + if (!expression) + throw invalidRequest(messageTemplate, arg1, arg2); + } + + /** + * Checks that the specified expression is <code>true</code>. If not an {@code InvalidRequestException} will + * be thrown. + * + * @param expression the expression to test + * @param messageTemplate the template used to build the error message + * @param arg1 the first message argument + * @param arg2 the second message argument + * @param arg3 the third message argument + * @throws InvalidRequestException if the specified expression is {@code false}. */ public static void checkTrue(boolean expression, String messageTemplate, - Object... messageArgs) - throws InvalidRequestException + Object arg1, + Object arg2, + Object arg3) throws InvalidRequestException { if (!expression) - throw invalidRequest(messageTemplate, messageArgs); + throw invalidRequest(messageTemplate, arg1, arg2, arg3); + } + + /** + * Checks that the specified collections is NOT <code>empty</code>. + * If it is an {@code InvalidRequestException} will be thrown. + * + * @param collection the collection to test + * @param messageTemplate the template used to build the error message + * @param messageArg the message argument + * @return the collection + * @throws InvalidRequestException if the specified collection is <code>empty</code>. + */ + public static <T extends Collection<E>, E> T checkNotEmpty(T collection, + String messageTemplate, + Object messageArg) + throws InvalidRequestException + { + checkTrue(!collection.isEmpty(), messageTemplate, messageArg); + return collection; + } + + /** + * Checks that the specified collections is NOT <code>empty</code>. + * If it is an {@code InvalidRequestException} will be thrown. + * + * @param collection the collection to test + * @param messageTemplate the template used to build the error message + * @param arg1 the first message argument + * @param arg2 the second message argument + * @return the collection + * @throws InvalidRequestException if the specified collection is <code>empty</code>. + */ + public static <T extends Collection<E>, E> T checkNotEmpty(T collection, + String messageTemplate, + Object arg1, + Object arg2) + throws InvalidRequestException + { + checkTrue(!collection.isEmpty(), messageTemplate, arg1, arg2); + return collection; } /** @@ -96,24 +190,60 @@ public final class RequestValidations } /** - * Checks that the specified expression is <code>false</code>. If not an <code>InvalidRequestException</code> will + * Checks that the specified expression is {@code false}. If not an {@code InvalidRequestException} will * be thrown. * * @param expression the expression to test * @param messageTemplate the template used to build the error message - * @param messageArgs the message arguments + * @param messageArg the message argument * @throws InvalidRequestException if the specified expression is <code>true</code>. */ public static void checkFalse(boolean expression, String messageTemplate, - Object... messageArgs) - throws InvalidRequestException + Object messageArg) throws InvalidRequestException { - checkTrue(!expression, messageTemplate, messageArgs); + checkTrue(!expression, messageTemplate, messageArg); } /** - * Checks that the specified expression is <code>false</code>. If not an <code>InvalidRequestException</code> will + * Checks that the specified expression is {@code false}. If not an {@code InvalidRequestException} will + * be thrown. + * + * @param expression the expression to test + * @param messageTemplate the template used to build the error message + * @param arg1 the first message argument + * @param arg2 the second message argument + * @throws InvalidRequestException if the specified expression is <code>true</code>. + */ + public static void checkFalse(boolean expression, + String messageTemplate, + Object arg1, + Object arg2) throws InvalidRequestException + { + checkTrue(!expression, messageTemplate, arg1, arg2); + } + + /** + * Checks that the specified expression is {@code false}. If not an {@code InvalidRequestException} will + * be thrown. + * + * @param expression the expression to test + * @param messageTemplate the template used to build the error message + * @param arg1 the first message argument + * @param arg2 the second message argument + * @param arg3 the third message argument + * @throws InvalidRequestException if the specified expression is <code>true</code>. + */ + public static void checkFalse(boolean expression, + String messageTemplate, + Object arg1, + Object arg2, + Object arg3) throws InvalidRequestException + { + checkTrue(!expression, messageTemplate, arg1, arg2, arg3); + } + /** + * Checks that the specified expression is {@code false}. If not an {@code InvalidRequestException} will * be thrown. * * @param expression the expression to test @@ -126,91 +256,114 @@ public final class RequestValidations } /** - * Checks that the specified object is NOT <code>null</code>. - * If it is an <code>InvalidRequestException</code> will be throws. + * Checks that the specified object is NOT {@code null}. + * If it is an {@code InvalidRequestException} will be thrown. + * + * @param object the object to test + * @param message the error message + * @return the object + * @throws InvalidRequestException if the specified object is {@code null}. + */ + public static <T> T checkNotNull(T object, String message) throws InvalidRequestException + { + checkTrue(object != null, message); + return object; + } + + /** + * Checks that the specified object is NOT {@code null}. + * If it is an {@code InvalidRequestException} will be thrown. * * @param object the object to test * @param messageTemplate the template used to build the error message - * @param messageArgs the message arguments + * @param messageArg the message argument * @return the object - * @throws InvalidRequestException if the specified object is <code>null</code>. + * @throws InvalidRequestException if the specified object is {@code null}. */ - public static <T> T checkNotNull(T object, String messageTemplate, Object... messageArgs) - throws InvalidRequestException + public static <T> T checkNotNull(T object, String messageTemplate, Object messageArg) throws InvalidRequestException { - checkTrue(object != null, messageTemplate, messageArgs); + checkTrue(object != null, messageTemplate, messageArg); return object; } /** - * Checks that the specified collections is NOT <code>empty</code>. - * If it is an <code>InvalidRequestException</code> will be throws. + * Checks that the specified object is NOT {@code null}. + * If it is an {@code InvalidRequestException} will be thrown. * - * @param collection the collection to test + * @param object the object to test * @param messageTemplate the template used to build the error message - * @param messageArgs the message arguments - * @return the collection - * @throws InvalidRequestException if the specified collection is <code>empty</code>. + * @param arg1 the first message argument + * @param arg2 the second message argument + * @return the object + * @throws InvalidRequestException if the specified object is {@code null}. */ - public static <T extends Collection<E>, E> T checkNotEmpty(T collection, String messageTemplate, Object... messageArgs) - throws InvalidRequestException + public static <T> T checkNotNull(T object, + String messageTemplate, + Object arg1, + Object arg2) throws InvalidRequestException { - checkTrue(!collection.isEmpty(), messageTemplate, messageArgs); - return collection; + checkTrue(object != null, messageTemplate, arg1, arg2); + return object; } /** * Checks that the specified bind marker value is set to a meaningful value. - * If it is not a <code>InvalidRequestException</code> will be thrown. + * If it is not a {@code InvalidRequestException} will be thrown. * * @param b the <code>ByteBuffer</code> to test * @param messageTemplate the template used to build the error message - * @param messageArgs the message arguments + * @param messageArg the message argument * @throws InvalidRequestException if the specified bind marker value is not set to a meaningful value. */ - public static void checkBindValueSet(ByteBuffer b, String messageTemplate, Object... messageArgs) - throws InvalidRequestException + public static void checkBindValueSet(ByteBuffer b, String messageTemplate, Object messageArg) throws InvalidRequestException { - checkTrue(b != ByteBufferUtil.UNSET_BYTE_BUFFER, messageTemplate, messageArgs); + checkTrue(b != ByteBufferUtil.UNSET_BYTE_BUFFER, messageTemplate, messageArg); } /** - * Checks that the specified object is <code>null</code>. - * If it is not an <code>InvalidRequestException</code> will be throws. + * Checks that the specified object is {@code null}. + * If it is not an {@code InvalidRequestException} will be thrown. * * @param object the object to test * @param messageTemplate the template used to build the error message - * @param messageArgs the message arguments - * @return the object - * @throws InvalidRequestException if the specified object is not <code>null</code>. + * @param messageArg the message argument + * @throws InvalidRequestException if the specified object is not {@code null}. */ - public static <T> T checkNull(T object, String messageTemplate, Object... messageArgs) - throws InvalidRequestException + public static void checkNull(Object object, String messageTemplate, Object messageArg) throws InvalidRequestException { - checkTrue(object == null, messageTemplate, messageArgs); - return object; + checkTrue(object == null, messageTemplate, messageArg); } /** - * Checks that the specified object is <code>null</code>. - * If it is not an <code>InvalidRequestException</code> will be throws. + * Checks that the specified object is {@code null}. + * If it is not an {@code InvalidRequestException} will be thrown. * * @param object the object to test * @param message the error message - * @return the object - * @throws InvalidRequestException if the specified object is not <code>null</code>. + * @throws InvalidRequestException if the specified object is not {@code null}. + */ + public static void checkNull(Object object, String message) throws InvalidRequestException + { + checkTrue(object == null, message); + } + + /** + * Returns an {@code InvalidRequestException} with the specified message. + * + * @param message the error message + * @return an {@code InvalidRequestException} with the specified message. */ - public static <T> T checkNull(T object, String message) throws InvalidRequestException + public static InvalidRequestException invalidRequest(String message) { - return checkNull(object, message, EMPTY_OBJECT_ARRAY); + return new InvalidRequestException(message); } /** - * Returns an <code>InvalidRequestException</code> with the specified message. + * Returns an {@code InvalidRequestException} with the specified message. * * @param messageTemplate the template used to build the error message * @param messageArgs the message arguments - * @return an <code>InvalidRequestException</code> with the specified message. + * @return an {@code InvalidRequestException} with the specified message. */ public static InvalidRequestException invalidRequest(String messageTemplate, Object... messageArgs) { --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org