/*
 * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.helper;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.*;

/**
 * Provide a concurrent fixed size caching mechanism.
 * This is used for caching EJBQL parsed queries, Update calls,
 * and other places a fixed size cache is needed.
 * The default fixed size is 100.
 */
public class ConcurrentFixedCache implements Serializable {
    protected int maxSize;
    protected Map cache;

    /**
     * Create a new concurrent cache, with a fixed size of 100.
     */
    public ConcurrentFixedCache() {
        this(100);
    }

    /**
     * Create a new concurrent cache, with the max size.
     */
    public ConcurrentFixedCache(int maxSize) {
        // PERF: Use a concurrent map to allow concurrent gets.
        this.cache = new ConcurrentHashMap(maxSize);
        this.maxSize = maxSize;
    }

    /**
     * Return the fixed size of the parse cache.
     */
    public int getMaxSize() {
        return maxSize;
    }

    /**
     * Set the fixed size of the parse cache.
     * When the size is exceeded, subsequent EJBQL will not be cached.
     * The default size is 100;
     */
    public void setMaxSize(int maxSize) {
        this.maxSize = maxSize;
    }

    /**
     * Return the pre-parsed query that represents the EJBQL string.
     * If the EJBQL has not been cached, null is returned.
     */
    public Object get(Object key) {
        return this.cache.get(key);
    }

    public void clear(){
        this.cache.clear();
    }

    /**
     * Add the value to the cache.
     * Remove the
     */
    public void put(Object key, Object value) {
        if (this.maxSize == 0) {
            return;
        }
        this.cache.put(key, value);
        // Currently just removes the first one encountered, not LRU,
        // this is not ideal, but the most concurrent and quickest way to ensure fixed size.
        if (this.cache.size() > this.maxSize) {
            Iterator iterator = this.cache.keySet().iterator();
            try {
                while ((this.cache.size() > this.maxSize) && iterator.hasNext()) {
                    Object next = iterator.next();
                    // Do not remove what was just put in.
                    if (next != key) {
                        this.cache.remove(next);
                    }
                }
            } catch (Exception alreadyGone) {
                // Ignore.
            }
        }
    }

    /**
     * Remove from cache.
     */
    public void remove(Object key) {
        this.cache.remove(key);
    }

    /**
     * Return the cache.
     */
    public Map getCache() {
        return cache;
    }
}
