Skip to content

Commit

Permalink
feat: add infinispan jdk17 module (#245)
Browse files Browse the repository at this point in the history
  • Loading branch information
iProdigy authored Apr 7, 2024
1 parent 4a56844 commit ed1eb30
Show file tree
Hide file tree
Showing 8 changed files with 261 additions and 11 deletions.
23 changes: 12 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,18 @@ example), so it is safer to code against this API for long-term flexibility*

The following backing cache implementations have bindings already provided by this library:

| Backend | Provider | Artifact |
| :-----: | :------: | :------: |
| [Caffeine](https://github.com/ben-manes/caffeine/wiki) | `CaffeineProvider` | `cache-provider-caffeine` |
| [Caffeine3](https://github.com/ben-manes/caffeine/wiki) | `Caffeine3Provider` | `cache-provider-caffeine3` |
| [Guava](https://github.com/google/guava/wiki/CachesExplained) | `GuavaProvider` | `cache-provider-guava` |
| [Cache2k](https://cache2k.org) | `Cache2kProvider` | `cache-provider-cache2k` |
| [AndroidX](https://developer.android.com/reference/androidx/collection/LruCache) | `AndroidLruProvider` | `cache-provider-androidx` |
| [ExpiringMap](https://github.com/jhalterman/expiringmap#expiringmap) | `ExpiringMapProvider` | `cache-provider-expiringmap` |
| [Ehcache v3 (heap)](https://www.ehcache.org/documentation/3.0/index.html) | `EhcacheProvider` | `cache-provider-ehcache` |
| [Infinispan (heap)](https://infinispan.org/documentation/) | `InfinispanProvider` | `cache-provider-infinispan` |
| [Infinispan v14 (heap)](https://infinispan.org/documentation/) | `InfinispanProvider` | `cache-provider-infinispan-java11` |
| Backend | Provider | Artifact |
|:--------------------------------------------------------------------------------:|:---------------------:|:----------------------------------:|
| [Caffeine](https://github.com/ben-manes/caffeine/wiki) | `CaffeineProvider` | `cache-provider-caffeine` |
| [Caffeine3](https://github.com/ben-manes/caffeine/wiki) | `Caffeine3Provider` | `cache-provider-caffeine3` |
| [Guava](https://github.com/google/guava/wiki/CachesExplained) | `GuavaProvider` | `cache-provider-guava` |
| [Cache2k](https://cache2k.org) | `Cache2kProvider` | `cache-provider-cache2k` |
| [AndroidX](https://developer.android.com/reference/androidx/collection/LruCache) | `AndroidLruProvider` | `cache-provider-androidx` |
| [ExpiringMap](https://github.com/jhalterman/expiringmap#expiringmap) | `ExpiringMapProvider` | `cache-provider-expiringmap` |
| [Ehcache v3 (heap)](https://www.ehcache.org/documentation/3.0/index.html) | `EhcacheProvider` | `cache-provider-ehcache` |
| [Infinispan (heap)](https://infinispan.org/documentation/) | `InfinispanProvider` | `cache-provider-infinispan` |
| [Infinispan v14 (heap)](https://infinispan.org/documentation/) | `InfinispanProvider` | `cache-provider-infinispan-java11` |
| [Infinispan v15 (heap)](https://infinispan.org/documentation/) | `InfinispanProvider` | `cache-provider-infinispan-java17` |

Don't see your preferred implementation listed above?
Fear not, it is not difficult to create your own binding, and we'd be happy to accept it in a PR!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ private static void populateProviders(CacheApiSettings cacheApiSettings) {
loadImpl.accept("io.github.xanthic.cache.provider.caffeine3.Caffeine3Provider");
loadImpl.accept("io.github.xanthic.cache.provider.caffeine.CaffeineProvider");
loadImpl.accept("io.github.xanthic.cache.provider.cache2k.Cache2kProvider");
loadImpl.accept("io.github.xanthic.cache.provider.infinispanjdk17.InfinispanProvider");
loadImpl.accept("io.github.xanthic.cache.provider.infinispanjdk11.InfinispanProvider");
loadImpl.accept("io.github.xanthic.cache.provider.infinispan.InfinispanProvider");
loadImpl.accept("io.github.xanthic.cache.provider.expiringmap.ExpiringMapProvider");
Expand Down
22 changes: 22 additions & 0 deletions provider-infinispan-java17/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
dependencies {
api(project(":cache-core"))

implementation(platform("org.infinispan:infinispan-bom:15.0.0.Final"))

compileOnly("org.infinispan:infinispan-component-annotations")
implementation("org.infinispan:infinispan-core")

testImplementation(testFixtures(project(":cache-core")))
}

java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

publishing.publications.withType<MavenPublication> {
pom {
name.set("Xanthic - Infinispan Provider Module for JDK 17")
description.set("Xanthic Provider dependency for Infinispan on JDK 17+")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package io.github.xanthic.cache.provider.infinispanjdk17;

import io.github.xanthic.cache.api.Cache;
import lombok.Value;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;

@Value
class InfinispanDelegate<K, V> implements Cache<K, V> {
org.infinispan.Cache<K, V> cache;

@Override
public V get(@NotNull K key) {
return cache.get(key);
}

@Override
public V put(@NotNull K key, @NotNull V value) {
return cache.put(key, value);
}

@Override
public V remove(@NotNull K key) {
return cache.remove(key);
}

@Override
public void clear() {
cache.clear();
}

@Override
public long size() {
return cache.size();
}

@Nullable
@Override
public V compute(@NotNull K key, @NotNull BiFunction<? super K, ? super V, ? extends V> computeFunc) {
return cache.compute(key, computeFunc);
}

@Override
public V computeIfAbsent(@NotNull K key, @NotNull Function<K, V> computeFunc) {
return cache.computeIfAbsent(key, computeFunc);
}

@Override
public V computeIfPresent(@NotNull K key, @NotNull BiFunction<? super K, ? super V, ? extends V> computeFunc) {
return cache.computeIfPresent(key, computeFunc);
}

@Override
public V putIfAbsent(@NotNull K key, @NotNull V value) {
return cache.putIfAbsent(key, value);
}

@Override
public V merge(@NotNull K key, @NotNull V value, @NotNull BiFunction<V, V, V> mergeFunc) {
return cache.merge(key, value, mergeFunc);
}

@Override
public boolean replace(@NotNull K key, @NotNull V value) {
return cache.replace(key, value) != null;
}

@Override
public boolean replace(@NotNull K key, @NotNull V oldValue, @NotNull V newValue) {
return cache.replace(key, oldValue, newValue);
}

@Override
public void putAll(@NotNull Map<? extends K, ? extends V> map) {
cache.putAll(map);
}

@Override
public void forEach(@NotNull BiConsumer<? super K, ? super V> action) {
cache.forEach(action);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package io.github.xanthic.cache.provider.infinispanjdk17;

import io.github.xanthic.cache.api.RemovalListener;
import io.github.xanthic.cache.api.domain.RemovalCause;
import lombok.Value;
import org.infinispan.notifications.Listener;
import org.infinispan.notifications.cachelistener.annotation.CacheEntriesEvicted;
import org.infinispan.notifications.cachelistener.annotation.CacheEntryExpired;
import org.infinispan.notifications.cachelistener.annotation.CacheEntryInvalidated;
import org.infinispan.notifications.cachelistener.annotation.CacheEntryModified;
import org.infinispan.notifications.cachelistener.annotation.CacheEntryRemoved;
import org.infinispan.notifications.cachelistener.event.CacheEntriesEvictedEvent;
import org.infinispan.notifications.cachelistener.event.CacheEntryExpiredEvent;
import org.infinispan.notifications.cachelistener.event.CacheEntryInvalidatedEvent;
import org.infinispan.notifications.cachelistener.event.CacheEntryModifiedEvent;
import org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
import org.infinispan.notifications.cachelistener.event.Event;

import java.lang.annotation.Annotation;
import java.util.Collections;
import java.util.EnumSet;
import java.util.IdentityHashMap;
import java.util.Set;

@Value
@Listener
class InfinispanListener<K, V> {
static final Set<Event.Type> EVENTS;
static final Set<Class<? extends Annotation>> ANNOTATIONS;

RemovalListener<K, V> removalListener;

@CacheEntriesEvicted
public void onPostEvictions(CacheEntriesEvictedEvent<K, V> event) {
if (!event.isPre())
event.getEntries().forEach((k, v) -> removalListener.onRemoval(k, v, RemovalCause.SIZE));
}

@CacheEntryExpired
public void onExpiry(CacheEntryExpiredEvent<K, V> event) {
removalListener.onRemoval(event.getKey(), event.getValue(), RemovalCause.TIME);
}

@CacheEntryInvalidated
public void onInvalidation(CacheEntryInvalidatedEvent<K, V> event) {
removalListener.onRemoval(event.getKey(), event.getValue(), RemovalCause.OTHER);
}

@CacheEntryModified
public void onPostModifyExisting(CacheEntryModifiedEvent<K, V> event) {
if (!event.isCreated() && !event.isPre())
removalListener.onRemoval(event.getKey(), event.getOldValue(), RemovalCause.REPLACED);
}

@CacheEntryRemoved
public void onPostRemoval(CacheEntryRemovedEvent<K, V> event) {
if (!event.isPre())
removalListener.onRemoval(event.getKey(), event.getOldValue(), RemovalCause.MANUAL);
}

static {
EVENTS = EnumSet.noneOf(Event.Type.class);
EVENTS.add(Event.Type.CACHE_ENTRY_EVICTED);
EVENTS.add(Event.Type.CACHE_ENTRY_EXPIRED);
EVENTS.add(Event.Type.CACHE_ENTRY_INVALIDATED);
EVENTS.add(Event.Type.CACHE_ENTRY_MODIFIED);
EVENTS.add(Event.Type.CACHE_ENTRY_REMOVED);

ANNOTATIONS = Collections.newSetFromMap(new IdentityHashMap<>());
ANNOTATIONS.add(CacheEntriesEvicted.class);
ANNOTATIONS.add(CacheEntryExpired.class);
ANNOTATIONS.add(CacheEntryInvalidated.class);
ANNOTATIONS.add(CacheEntryModified.class);
ANNOTATIONS.add(CacheEntryRemoved.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package io.github.xanthic.cache.provider.infinispanjdk17;

import io.github.xanthic.cache.api.Cache;
import io.github.xanthic.cache.api.ICacheSpec;
import io.github.xanthic.cache.api.domain.ExpiryType;
import io.github.xanthic.cache.core.AbstractCacheProvider;
import org.infinispan.commons.api.CacheContainerAdmin;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
* Provides {@link Cache} instances using Infinispan's {@link org.infinispan.Cache} in heap-mode.
* <p>
* Implements size and time-based expiry.
*/
public final class InfinispanProvider extends AbstractCacheProvider {
private static final EmbeddedCacheManager MANAGER = new DefaultCacheManager();

@Override
public <K, V> Cache<K, V> build(ICacheSpec<K, V> spec) {
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.simpleCache(true);
if (spec.maxSize() != null) builder.memory().maxCount(spec.maxSize());
handleExpiration(spec.expiryTime(), spec.expiryType(), (time, type) -> {
if (type == ExpiryType.POST_WRITE)
builder.expiration().lifespan(time.toNanos(), TimeUnit.NANOSECONDS);
else
builder.expiration().maxIdle(time.toNanos(), TimeUnit.NANOSECONDS);
});

org.infinispan.Cache<K, V> cache = MANAGER.administration()
.withFlags(CacheContainerAdmin.AdminFlag.VOLATILE)
.createCache(UUID.randomUUID().toString(), builder.build());

if (spec.removalListener() != null) {
cache.addFilteredListener(
new InfinispanListener<>(spec.removalListener()),
(key, oldValue, oldMeta, newValue, newMeta, eventType) -> eventType != null && InfinispanListener.EVENTS.contains(eventType.getType()),
null,
InfinispanListener.ANNOTATIONS
);
}

return new InfinispanDelegate<>(cache);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package io.github.xanthic.cache.provider.infinispanjdk17;

import io.github.xanthic.cache.core.provider.ProviderTestBase;

public class InfinispanJava17ProviderTest extends ProviderTestBase {

public InfinispanJava17ProviderTest() {
super(new InfinispanProvider());
}

}
2 changes: 2 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ include(
":provider-guava",
":provider-infinispan",
":provider-infinispan-java11",
":provider-infinispan-java17",
)

project(":bom").name = "cache-bom"
Expand All @@ -35,3 +36,4 @@ project(":provider-expiringmap").name = "cache-provider-expiringmap"
project(":provider-guava").name = "cache-provider-guava"
project(":provider-infinispan").name = "cache-provider-infinispan"
project(":provider-infinispan-java11").name = "cache-provider-infinispan-java11"
project(":provider-infinispan-java17").name = "cache-provider-infinispan-java17"

0 comments on commit ed1eb30

Please sign in to comment.