Caffeine.java

121 lines | 3.708 kB Blame History Raw Download
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufrgs.inf.prosoft.cache;

import java.util.concurrent.TimeUnit;

/**
 *
 * @author root
 */
public class Caffeine<K, V> implements Cache<K, V> {

    private static final boolean CACHE_EVALUATE_PERFORMANCE = System.getenv("CACHE_EVENTS") == null || !System.getenv("CACHE_EVENTS").equals("false");
    private static final boolean CACHE_REGISTER_SIZE = System.getenv("CACHE_REGISTER_SIZE") != null && System.getenv("CACHE_REGISTER_SIZE").equals("true");
    private final com.github.benmanes.caffeine.cache.Cache<K, V> cache;
    private final CachePerformance cachePerformance;

    public Caffeine() {
        this(new CachePerformance());
    }

    public Caffeine(long ttl) {
        this(new CachePerformance(), ttl);
    }

    public Caffeine(String name) {
        this(new CachePerformance(name));
    }

    public Caffeine(String name, long ttl) {
        this(new CachePerformance(name), ttl);
    }

    public Caffeine(String name, Long ttl, long size) {
        this(new CachePerformance(name), ttl, size);
    }

    public Caffeine(CachePerformance cachingPerformance) {
        this.cachePerformance = cachingPerformance;
        this.cache = com.github.benmanes.caffeine.cache.Caffeine.newBuilder()
                .build();
    }

    public Caffeine(CachePerformance cachingPerformance, long ttl) {
        this.cachePerformance = cachingPerformance;
        this.cache = com.github.benmanes.caffeine.cache.Caffeine.newBuilder()
                .expireAfterWrite(ttl, TimeUnit.MILLISECONDS)
                .build();
    }

    public Caffeine(CachePerformance cachingPerformance, Long ttl, long size) {
        this.cachePerformance = cachingPerformance;
        if (ttl == null) {
            this.cache = com.github.benmanes.caffeine.cache.Caffeine.newBuilder()
                    .maximumSize(size)
                    .build();

        } else {
            this.cache = com.github.benmanes.caffeine.cache.Caffeine.newBuilder()
                    .expireAfterWrite(ttl, TimeUnit.MILLISECONDS)
                    .maximumSize(size)
                    .build();

        }
    }

    public CachePerformance getCachePerformance() {
        return this.cachePerformance;
    }

    @Override
    public void put(K key, V value, long timeToLive) {
        put(key, value);
    }

    @Override
    public void put(K key, V value) {
        this.cache.put(key, value);
        registerEvent(EventType.ADDITION, value);
    }

    @Override
    public V get(K key) throws KeyNotFoundException {
        V get = this.cache.getIfPresent(key);
        if (get == null) {
            registerEvent(EventType.MISS, key);
        }
        registerEvent(EventType.HIT, get);
        return get;
    }

    @Override
    public void invalidate(K key) {
        this.cache.invalidate(key);
        registerEvent(EventType.INVALIDATION, null);
    }

    private String getIdentifier(Object object) {
        return object != null ? String.valueOf(object.hashCode()) : "null";
    }

    private void registerEvent(EventType eventType, Object object) {
        if (!CACHE_EVALUATE_PERFORMANCE) {
            return;
        }
        String identifier = getIdentifier(object);
        if (CACHE_REGISTER_SIZE) {
            this.cachePerformance.registerEvent(eventType, identifier, CachePerformance.calculateObjectSize(object));
        } else {
            this.cachePerformance.registerEvent(eventType, identifier);
        }
        if (eventType.equals(EventType.ADDITION)) {
            this.cachePerformance.registerSize((int) this.cache.stats().loadCount());
        }
    }

}