All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.quarkus.oidc.runtime.MemoryCache Maven / Gradle / Ivy

Go to download

Secure your applications with OpenID Connect Adapter and IDP such as Keycloak

There is a newer version: 3.17.5
Show newest version
package io.quarkus.oidc.runtime;

import java.time.Duration;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

import io.vertx.core.Handler;
import io.vertx.core.Vertx;

public class MemoryCache {
    private volatile Long timerId = null;

    private final Map> cacheMap = new ConcurrentHashMap<>();
    private AtomicInteger size = new AtomicInteger();
    private final Duration cacheTimeToLive;
    private final int cacheSize;

    public MemoryCache(Vertx vertx, Optional cleanUpTimerInterval,
            Duration cacheTimeToLive, int cacheSize) {
        this.cacheTimeToLive = cacheTimeToLive;
        this.cacheSize = cacheSize;
        init(vertx, cleanUpTimerInterval);
    }

    private void init(Vertx vertx, Optional cleanUpTimerInterval) {
        if (cleanUpTimerInterval.isPresent()) {
            timerId = vertx.setPeriodic(cleanUpTimerInterval.get().toMillis(), new Handler() {
                @Override
                public void handle(Long event) {
                    // Remove all the entries which have expired
                    removeInvalidEntries();
                }
            });
        }
    }

    public void add(String key, T result) {
        if (cacheSize > 0) {
            if (!prepareSpaceForNewCacheEntry()) {
                clearCache();
            }
            cacheMap.put(key, new CacheEntry(result));
        }
    }

    public T remove(String key) {
        CacheEntry entry = removeCacheEntry(key);
        return entry == null ? null : entry.result;
    }

    public T get(String key) {
        CacheEntry entry = cacheMap.get(key);
        return entry == null ? null : entry.result;
    }

    public boolean containsKey(String key) {
        return cacheMap.containsKey(key);
    }

    private void removeInvalidEntries() {
        long now = now();
        for (Iterator>> it = cacheMap.entrySet().iterator(); it.hasNext();) {
            Map.Entry> next = it.next();
            if (next != null) {
                if (isEntryExpired(next.getValue(), now)) {
                    try {
                        it.remove();
                        size.decrementAndGet();
                    } catch (IllegalStateException ex) {
                        // continue
                    }
                }
            }
        }
    }

    private boolean prepareSpaceForNewCacheEntry() {
        int currentSize;
        do {
            currentSize = size.get();
            if (currentSize == cacheSize) {
                return false;
            }
        } while (!size.compareAndSet(currentSize, currentSize + 1));
        return true;
    }

    private CacheEntry removeCacheEntry(String token) {
        CacheEntry entry = cacheMap.remove(token);
        if (entry != null) {
            size.decrementAndGet();
        }
        return entry;
    }

    private boolean isEntryExpired(CacheEntry entry, long now) {
        return entry.createdTime + cacheTimeToLive.toMillis() < now;
    }

    private static long now() {
        return System.currentTimeMillis();
    }

    private static class CacheEntry {
        volatile T result;
        long createdTime = System.currentTimeMillis();

        public CacheEntry(T result) {
            this.result = result;
        }
    }

    public int getCacheSize() {
        return cacheMap.size();
    }

    public void clearCache() {
        cacheMap.clear();
        size.set(0);
    }

    public void stopTimer(Vertx vertx) {
        if (timerId != null && vertx.cancelTimer(timerId)) {
            timerId = null;
        }
    }

    public boolean isTimerRunning() {
        return timerId != null;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy