Skip to content

Commit

Permalink
Make use of new Java language features
Browse files Browse the repository at this point in the history
This cleans up the java code a bit.
  • Loading branch information
chrisvest committed Jun 30, 2024
1 parent 94e6fab commit 5ceb60e
Show file tree
Hide file tree
Showing 18 changed files with 83 additions and 126 deletions.
13 changes: 6 additions & 7 deletions src/main/java/stormpot/BSlot.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,13 @@ private int getClaimState() {
}

private PoolException badStateOnTransitionToLive(int slotState) {
String state;
switch (slotState) {
case DEAD: state = "DEAD"; break;
case LIVING: state = "LIVING"; break;
default: state = "STATE[" + slotState + "]";
}
String state = switch (slotState) {
case DEAD -> "DEAD";
case LIVING -> "LIVING";
default -> "STATE[" + slotState + "]";
};
return new PoolException("Slot release from bad state: " + state + ". " +
"You most likely called release() twice on the same object.");
"You most likely called release() twice on the same object.");
}

void claim2live() {
Expand Down
14 changes: 7 additions & 7 deletions src/main/java/stormpot/PoolBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ DIRECT, new PoolBuilderPermissions(false, true, false, false, false)
* @return This {@code PoolBuilder} instance.
*/
public synchronized PoolBuilder<T> setSize(int size) {
checkPermission(permissions.setSize, "size");
checkPermission(permissions.setSize(), "size");
if (size < 0) {
throw new IllegalArgumentException("Size must be at least 0, but was " + size + ".");
}
Expand Down Expand Up @@ -143,7 +143,7 @@ public synchronized int getSize() {
@SuppressWarnings("unchecked")
public synchronized <X extends Poolable> PoolBuilder<X> setAllocator(
Allocator<X> allocator) {
checkPermission(permissions.setAllocator, "allocator");
checkPermission(permissions.setAllocator(), "allocator");
requireNonNull(allocator, "The Allocator cannot be null.");
this.allocator = (Allocator<T>) allocator;
return (PoolBuilder<X>) this;
Expand Down Expand Up @@ -184,7 +184,7 @@ public synchronized Reallocator<T> getReallocator() {
* @return This {@code PoolBuilder} instance.
*/
public synchronized PoolBuilder<T> setExpiration(Expiration<? super T> expiration) {
checkPermission(permissions.setExpiration, "expiration");
checkPermission(permissions.setExpiration(), "expiration");
requireNonNull(expiration, "Expiration cannot be null.");
this.expiration = expiration;
return this;
Expand Down Expand Up @@ -241,7 +241,7 @@ public synchronized ThreadFactory getThreadFactory() {
* @return This {@code PoolBuilder} instance.
*/
public synchronized PoolBuilder<T> setThreadFactory(ThreadFactory factory) {
checkPermission(permissions.setThreadFactory, "thread factory");
checkPermission(permissions.setThreadFactory(), "thread factory");
requireNonNull(factory, "ThreadFactory cannot be null.");
threadFactory = factory;
return this;
Expand Down Expand Up @@ -314,7 +314,7 @@ public synchronized boolean isBackgroundExpirationEnabled() {
* @return This {@code PoolBuilder} instance.
*/
public synchronized PoolBuilder<T> setBackgroundExpirationEnabled(boolean enabled) {
checkPermission(permissions.setBackgroundExpiration, "background expiration enabled/disabled");
checkPermission(permissions.setBackgroundExpiration(), "background expiration enabled/disabled");
backgroundExpirationEnabled = enabled;
return this;
}
Expand Down Expand Up @@ -347,7 +347,7 @@ public synchronized int getBackgroundExpirationCheckDelay() {
* @return This {@code PoolBuilder} instance.
*/
public synchronized PoolBuilder<T> setBackgroundExpirationCheckDelay(int delay) {
checkPermission(permissions.setBackgroundExpiration, "background expiration check delay");
checkPermission(permissions.setBackgroundExpiration(), "background expiration check delay");
if (delay < 0) {
throw new IllegalArgumentException("Background expiration check delay cannot be negative.");
}
Expand All @@ -362,7 +362,7 @@ public synchronized PoolBuilder<T> setBackgroundExpirationCheckDelay(int delay)
*/
@SuppressWarnings("unchecked")
@Override
public final synchronized PoolBuilder<T> clone() {
public synchronized PoolBuilder<T> clone() {
try {
return (PoolBuilder<T>) super.clone();
} catch (CloneNotSupportedException e) {
Expand Down
25 changes: 6 additions & 19 deletions src/main/java/stormpot/PoolBuilderPermissions.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,10 @@
*/
package stormpot;

class PoolBuilderPermissions {
final boolean setAllocator;
final boolean setSize;
final boolean setExpiration;
final boolean setThreadFactory;
final boolean setBackgroundExpiration;

PoolBuilderPermissions(
boolean setAllocator,
boolean setSize,
boolean setExpiration,
boolean setThreadFactory,
boolean setBackgroundExpiration) {
this.setAllocator = setAllocator;
this.setSize = setSize;
this.setExpiration = setExpiration;
this.setThreadFactory = setThreadFactory;
this.setBackgroundExpiration = setBackgroundExpiration;
}
record PoolBuilderPermissions(
boolean setAllocator,
boolean setSize,
boolean setExpiration,
boolean setThreadFactory,
boolean setBackgroundExpiration) {
}
3 changes: 3 additions & 0 deletions src/main/java/stormpot/PoolException.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package stormpot;

import java.io.Serial;

/**
* The PoolException may be thrown by a pool implementation in a number of
* circumstances:
Expand All @@ -32,6 +34,7 @@
* @author Chris Vest
*/
public class PoolException extends RuntimeException {
@Serial
private static final long serialVersionUID = -1908093409167496640L;

/**
Expand Down
11 changes: 4 additions & 7 deletions src/main/java/stormpot/PreciseLeakDetector.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ private static class WeakRef extends WeakReference<Object> {
// 'probe' array. When inserting, if that slot is null, then we insert the
// WeakRef directly into that place. In fact, we allow building a WeakRef
// chain up to 4 elements long, directly in the first-level 'probes' array.
// Otherwise we add the second-level 32 element array, rehash the existing
// Otherwise, we add the second-level 32 element array, rehash the existing
// chain into it, by using the next 5 second-least significant bits as
// index. From here on, we don't create any more levels, but just link the
// WeakRefs together like a daisy-chain. This way, we create at most 33
Expand All @@ -62,8 +62,7 @@ synchronized void register(Object obj) {
return;
}

if (current instanceof WeakRef) {
WeakRef currentRef = (WeakRef) current;
if (current instanceof WeakRef currentRef) {
if (chainShorterThan(4, current)) {
WeakRef ref = new WeakRef(obj);
ref.next = currentRef;
Expand Down Expand Up @@ -120,8 +119,7 @@ synchronized void unregister(Object obj) {

Object current = probes[hash1];

if (current instanceof WeakRef) {
WeakRef ref = (WeakRef) current;
if (current instanceof WeakRef ref) {
probes[hash1] = removeFromChain(ref, obj);
return;
}
Expand Down Expand Up @@ -154,8 +152,7 @@ synchronized long countLeakedObjects() {
Object current = probes[i];
if (current instanceof WeakRef) {
probes[i] = pruneChain((WeakRef) current);
} else if (current instanceof WeakRef[]) {
WeakRef[] level2 = (WeakRef[]) current;
} else if (current instanceof WeakRef[] level2) {
for (int j = 0; j < level2.length; j++) {
level2[j] = pruneChain(level2[j]);
}
Expand Down
11 changes: 5 additions & 6 deletions src/main/java/stormpot/Timeout.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public TimeUnit getBaseUnit() {

@Override
public int hashCode() {
return 31 * (1 + (int) (timeoutBase ^ (timeoutBase >>> 32)));
return 31 * (1 + Long.hashCode(timeoutBase));
}

/**
Expand All @@ -153,10 +153,9 @@ public int hashCode() {
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Timeout)) {
return false;
}
Timeout that = (Timeout) obj;
return this.timeoutBase == that.timeoutBase;
if (obj instanceof Timeout that) {
return this.timeoutBase == that.timeoutBase;
}
return false;
}
}
52 changes: 16 additions & 36 deletions src/test/java/blackbox/AbstractPoolTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
Expand All @@ -55,7 +54,6 @@
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static stormpot.UnitKit.$await;
import static stormpot.UnitKit.$catchFrom;
import static stormpot.UnitKit.$claim;
Expand Down Expand Up @@ -123,11 +121,8 @@ void tryClaimMustReturnIfPoolIsNotEmpty(Taps taps) throws Exception {
T a = tap.claim(longTimeout); // Wait for the pool to be populated
a.release();
T obj = tap.tryClaim();
try {
assertThat(obj).isNotNull();
} finally {
obj.release();
}
assertThat(obj).isNotNull();
obj.release();
}

/**
Expand Down Expand Up @@ -158,11 +153,8 @@ void tryClaimMustReturnNullIfPoolIsEmpty(Taps taps) throws Exception {
void claimMustReturnIfWithinTimeout(Taps taps) throws Exception {
createOneObjectPool();
T obj = taps.get(this).claim(longTimeout);
try {
assertThat(obj).isNotNull();
} finally {
obj.release();
}
assertThat(obj).isNotNull();
obj.release();
}

/**
Expand Down Expand Up @@ -1081,18 +1073,6 @@ void supplyMustReleaseClaimedObject(Taps taps) throws Exception {
tap.supply(longTimeout, nullConsumer);
}

private static Object expectException(Callable<?> callable) {
try {
callable.call();
fail("The ExpectedException was not thrown");
} catch (ExpectedException ignore) {
// We expect this
} catch (Exception e) {
throw new AssertionError("Failed for other reason", e);
}
return null;
}

@ParameterizedTest
@EnumSource(Taps.class)
void applyMustReleaseClaimedObjectEvenIfFunctionThrows(Taps taps) throws Exception {
Expand All @@ -1102,12 +1082,12 @@ void applyMustReleaseClaimedObjectEvenIfFunctionThrows(Taps taps) throws Excepti
throw new ExpectedException();
};

expectException(() -> tap.apply(longTimeout, thrower));
expectException(() -> tap.apply(longTimeout, thrower));
fork(() -> expectException(() -> tap.apply(longTimeout, thrower))).join();
fork(() -> expectException(() -> tap.apply(longTimeout, thrower))).join();
expectException(() -> tap.apply(longTimeout, thrower));
expectException(() -> tap.apply(longTimeout, thrower));
assertThrows(ExpectedException.class, () -> tap.apply(longTimeout, thrower));
assertThrows(ExpectedException.class, () -> tap.apply(longTimeout, thrower));
fork(() -> assertThrows(ExpectedException.class, () -> tap.apply(longTimeout, thrower))).join();
fork(() -> assertThrows(ExpectedException.class, () -> tap.apply(longTimeout, thrower))).join();
assertThrows(ExpectedException.class, () -> tap.apply(longTimeout, thrower));
assertThrows(ExpectedException.class, () -> tap.apply(longTimeout, thrower));
}

@ParameterizedTest
Expand All @@ -1119,12 +1099,12 @@ void supplyMustReleaseClaimedObjectEvenIfConsumerThrows(Taps taps) throws Except
throw new ExpectedException();
};

expectException(() -> tap.supply(longTimeout, thrower));
expectException(() -> tap.supply(longTimeout, thrower));
fork(() -> expectException(() -> tap.supply(longTimeout, thrower))).join();
fork(() -> expectException(() -> tap.supply(longTimeout, thrower))).join();
expectException(() -> tap.supply(longTimeout, thrower));
expectException(() -> tap.supply(longTimeout, thrower));
assertThrows(ExpectedException.class, () -> tap.supply(longTimeout, thrower));
assertThrows(ExpectedException.class, () -> tap.supply(longTimeout, thrower));
fork(() -> assertThrows(ExpectedException.class, () -> tap.supply(longTimeout, thrower))).join();
fork(() -> assertThrows(ExpectedException.class, () -> tap.supply(longTimeout, thrower))).join();
assertThrows(ExpectedException.class, () -> tap.supply(longTimeout, thrower));
assertThrows(ExpectedException.class, () -> tap.supply(longTimeout, thrower));
}

@ParameterizedTest
Expand Down
12 changes: 6 additions & 6 deletions src/test/java/blackbox/AllocatorBasedPoolTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -737,7 +737,7 @@ void mustPropagateExceptionsFromAllocateThroughClaim(Taps taps) throws Exception
tap.claim(longTimeout);
fail("expected claim to throw");
} catch (PoolException poolException) {
assertThat(poolException.getCause()).isSameAs((Throwable) expectedException);
assertThat(poolException.getCause()).isSameAs(expectedException);
}
}

Expand Down Expand Up @@ -774,7 +774,7 @@ void mustPropagateExceptionsFromReallocateThroughClaim(Taps taps) throws Excepti
tap.claim(longTimeout);
fail("expected claim to throw");
} catch (PoolException poolException) {
assertThat(poolException.getCause()).isSameAs((Throwable) expectedException);
assertThat(poolException.getCause()).isSameAs(expectedException);
}
}

Expand Down Expand Up @@ -1215,7 +1215,7 @@ void decreasingSizeMustEventuallyDeallocateSurplusObjects(Taps taps) throws Exce
pool.setTargetSize(newSize);
while (allocator.countDeallocations() != startingSize - newSize) {
if (!objs.isEmpty()) {
objs.remove(0).release(); // give the pool objects to deallocate
objs.removeFirst().release(); // give the pool objects to deallocate
} else {
tap.claim(longTimeout).release(); // prod it & poke it
}
Expand Down Expand Up @@ -1274,15 +1274,15 @@ void mustNotReallocateWhenReleasingExpiredObjectsIntoShrunkPool()
pool.setTargetSize(newSize);
for (int i = 0; i < startingSize - newSize; i++) {
// release the surplus expired objects back into the pool
objs.remove(0).release();
objs.removeFirst().release();
}
// now the released objects should not cause reallocations, so claim
// returns null (it's still depleted) and allocation count stays put
try {
assertThat(pool.claim(shortTimeout)).isNull();
assertThat(allocator.countAllocations()).isEqualTo(startingSize);
} finally {
objs.remove(0).release();
objs.removeFirst().release();
}
}

Expand Down Expand Up @@ -1860,7 +1860,7 @@ void newlyAllocatedObjectsMustBeClaimedAheadOfExistingLiveObjects(Taps taps) thr
GenericPoolable a = tap.claim(longTimeout);
try {
List<GenericPoolable> allocations = allocator.getAllocations();
assertThat(a).isSameAs(allocations.get(allocations.size() - 1));
assertThat(a).isSameAs(allocations.getLast());
} finally {
a.release();
}
Expand Down
Loading

0 comments on commit 5ceb60e

Please sign in to comment.