Skip to content

Commit

Permalink
Use the jcu.findConstructor code for generator caching
Browse files Browse the repository at this point in the history
Use the new code from #2441 to improve Sql generator method lookup and on demand
attachment.
  • Loading branch information
hgschmie committed Jul 16, 2023
1 parent 0be21f8 commit 5869745
Showing 1 changed file with 22 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@
*/
package org.jdbi.v3.sqlobject;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.EnumSet;
import java.util.Optional;
import java.util.Set;
Expand All @@ -27,6 +24,8 @@
import org.jdbi.v3.core.extension.ExtensionMetadata;
import org.jdbi.v3.core.extension.Extensions;
import org.jdbi.v3.core.extension.HandleSupplier;
import org.jdbi.v3.core.internal.JdbiClassUtils;
import org.jdbi.v3.core.internal.JdbiClassUtils.MethodHandleHolder;
import org.jdbi.v3.core.internal.OnDemandExtensions;
import org.jdbi.v3.core.internal.exceptions.Sneaky;

Expand All @@ -39,8 +38,11 @@
*/
final class GeneratorSqlObjectFactory extends AbstractSqlObjectFactory implements OnDemandExtensions.Factory {

private final ConcurrentMap<Class<?>, MethodHandle> newAttached = new ConcurrentHashMap<>();
private final ConcurrentMap<Class<?>, MethodHandle> newOnDemand = new ConcurrentHashMap<>();
private static final Class<?>[] EXTENSION_TYPES = {ExtensionMetadata.class, HandleSupplier.class, ConfigRegistry.class};
private static final Class<?>[] ON_DEMAND_TYPES = {Jdbi.class};

private final ConcurrentMap<Class<?>, MethodHandleHolder<?>> attachedTypeCache = new ConcurrentHashMap<>();
private final ConcurrentMap<Class<?>, MethodHandleHolder<?>> onDemandTypeCache = new ConcurrentHashMap<>();

GeneratorSqlObjectFactory() {}

Expand All @@ -61,6 +63,7 @@ public Set<FactoryFlag> getFactoryFlags() {
* @param handleSupplier the Handle instance to attach this sql object to.
* @return the new sql object bound to this handle.
*/
@SuppressWarnings("unchecked")
@Override
public <E> E attach(Class<E> extensionType, HandleSupplier handleSupplier) {
if (!isConcrete(extensionType)) {
Expand All @@ -72,23 +75,8 @@ public <E> E attach(Class<E> extensionType, HandleSupplier handleSupplier) {
final ExtensionMetadata extensionMetaData = config.get(Extensions.class).findMetadata(extensionType, this);
final ConfigRegistry instanceConfig = extensionMetaData.createInstanceConfiguration(config);

try {
return (E) newAttached.computeIfAbsent(extensionType, GeneratorSqlObjectFactory::createAttacher)
.invokeExact(extensionMetaData, handleSupplier, instanceConfig);
} catch (Throwable e) {
throw Sneaky.throwAnyway(e);
}
}

private static MethodHandle createAttacher(Class<?> extensionType) {
try {
var ctor = MethodHandles.lookup().findConstructor(
Class.forName(getGeneratedClassName(extensionType)),
MethodType.methodType(void.class, ExtensionMetadata.class, HandleSupplier.class, ConfigRegistry.class));
return ctor.asType(ctor.type().changeReturnType(Object.class));
} catch (ReflectiveOperationException e) {
throw new UnableToCreateSqlObjectException(e);
}
return (E) attachedTypeCache.computeIfAbsent(extensionType, GeneratorSqlObjectFactory::getGeneratedClass)
.invoke(handle -> handle.invokeExact(extensionMetaData, handleSupplier, instanceConfig));
}

@Override
Expand All @@ -97,23 +85,23 @@ public Optional<Object> onDemand(Jdbi jdbi, Class<?> extensionType, Class<?>...
return Optional.empty();
}

return Optional.of(onDemandTypeCache.computeIfAbsent(extensionType, GeneratorSqlObjectFactory::getOnDemandClass)
.invoke(handle -> handle.invokeExact(jdbi)));
}

private static MethodHandleHolder<?> getGeneratedClass(Class<?> extensionType) {
try {
return Optional.of(
newOnDemand.computeIfAbsent(extensionType, GeneratorSqlObjectFactory::createOnDemand)
.invokeExact(jdbi));
} catch (Throwable e) {
throw Sneaky.throwAnyway(e);
return JdbiClassUtils.findConstructor(Class.forName(getGeneratedClassName(extensionType)), EXTENSION_TYPES);
} catch (Throwable t) {
throw Sneaky.throwAnyway(t);
}
}

private static MethodHandle createOnDemand(Class<?> extensionType) {
private static MethodHandleHolder<?> getOnDemandClass(Class<?> extensionType) {
try {
var ctor = MethodHandles.lookup().findConstructor(
Class.forName(getOnDemandClassName(extensionType)),
MethodType.methodType(void.class, Jdbi.class));
return ctor.asType(ctor.type().changeReturnType(Object.class));
} catch (ReflectiveOperationException e) {
throw new UnableToCreateSqlObjectException(e);
return JdbiClassUtils.findConstructor(Class.forName(getOnDemandClassName(extensionType)), ON_DEMAND_TYPES);
} catch (Throwable t) {
throw Sneaky.throwAnyway(t);
}
}

Expand Down

0 comments on commit 5869745

Please sign in to comment.