From 2d5d882da9cfe174a962bfc5155284bf4c155826 Mon Sep 17 00:00:00 2001 From: Heshan Padamsiri Date: Sun, 16 Feb 2025 12:19:07 +0530 Subject: [PATCH] Test: cache with concurrent HashMaps --- .../runtime/api/creators/TypeCreator.java | 7 ++-- .../types/semtype/TypeCheckCacheFactory.java | 11 +++--- .../runtime/internal/types/BArrayType.java | 37 ++++++++++--------- .../internal/types/TypeIdSupplier.java | 7 ++-- 4 files changed, 32 insertions(+), 30 deletions(-) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/creators/TypeCreator.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/creators/TypeCreator.java index 62f6dce38c00..54d736c3f642 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/creators/TypeCreator.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/creators/TypeCreator.java @@ -17,7 +17,6 @@ */ package io.ballerina.runtime.api.creators; -import com.github.benmanes.caffeine.cache.Cache; import io.ballerina.runtime.api.Module; import io.ballerina.runtime.api.types.ArrayType; import io.ballerina.runtime.api.types.ErrorType; @@ -561,15 +560,15 @@ public static void registerRecordType(BRecordType recordType) { } public static void resetAllCaches() { - RecordTypeCache.cache.invalidateAll(); + RecordTypeCache.cache.clear(); } private static final class RecordTypeCache { - private static final Cache cache = CacheFactory.createCache(); + private static final Map cache = CacheFactory.createCachingHashMap(); BRecordType get(TypeIdentifier key) { - return cache.getIfPresent(key); + return cache.get(key); } void put(TypeIdentifier identifier, BRecordType value) { diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/TypeCheckCacheFactory.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/TypeCheckCacheFactory.java index a7933e41ca57..843fdfeac257 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/TypeCheckCacheFactory.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/TypeCheckCacheFactory.java @@ -1,10 +1,11 @@ package io.ballerina.runtime.api.types.semtype; -import com.github.benmanes.caffeine.cache.LoadingCache; import io.ballerina.runtime.api.types.TypeIdentifier; import io.ballerina.runtime.internal.types.semtype.CacheFactory; import io.ballerina.runtime.internal.types.semtype.TypeCheckCacheImpl; +import java.util.Map; + /** * Factory for creating {@link TypeCheckCache} instances. * @@ -12,14 +13,14 @@ */ public class TypeCheckCacheFactory { - private static final LoadingCache cache = - CacheFactory.createCache(TypeCheckCacheFactory::create); + private static final Map cache = + CacheFactory.createCachingHashMap(); private TypeCheckCacheFactory() { } public static TypeCheckCache get(TypeIdentifier identifier) { - return cache.get(identifier); + return cache.computeIfAbsent(identifier, TypeCheckCacheFactory::create); } private static TypeCheckCache create(TypeIdentifier identifier) { @@ -31,6 +32,6 @@ public static TypeCheckCache create() { } public static void reset() { - cache.invalidateAll(); + cache.clear(); } } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BArrayType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BArrayType.java index 455dd8f77a04..6a06d42a9cd5 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BArrayType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BArrayType.java @@ -17,7 +17,6 @@ */ package io.ballerina.runtime.internal.types; -import com.github.benmanes.caffeine.cache.LoadingCache; import io.ballerina.runtime.api.flags.TypeFlags; import io.ballerina.runtime.api.types.ArrayType; import io.ballerina.runtime.api.types.IntersectionType; @@ -25,6 +24,7 @@ import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.semtype.BasicTypeBitSet; import io.ballerina.runtime.api.types.semtype.Builder; +import io.ballerina.runtime.api.types.semtype.CacheableTypeDescriptor; import io.ballerina.runtime.api.types.semtype.Context; import io.ballerina.runtime.api.types.semtype.Env; import io.ballerina.runtime.api.types.semtype.SemType; @@ -119,7 +119,7 @@ public void setElementType(Type elementType, int dimensions, boolean elementRO) this.elementType = readonly && !elementRO ? ReadOnlyUtils.getReadOnlyType(elementType) : elementType; this.dimensions = dimensions; if (size == -1) { - TypeCheckCacheData.TypeCheckCacheRecord data; + TypeCheckCacheData.TypeCheckCacheFlyweight data; if (isReadOnly()) { data = TypeCheckCacheData.getRO(elementType); } else { @@ -356,29 +356,32 @@ private SemType shapeOfInner(Context cx, ShapeSupplier shapeSupplier, AbstractAr private static class TypeCheckCacheData { private static final Map cachedSemTypes = new ConcurrentHashMap<>(); - private static final LoadingCache cacheRW = CacheFactory.createIdentityCache( - ignored -> new TypeCheckCacheRecord(TypeIdSupplier.getAnonId(), TypeCheckCacheFactory.create())); - private static final LoadingCache cacheRO = CacheFactory.createIdentityCache( - ignored -> new TypeCheckCacheRecord(TypeIdSupplier.getAnonId(), TypeCheckCacheFactory.create())); + private static final Map cacheRW = CacheFactory.createCachingHashMap(); + private static final Map cacheRO = CacheFactory.createCachingHashMap(); - private record TypeCheckCacheRecord(int typeId, TypeCheckCache typeCheckCache) { + private record TypeCheckCacheFlyweight(int typeId, TypeCheckCache typeCheckCache) { + public static TypeCheckCacheFlyweight create(Integer typeId) { + return new TypeCheckCacheFlyweight(TypeIdSupplier.getAnonId(), TypeCheckCacheFactory.create()); + } + + public static TypeCheckCacheFlyweight create() { + return new TypeCheckCacheFlyweight(TypeIdSupplier.getAnonId(), TypeCheckCacheFactory.create()); + } } - public static TypeCheckCacheData.TypeCheckCacheRecord getRW(Type constraint) { - if (constraint instanceof BTypeReferenceType referenceType) { - assert referenceType.getReferredType() != null; - return getRW(referenceType.getReferredType()); + public static TypeCheckCacheFlyweight getRW(Type constraint) { + if (constraint instanceof CacheableTypeDescriptor cacheableTypeDescriptor) { + return cacheRW.computeIfAbsent(cacheableTypeDescriptor.typeId(), TypeCheckCacheFlyweight::create); } - return cacheRW.get(constraint); + return TypeCheckCacheFlyweight.create(); } - public static TypeCheckCacheData.TypeCheckCacheRecord getRO(Type constraint) { - if (constraint instanceof BTypeReferenceType referenceType) { - assert referenceType.getReferredType() != null; - return getRO(referenceType.getReferredType()); + public static TypeCheckCacheFlyweight getRO(Type constraint) { + if (constraint instanceof CacheableTypeDescriptor cacheableTypeDescriptor) { + return cacheRO.computeIfAbsent(cacheableTypeDescriptor.typeId(), TypeCheckCacheFlyweight::create); } - return cacheRO.get(constraint); + return TypeCheckCacheFlyweight.create(); } } } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/TypeIdSupplier.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/TypeIdSupplier.java index 4fb1671acaa8..3d6c07341430 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/TypeIdSupplier.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/TypeIdSupplier.java @@ -1,15 +1,14 @@ package io.ballerina.runtime.internal.types; -import com.github.benmanes.caffeine.cache.LoadingCache; import io.ballerina.runtime.api.types.TypeIdentifier; import io.ballerina.runtime.internal.types.semtype.CacheFactory; +import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; public final class TypeIdSupplier { - private static final LoadingCache cache = - CacheFactory.createCache(TypeIdSupplier::getNamedId); + private static final Map cache = CacheFactory.createCachingHashMap(); private static final AtomicInteger nextNamedId = new AtomicInteger(0); private static final AtomicInteger nextAnonId = new AtomicInteger(-2); @@ -18,7 +17,7 @@ private TypeIdSupplier() { } public static int namedId(TypeIdentifier id) { - return cache.get(id); + return cache.computeIfAbsent(id, TypeIdSupplier::getNamedId); } public static int getNamedId(TypeIdentifier id) {