Skip to content

Commit

Permalink
Test: cache with concurrent HashMaps
Browse files Browse the repository at this point in the history
  • Loading branch information
heshanpadmasiri committed Feb 16, 2025
1 parent 58275cd commit 2d5d882
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<TypeIdentifier, BRecordType> cache = CacheFactory.createCache();
private static final Map<TypeIdentifier, BRecordType> cache = CacheFactory.createCachingHashMap();

BRecordType get(TypeIdentifier key) {
return cache.getIfPresent(key);
return cache.get(key);
}

void put(TypeIdentifier identifier, BRecordType value) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
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.
*
* @since 2201.11.0
*/
public class TypeCheckCacheFactory {

private static final LoadingCache<TypeIdentifier, TypeCheckCache> cache =
CacheFactory.createCache(TypeCheckCacheFactory::create);
private static final Map<TypeIdentifier, TypeCheckCache> 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) {
Expand All @@ -31,6 +32,6 @@ public static TypeCheckCache create() {
}

public static void reset() {
cache.invalidateAll();
cache.clear();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
*/
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;
import io.ballerina.runtime.api.types.Type;
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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -356,29 +356,32 @@ private SemType shapeOfInner(Context cx, ShapeSupplier shapeSupplier, AbstractAr
private static class TypeCheckCacheData {

private static final Map<Integer, SemType> cachedSemTypes = new ConcurrentHashMap<>();
private static final LoadingCache<Type, TypeCheckCacheRecord> cacheRW = CacheFactory.createIdentityCache(
ignored -> new TypeCheckCacheRecord(TypeIdSupplier.getAnonId(), TypeCheckCacheFactory.create()));
private static final LoadingCache<Type, TypeCheckCacheRecord> cacheRO = CacheFactory.createIdentityCache(
ignored -> new TypeCheckCacheRecord(TypeIdSupplier.getAnonId(), TypeCheckCacheFactory.create()));
private static final Map<Integer, TypeCheckCacheFlyweight> cacheRW = CacheFactory.createCachingHashMap();
private static final Map<Integer, TypeCheckCacheFlyweight> 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();
}
}
}
Original file line number Diff line number Diff line change
@@ -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<TypeIdentifier, Integer> cache =
CacheFactory.createCache(TypeIdSupplier::getNamedId);
private static final Map<TypeIdentifier, Integer> cache = CacheFactory.createCachingHashMap();
private static final AtomicInteger nextNamedId = new AtomicInteger(0);
private static final AtomicInteger nextAnonId = new AtomicInteger(-2);

Expand All @@ -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) {
Expand Down

0 comments on commit 2d5d882

Please sign in to comment.