FacetCache.java 4.54 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  org.apache.commons.collections.map.AbstractLinkedMap
 *  org.apache.commons.collections.map.AbstractLinkedMap$LinkEntry
 *  org.apache.commons.collections.map.LRUMap
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.search.impl.builder;

import com.day.cq.search.PredicateGroup;
import com.day.cq.search.facets.Facet;
import java.util.Map;
import org.apache.commons.collections.map.AbstractLinkedMap;
import org.apache.commons.collections.map.LRUMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class FacetCache {
    private final Logger log;
    private final Map<PredicateGroup, Entry> map;
    private final int maxEntries;
    private final long entryLifetimeMsec;
    private int accesses;
    private int misses;

    public FacetCache(int maxEntries, long entryLifetimeMsec) {
        this.log = LoggerFactory.getLogger(this.getClass());
        this.map = new CustomLRUMap();
        this.accesses = 0;
        this.misses = 0;
        this.maxEntries = Math.max(maxEntries, 0);
        this.entryLifetimeMsec = entryLifetimeMsec;
        this.log.info("{}", (Object)this.toString());
    }

    public String toString() {
        return this.getClass().getSimpleName() + ", max entries=" + this.maxEntries + ", entry lifetime (msec)=" + this.entryLifetimeMsec + (this.maxEntries <= 0 ? ", OFF" : ", ON");
    }

    public synchronized void clear() {
        this.log.info("clearing facet cache");
        this.map.clear();
    }

    public synchronized Map<String, Facet> get(PredicateGroup key) {
        boolean doInfoStats;
        Map<String, Facet> result;
        if (this.maxEntries == 0) {
            this.log.trace("max entries is set to zero, caching disabled");
            return null;
        }
        if ((long)this.accesses == Long.MAX_VALUE) {
            this.accesses = 0;
            this.misses = 0;
        }
        ++this.accesses;
        Entry e = this.map.get(key);
        if (e == null) {
            ++this.misses;
            result = null;
        } else if (e.expired()) {
            this.log.debug("expired facets entry, removing from cache:\n{}", (Object)key);
            this.map.remove(key);
            ++this.misses;
            result = null;
        } else {
            result = e.data;
        }
        boolean bl = doInfoStats = this.accesses % 10 == 0;
        if (this.log.isInfoEnabled() && doInfoStats || this.log.isDebugEnabled()) {
            long ratio = 100;
            if (this.misses >= 0) {
                ratio -= (long)this.misses * 100 / (long)this.accesses;
            }
            StringBuilder statistics = new StringBuilder();
            statistics.append("size=").append(this.map.size());
            statistics.append(", #accesses=").append(this.accesses);
            statistics.append(", #hits=").append(this.accesses - this.misses);
            statistics.append(", #misses=").append(this.misses);
            statistics.append(", cacheRatio=").append(ratio).append("%");
            if (doInfoStats) {
                this.log.info(statistics.toString());
            } else {
                this.log.debug(statistics.toString());
            }
        }
        return result;
    }

    public synchronized void put(PredicateGroup key, Map<String, Facet> value) {
        if (this.maxEntries == 0) {
            this.log.trace("max entries is set to zero, caching disabled");
            return;
        }
        this.log.trace("caching facets:\n{}", (Object)key);
        this.map.put(key, new Entry(value));
    }

    private class CustomLRUMap
    extends LRUMap {
        private static final long serialVersionUID = 1;

        private CustomLRUMap() {
        }

        public boolean isFull() {
            return this.size() >= FacetCache.this.maxEntries;
        }

        protected boolean removeLRU(AbstractLinkedMap.LinkEntry entry) {
            FacetCache.this.log.debug("cache hit size limit at {} entries, removing least recently used one:\n{}", (Object)this.size(), entry.getKey());
            return super.removeLRU(entry);
        }
    }

    private class Entry {
        final Map<String, Facet> data;
        final long expirationTime;

        Entry(Map<String, Facet> data) {
            this.data = data;
            this.expirationTime = FacetCache.this.entryLifetimeMsec > 0 ? System.currentTimeMillis() + FacetCache.this.entryLifetimeMsec : -1;
        }

        boolean expired() {
            return this.expirationTime >= 0 && System.currentTimeMillis() > this.expirationTime;
        }
    }

}