You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by mr...@apache.org on 2026/09/24 06:33:13 UTC

(jackrabbit-oak) branch trunk updated: OAK-12402: Add allocation-free primitive checkArgument overloads to Validate (#3132)

This is an automated email from the ASF dual-hosted git repository.

mreutegg pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 09b92f74e4 OAK-12402: Add allocation-free primitive checkArgument overloads to Validate (#3132)
09b92f74e4 is described below

commit 09b92f74e489d37c61414766bd50e1716f517d16
Author: Lucas Weitzendorf <lw...@gmail.com>
AuthorDate: Thu Sep 24 08:33:08 2026 +0200

    OAK-12402: Add allocation-free primitive checkArgument overloads to Validate (#3132)
    
    Validate.checkArgument(boolean, String, Object...) boxes its argument and
    allocates a varargs Object[] on every call, even when the check passes.
    ListRecord's constructor validates its size with this varargs overload on the
    hot record-navigation path (every multi-value / multi-segment / large-string
    read), boxing an int and allocating an Object[] per construction. Profiling a
    segment-store traversal (JFR settings=profile) showed Integer.valueOf at ~3.3%
    of on-CPU samples, all from ListRecord.<init>.
    
    Add primitive long and double checkArgument overloads (one per numeric family).
    Every integral primitive (byte/short/char/int/long) binds to the long overload
    via primitive widening, and float/double bind to the double overload, all with
    no boxing - so callers like ListRecord.<init> bind automatically with no source
    change and no per-call allocation. Each overload keeps the allocation-free path
    inline and delegates the failure / template-diagnostic path to the varargs
    overload, preserving its contract (messageTemplate null-check, checkTemplate
    diagnostic).
    
    Package version bumped 1.0.0 -> 1.1.0 for the backward-compatible additions.
    
    Co-authored-by: Lucas Weitzendorf <lw...@adobe.com>
---
 .../oak/commons/conditions/Validate.java           | 40 ++++++++++++++++++++++
 .../oak/commons/conditions/package-info.java       |  2 +-
 .../oak/commons/conditions/ValidateTest.java       | 40 ++++++++++++++++++++++
 3 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/conditions/Validate.java b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/conditions/Validate.java
index f51163b944..2921b0aa44 100644
--- a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/conditions/Validate.java
+++ b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/conditions/Validate.java
@@ -100,6 +100,46 @@ public final class Validate {
         }
     }
 
+    /**
+     * Checks the specified expression. Overload for integral primitives to avoid autoboxing.
+     *
+     * @param expression
+     *            to check
+     * @param messageTemplate
+     *            to use in exception (using {@link String#format} syntax)
+     * @param arg
+     *            the single message argument
+     * @throws IllegalArgumentException
+     *             when false
+     */
+    public static void checkArgument(boolean expression, @NotNull String messageTemplate, long arg) {
+        if (expression && !CHECKMESSAGETEMPLATE) {
+            Objects.requireNonNull(messageTemplate);
+        } else {
+            checkArgument(expression, messageTemplate, (Object) arg);
+        }
+    }
+
+    /**
+     * Checks the specified expression. Overload for floating-point primitives to avoid autoboxing.
+     *
+     * @param expression
+     *            to check
+     * @param messageTemplate
+     *            to use in exception (using {@link String#format} syntax)
+     * @param arg
+     *            the single message argument
+     * @throws IllegalArgumentException
+     *             when false
+     */
+    public static void checkArgument(boolean expression, @NotNull String messageTemplate, double arg) {
+        if (expression && !CHECKMESSAGETEMPLATE) {
+            Objects.requireNonNull(messageTemplate);
+        } else {
+            checkArgument(expression, messageTemplate, (Object) arg);
+        }
+    }
+
     /**
      * Checks whether the specified expression is true
      *
diff --git a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/conditions/package-info.java b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/conditions/package-info.java
index f13977ce42..fa945e3be3 100644
--- a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/conditions/package-info.java
+++ b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/conditions/package-info.java
@@ -21,7 +21,7 @@
  * Utilities for argument checking.
  */
 @Internal(since = "1.0.0")
-@Version("1.0.0")
+@Version("1.1.0")
 package org.apache.jackrabbit.oak.commons.conditions;
 import org.apache.jackrabbit.oak.commons.annotations.Internal;
 import org.osgi.annotation.versioning.Version;
diff --git a/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/conditions/ValidateTest.java b/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/conditions/ValidateTest.java
index 4dc7ae92a1..c69b649889 100644
--- a/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/conditions/ValidateTest.java
+++ b/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/conditions/ValidateTest.java
@@ -75,6 +75,46 @@ public class ValidateTest {
         }
     }
 
+    @Test
+    public void checkArgumentTrueWithLongArg() {
+        Validate.checkArgument(true, "value: %s", 42L);
+    }
+
+    @Test
+    public void checkArgumentFalseWithLongArg() {
+        try {
+            Validate.checkArgument(false, "value: %s", 9_000_000_000L);
+            fail("exception expected");
+        } catch (IllegalArgumentException ex) {
+            assertEquals("value: 9000000000", ex.getMessage());
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void checkArgumentTrueWithLongArgNullTemplate() {
+        Validate.checkArgument(true, null, 42L);
+    }
+
+    @Test
+    public void checkArgumentTrueWithDoubleArg() {
+        Validate.checkArgument(true, "value: %s", 3.5d);
+    }
+
+    @Test
+    public void checkArgumentFalseWithDoubleArg() {
+        try {
+            Validate.checkArgument(false, "value: %s", 3.5d);
+            fail("exception expected");
+        } catch (IllegalArgumentException ex) {
+            assertEquals("value: 3.5", ex.getMessage());
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void checkArgumentTrueWithDoubleArgNullTemplate() {
+        Validate.checkArgument(true, null, 3.5d);
+    }
+
     @Test
     public void checkArgumentFalseWithMessageTemplateTooFew() {
         try {