FiniteSizedCache.java 2.9 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.adobe.pdfg.common;

import com.adobe.pdfg.common.IObjectRetriever;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class FiniteSizedCache {
    private int size;
    private IObjectRetriever retriever;
    private int nEntries;
    private int minUsageCount;
    private Map cache;
    private Object minUsageKey;

    public FiniteSizedCache(int size, IObjectRetriever retriever) {
        this.size = size;
        this.retriever = retriever;
        this.nEntries = 0;
        this.minUsageCount = Integer.MAX_VALUE;
        this.cache = new HashMap(this.size);
        this.minUsageKey = null;
    }

    public Object retrieve(Object key) throws Exception {
        Object value;
        value = null;
        CacheEntry entry = (CacheEntry)this.cache.get(key);
        if (entry != null) {
            value = entry.value;
            ++entry.usageCount;
            if (key.equals(this.minUsageKey)) {
                ++this.minUsageCount;
                for (Map.Entry mapEntry : this.cache.entrySet()) {
                    Object keyInCache = mapEntry.getKey();
                    CacheEntry entryInCache = (CacheEntry)mapEntry.getValue();
                    if (entryInCache.usageCount >= this.minUsageCount) continue;
                    this.minUsageCount = entryInCache.usageCount;
                    this.minUsageKey = keyInCache;
                    break;
                }
            }
        } else {
            value = this.retriever.retrieve(key);
            if (this.size == this.nEntries) {
                this.cache.remove(this.minUsageKey);
                --this.nEntries;
                this.minUsageKey = null;
            }
            entry = new CacheEntry();
            entry.usageCount = 1;
            entry.value = value;
            this.cache.put(key, entry);
            ++this.nEntries;
            if (this.minUsageCount >= 1 || this.minUsageKey == null) {
                this.minUsageCount = 1;
                this.minUsageKey = key;
            }
        }
        return this.cloneObject(value);
    }

    private Object cloneObject(Object object) throws Exception {
        ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(outBytes);
        out.writeObject(object);
        byte[] serializedObject = outBytes.toByteArray();
        ByteArrayInputStream inBytes = new ByteArrayInputStream(serializedObject);
        ObjectInputStream in = new ObjectInputStream(inBytes);
        return in.readObject();
    }

    private static class CacheEntry {
        public int usageCount;
        public Object value;

        private CacheEntry() {
        }
    }

}