diff --git a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java index 8d44072014c3..8c1d28b259ef 100644 --- a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java +++ b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java @@ -19,6 +19,7 @@ import java.nio.ByteBuffer; import java.time.Instant; import java.util.Arrays; +import java.util.Iterator; import java.util.List; import java.util.Objects; import java.util.Set; @@ -36,6 +37,7 @@ import org.eclipse.jetty.io.internal.QueuedPool; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.ConcurrentPool; +import org.eclipse.jetty.util.MathUtils; import org.eclipse.jetty.util.Pool; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; @@ -224,7 +226,7 @@ public RetainableByteBuffer.Mutable acquire(int size, boolean direct) return RetainableByteBuffer.wrap(BufferUtil.allocate(size, direct)); } - bucket.recordAcquire(); + bucket.recordAcquire(size); // Try to acquire a pooled entry. Pool.Entry entry = bucket.getPool().acquire(); @@ -503,6 +505,7 @@ public String toString() private class RetainedBucket { private final LongAdder _acquires = new LongAdder(); + private final LongAdder _totalAcquired = new LongAdder(); private final LongAdder _pooled = new LongAdder(); private final LongAdder _nonPooled = new LongAdder(); private final LongAdder _evicts = new LongAdder(); @@ -523,10 +526,13 @@ private RetainedBucket(int capacity, int poolSize) _capacity = capacity; } - public void recordAcquire() + public void recordAcquire(int size) { if (isStatisticsEnabled()) + { _acquires.increment(); + _totalAcquired.add(size); + } } public void recordEvict() @@ -589,6 +595,7 @@ private int evict() public void clear() { _acquires.reset(); + _totalAcquired.reset(); _pooled.reset(); _nonPooled.reset(); _evicts.reset(); @@ -602,8 +609,10 @@ public String toString() { int entries = 0; int inUse = 0; - for (Pool.Entry entry : getPool().stream().toList()) + Iterator> iterator = getPool().stream().iterator(); + while (iterator.hasNext()) { + Pool.Entry entry = iterator.next(); entries++; if (entry.isInUse()) inUse++; @@ -611,8 +620,9 @@ public String toString() long pooled = _pooled.longValue(); long acquires = _acquires.longValue(); - float hitRatio = acquires == 0 ? Float.NaN : pooled * 100F / acquires; - return String.format("%s{capacity=%d,in-use=%d/%d,pooled/acquires=%d/%d(%.3f%%),non-pooled/evicts/removes/releases=%d/%d/%d/%d}", + float hitRatio = acquires == 0L ? Float.NaN : pooled * 100F / acquires; + long avgSize = acquires == 0L ? 0L : _totalAcquired.longValue() / acquires; + return String.format("%s{capacity=%d,in-use=%d/%d,pooled/acquires=%d/%d(%.3f%%),avgsize=%d,non-pooled/evicts/removes/releases=%d/%d/%d/%d}", super.toString(), getCapacity(), inUse, @@ -620,6 +630,7 @@ public String toString() pooled, acquires, hitRatio, + avgSize, _nonPooled.longValue(), _evicts.longValue(), _removes.longValue(), @@ -719,38 +730,113 @@ protected void acquire() } } + /** + * A variant of the {@link ArrayByteBufferPool} that + * uses a predefined set of buckets of buffers. + */ + public static class WithBucketCapacities extends ArrayByteBufferPool + { + public WithBucketCapacities(int... capacities) + { + this(0L, 0L, capacities); + } + + public WithBucketCapacities(long maxHeapMemory, long maxDirectMemory, int... capacities) + { + super(-1, 1, sort(capacities)[capacities.length - 1], Integer.MAX_VALUE, maxHeapMemory, maxDirectMemory, + c -> floorBucketIndexFor(c, capacities), i -> bucketCapacityForIndex(i, capacities)); + } + + private static int[] sort(int... values) + { + if (values.length == 0) + throw new IllegalArgumentException("At least one capacity is needed"); + Arrays.sort(values); + return values; + } + + private static int bucketCapacityForIndex(int idx, int... capacities) + { + if (idx >= capacities.length) + { + // An index over the capacities array's length is considered + // to refer to a multiple of the largest configured capacity; + // this logic is only meant for recordNoBucketAcquire(). + int largestCapacity = capacities[capacities.length - 1]; + int virtualIdx = idx - (capacities.length - 1); + return (virtualIdx + 1) * largestCapacity; + } + return capacities[idx]; + } + + private static int floorBucketIndexFor(int capacity, int... capacities) + { + int largestCapacity = capacities[capacities.length - 1]; + if (capacity > largestCapacity) + { + // A capacity over the largest configured capacity returns an + // index that corresponds to where in the capacities array it + // would stand if the latter had more entries that would all + // be multiples of the largest configured capacity; + // this logic is only meant for recordNoBucketAcquire(). + int remainder = capacity % largestCapacity != 0 ? 1 : 0; + int overLargestCapacityFactor = (capacity / largestCapacity) + remainder; + return overLargestCapacityFactor - 1 + capacities.length - 1; + } + + int idx = 0; + for (int i = 0; i < capacities.length; i++) + { + idx = i; + if (capacities[i] > capacity) + break; + } + return idx; + } + } + /** * A variant of the {@link ArrayByteBufferPool} that * uses buckets of buffers that increase in size by a power of * 2 (e.g. 1k, 2k, 4k, 8k, etc.). - * @deprecated Usage of {@code Quadratic} is often wasteful of additional space and can increase contention on - * the larger buffers. */ - @Deprecated(forRemoval = true, since = "12.1.0") public static class Quadratic extends ArrayByteBufferPool { public Quadratic() { - this(0, -1, Integer.MAX_VALUE); + this(-1, -1, Integer.MAX_VALUE); } public Quadratic(int minCapacity, int maxCapacity, int maxBucketSize) { - this(minCapacity, maxCapacity, maxBucketSize, -1L, -1L); + this(minCapacity, maxCapacity, maxBucketSize, 0L, 0L); } public Quadratic(int minCapacity, int maxCapacity, int maxBucketSize, long maxHeapMemory, long maxDirectMemory) { super(minCapacity, - -1, - maxCapacity, + computeMinCapacity(minCapacity), + computeMaxCapacity(maxCapacity), maxBucketSize, maxHeapMemory, maxDirectMemory, - c -> 32 - Integer.numberOfLeadingZeros(c - 1), - i -> 1 << i + // The bucket indices are the powers of 2, but those powers up to minCapacity are skipped so they must be + // substracted when computing the index and added when computing the capacity; so if minCapacity is 1024, any + // number from 0 to 1024 must return index 0, and index 0 must return capacity 1024. + c -> Integer.SIZE - Integer.numberOfLeadingZeros(c - 1) - MathUtils.ceilLog2(computeMinCapacity(minCapacity)), + i -> 1 << i + MathUtils.ceilLog2(computeMinCapacity(minCapacity)) ); } + + private static int computeMinCapacity(int minCapacity) + { + return minCapacity <= 0 ? 1024 : minCapacity; + } + + private static int computeMaxCapacity(int maxCapacity) + { + return maxCapacity <= 0 ? 65536 : maxCapacity; + } } /** diff --git a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferAggregator.java b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferAggregator.java index 3469c367ee5c..38ded84aef9c 100644 --- a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferAggregator.java +++ b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferAggregator.java @@ -16,7 +16,7 @@ import java.nio.ByteBuffer; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.TypeUtil; +import org.eclipse.jetty.util.MathUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -106,7 +106,7 @@ private void tryExpandBufferCapacity(int remaining) if (remaining <= capacityLeft) return; int need = remaining - capacityLeft; - _currentSize = Math.min(_maxSize, TypeUtil.ceilToNextPowerOfTwo(_currentSize + need)); + _currentSize = Math.min(_maxSize, MathUtils.ceilToNextPowerOfTwo(_currentSize + need)); if (_retainableByteBuffer != null) { diff --git a/jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayByteBufferPoolTest.java b/jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayByteBufferPoolTest.java index cc228c081091..c7b78446ad2d 100644 --- a/jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayByteBufferPoolTest.java +++ b/jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayByteBufferPoolTest.java @@ -391,44 +391,126 @@ public void testAcquireRelease() } @Test - @Deprecated(forRemoval = true) - public void testQuadraticPool() + public void testQuadraticPoolBucketSizes() { - ArrayByteBufferPool pool = new ArrayByteBufferPool.Quadratic(); - - RetainableByteBuffer retain5 = pool.acquire(5, false); - retain5.release(); - RetainableByteBuffer retain6 = pool.acquire(6, false); - assertThat(retain6, not(sameInstance(retain5))); - assertThat(retain6.getByteBuffer(), sameInstance(retain5.getByteBuffer())); - retain6.release(); - RetainableByteBuffer retain9 = pool.acquire(9, false); - assertThat(retain9, not(sameInstance(retain5))); - retain9.release(); - - assertThat(pool.acquire(1, false).capacity(), is(1)); - assertThat(pool.acquire(2, false).capacity(), is(2)); - RetainableByteBuffer b3 = pool.acquire(3, false); - assertThat(b3.capacity(), is(4)); - RetainableByteBuffer b4 = pool.acquire(4, false); - assertThat(b4.capacity(), is(4)); - - int capacity = 4; - while (true) - { - RetainableByteBuffer b = pool.acquire(capacity - 1, false); - assertThat(b.capacity(), Matchers.is(capacity)); - b = pool.acquire(capacity, false); - assertThat(b.capacity(), Matchers.is(capacity)); + ArrayByteBufferPool pool1 = new ArrayByteBufferPool.Quadratic(); + String dump1 = pool1.dump(); + assertThat(dump1, containsString("direct size=7\n")); + assertThat(dump1, containsString("{capacity=1024,")); + assertThat(dump1, containsString("{capacity=2048,")); + assertThat(dump1, containsString("{capacity=4096,")); + assertThat(dump1, containsString("{capacity=8192,")); + assertThat(dump1, containsString("{capacity=16384,")); + assertThat(dump1, containsString("{capacity=32768,")); + assertThat(dump1, containsString("{capacity=65536,")); + + ArrayByteBufferPool pool2 = new ArrayByteBufferPool.Quadratic(100, 800, Integer.MAX_VALUE); + String dump2 = pool2.dump(); + assertThat(dump2, containsString("direct size=4\n")); + assertThat(dump2, containsString("{capacity=128,")); + assertThat(dump2, containsString("{capacity=256,")); + assertThat(dump2, containsString("{capacity=512,")); + assertThat(dump2, containsString("{capacity=800,")); + + ArrayByteBufferPool pool3 = new ArrayByteBufferPool.Quadratic(1, 200, Integer.MAX_VALUE); + String dump3 = pool3.dump(); + assertThat(dump3, containsString("direct size=9\n")); + assertThat(dump3, containsString("{capacity=1,")); + assertThat(dump3, containsString("{capacity=2,")); + assertThat(dump3, containsString("{capacity=4,")); + assertThat(dump3, containsString("{capacity=8,")); + assertThat(dump3, containsString("{capacity=16,")); + assertThat(dump3, containsString("{capacity=32,")); + assertThat(dump3, containsString("{capacity=64,")); + assertThat(dump3, containsString("{capacity=128,")); + assertThat(dump3, containsString("{capacity=200,")); + } - if (capacity >= pool.getMaxCapacity()) - break; + @Test + public void testWithBucketCapacitiesBucketSizes() + { + { + ArrayByteBufferPool pool = new ArrayByteBufferPool.WithBucketCapacities(1024, 65536); + String dump = pool.dump(); + assertThat(dump, containsString("direct size=2\n")); + assertThat(dump, containsString("{capacity=1024,")); + assertThat(dump, containsString("{capacity=65536,")); + } + { + ArrayByteBufferPool pool = new ArrayByteBufferPool.WithBucketCapacities(30, 24); + String dump = pool.dump(); + assertThat(dump, containsString("direct size=2\n")); + assertThat(dump, containsString("{capacity=24,")); + assertThat(dump, containsString("{capacity=30,")); + } + { + ArrayByteBufferPool pool = new ArrayByteBufferPool.WithBucketCapacities(3, 7, 100); + String dump = pool.dump(); + assertThat(dump, containsString("direct size=3\n")); + assertThat(dump, containsString("{capacity=3,")); + assertThat(dump, containsString("{capacity=7,")); + assertThat(dump, containsString("{capacity=100,")); + } + } - b = pool.acquire(capacity + 1, false); - assertThat(b.capacity(), Matchers.is(capacity * 2)); + @Test + public void testWithBucketCapacitiesNoBucketSizes() + { + { + ArrayByteBufferPool pool = new ArrayByteBufferPool.WithBucketCapacities(1, 100); + pool.setStatisticsEnabled(true); + pool.acquire(200, false).release(); + pool.acquire(300, false).release(); + pool.acquire(800, false).release(); + pool.acquire(150, false).release(); + String dump = pool.dump(); + assertThat(dump, containsString("200: 2\n")); + assertThat(dump, containsString("300: 1\n")); + assertThat(dump, containsString("800: 1\n")); + } + { + ArrayByteBufferPool pool = new ArrayByteBufferPool.WithBucketCapacities(1, 7, 50, 100); + pool.setStatisticsEnabled(true); + pool.acquire(200, false).release(); + pool.acquire(300, false).release(); + pool.acquire(800, false).release(); + pool.acquire(150, false).release(); + String dump = pool.dump(); + assertThat(dump, containsString("200: 2\n")); + assertThat(dump, containsString("300: 1\n")); + assertThat(dump, containsString("800: 1\n")); + } + { + ArrayByteBufferPool pool = new ArrayByteBufferPool.WithBucketCapacities(128, 512, 2048); + pool.setStatisticsEnabled(true); + pool.acquire(8192, false).release(); + String dump = pool.dump(); + assertThat(dump, containsString("8192: 1\n")); + } + } - capacity = capacity * 2; + @Test + public void testWithBucketCapacitiesStats() + { + ArrayByteBufferPool pool = new ArrayByteBufferPool.WithBucketCapacities(1024, 65536); + pool.setStatisticsEnabled(true); + for (int i = 0; i < 5; i++) + { + pool.acquire(1023, false).release(); } + pool.acquire(2048, false).release(); + pool.acquire(4096, false).release(); + pool.acquire(4096, false).release(); + pool.acquire(6144, false).release(); + pool.acquire(65536 + 1, false).release(); + pool.acquire(65536 + 2, false).release(); + pool.acquire(65536 * 2 + 1, false).release(); + pool.acquire(65536 * 3 - 1, false).release(); + String dump = pool.dump(); + assertThat(dump, containsString("{capacity=1024,in-use=0/1,pooled/acquires=4/5(80.000%),avgsize=1023,non-pooled/evicts/removes/releases=0/0/0/5}")); + assertThat(dump, containsString("{capacity=65536,in-use=0/1,pooled/acquires=3/4(75.000%),avgsize=4096,non-pooled/evicts/removes/releases=0/0/0/4}")); + assertThat(dump, containsString("131072: 2\n")); + assertThat(dump, containsString("196608: 2\n")); } @Test diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/MathUtils.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/MathUtils.java index 5c71b5459b49..e48f3623faa8 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/MathUtils.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/MathUtils.java @@ -77,4 +77,30 @@ public static int cappedAdd(int a, int b, int maxValue) return maxValue; } } + + /** + * Get the next highest power of two + * @param value An integer + * @return a power of two that is greater than or equal to {@code value} + */ + public static int ceilToNextPowerOfTwo(int value) + { + if (value < 0) + throw new IllegalArgumentException("value must not be negative"); + int result = 1 << (Integer.SIZE - Integer.numberOfLeadingZeros(value - 1)); + return result > 0 ? result : Integer.MAX_VALUE; + } + + /** + * Computes binary logarithm of the given number ceiled to the next power of two. + * If the given number is 800, it is ceiled to 1024 which is the closest power of 2 greater than or equal to 800, + * then 1024 is 10_000_000_000 in binary, i.e.: 1 followed by 10 zeros, and it's also 2 to the power of 10. + * So for the numbers between 513 and 1024 the returned value is 10. + * @param value An integer + * @return the binary logarithm of the given number ceiled to the next power of two. + */ + public static int ceilLog2(int value) + { + return Integer.numberOfTrailingZeros(Integer.highestOneBit(ceilToNextPowerOfTwo(value))); + } } diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java index 995f5107285a..9727b79ace53 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java @@ -832,19 +832,6 @@ private TypeUtil() // prevents instantiation } - /** - * Get the next highest power of two - * @param value An integer - * @return a power of two that is greater than or equal to {@code value} - */ - public static int ceilToNextPowerOfTwo(int value) - { - if (value < 0) - throw new IllegalArgumentException("value must not be negative"); - int result = 1 << (Integer.SIZE - Integer.numberOfLeadingZeros(value - 1)); - return result > 0 ? result : Integer.MAX_VALUE; - } - /** * Test is a method has been declared on the class of an instance * @param object The object to check diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ReservedThreadExecutor.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ReservedThreadExecutor.java index 8a0cbeddb8a7..ce24bb6d1965 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ReservedThreadExecutor.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ReservedThreadExecutor.java @@ -20,8 +20,8 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import org.eclipse.jetty.util.MathUtils; import org.eclipse.jetty.util.ProcessorUtils; -import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.VirtualThreads; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; @@ -120,7 +120,7 @@ public static int reservedThreads(Executor executor, int capacity) if (executor instanceof ThreadPool.SizedThreadPool) { int threads = ((ThreadPool.SizedThreadPool)executor).getMaxThreads(); - return Math.max(1, TypeUtil.ceilToNextPowerOfTwo(Math.min(cpus, threads / 8))); + return Math.max(1, MathUtils.ceilToNextPowerOfTwo(Math.min(cpus, threads / 8))); } return cpus; } diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ThreadIdPool.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ThreadIdPool.java index 46b0756f18a3..93b27e3c16bf 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ThreadIdPool.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ThreadIdPool.java @@ -21,9 +21,9 @@ import java.util.function.Function; import java.util.function.Supplier; +import org.eclipse.jetty.util.MathUtils; import org.eclipse.jetty.util.MemoryUtils; import org.eclipse.jetty.util.ProcessorUtils; -import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.component.Dumpable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -65,7 +65,7 @@ private static int calcCapacity(int capacity) { if (capacity >= 0) return capacity; - return 2 * TypeUtil.ceilToNextPowerOfTwo(ProcessorUtils.availableProcessors()); + return 2 * MathUtils.ceilToNextPowerOfTwo(ProcessorUtils.availableProcessors()); } private static int toSlot(int index) diff --git a/jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/MathUtilsTest.java b/jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/MathUtilsTest.java new file mode 100644 index 000000000000..9239cb9351db --- /dev/null +++ b/jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/MathUtilsTest.java @@ -0,0 +1,46 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.util; + +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class MathUtilsTest +{ + @Test + public void testCeilNextPowerOfTwo() + { + assertThrows(IllegalArgumentException.class, () -> MathUtils.ceilToNextPowerOfTwo(-1)); + assertThat(MathUtils.ceilToNextPowerOfTwo(0), is(1)); + assertThat(MathUtils.ceilToNextPowerOfTwo(1), is(1)); + assertThat(MathUtils.ceilToNextPowerOfTwo(2), is(2)); + assertThat(MathUtils.ceilToNextPowerOfTwo(3), is(4)); + assertThat(MathUtils.ceilToNextPowerOfTwo(4), is(4)); + assertThat(MathUtils.ceilToNextPowerOfTwo(5), is(8)); + assertThat(MathUtils.ceilToNextPowerOfTwo(Integer.MAX_VALUE - 1), is(Integer.MAX_VALUE)); + } + + @Test + public void testCeilLog2() + { + assertThrows(IllegalArgumentException.class, () -> MathUtils.ceilLog2(-1)); + assertThat(MathUtils.ceilLog2(0), is(0)); + assertThat(MathUtils.ceilLog2(800), is(10)); + assertThat(MathUtils.ceilLog2(1024), is(10)); + assertThat(MathUtils.ceilLog2(Integer.MAX_VALUE), is(30)); + } +} diff --git a/jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/TypeUtilTest.java b/jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/TypeUtilTest.java index c57c079c9374..8c82772fea31 100644 --- a/jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/TypeUtilTest.java +++ b/jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/TypeUtilTest.java @@ -31,7 +31,6 @@ import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assumptions.assumeTrue; @@ -255,19 +254,6 @@ public void testToShortName(Class clazz, String shortName) assertThat(TypeUtil.toShortName(clazz), is(shortName)); } - @Test - public void testCeilNextPowerOfTwo() - { - assertThrows(IllegalArgumentException.class, () -> TypeUtil.ceilToNextPowerOfTwo(-1)); - assertThat(TypeUtil.ceilToNextPowerOfTwo(0), is(1)); - assertThat(TypeUtil.ceilToNextPowerOfTwo(1), is(1)); - assertThat(TypeUtil.ceilToNextPowerOfTwo(2), is(2)); - assertThat(TypeUtil.ceilToNextPowerOfTwo(3), is(4)); - assertThat(TypeUtil.ceilToNextPowerOfTwo(4), is(4)); - assertThat(TypeUtil.ceilToNextPowerOfTwo(5), is(8)); - assertThat(TypeUtil.ceilToNextPowerOfTwo(Integer.MAX_VALUE - 1), is(Integer.MAX_VALUE)); - } - public static class Base { protected String methodA(String arg)