package com.iamberry.cache;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
/**
 * @company	深圳爱贝源科技有限公司
 * @website www.iamberry.com
 * @author 	献
 * @tel		18271840547
 * @date	2016年9月5日
 * @explain	缓存实现，模拟JVM实现，多线程下是安全的
 */
public final class LocalCache<K, V> {

	/**
	 * 总大小
	 */
    private final int size;

    /**
     * 对象的分配区域
     */
    private final Map<K,V> eden;

    /**
     * 如果eden区域分配完毕，那么将数据分配到longterm,使用WeakHashMap维护数据
     */
    private final Map<K,V> longterm;

    /**
     * 构造参数，初始化一个默认大小的map，保证缓存的高效性
     * @param size
     */
    public LocalCache(int size) {
        this.size = size;
        this.eden = new ConcurrentHashMap<>(size);
        this.longterm = new WeakHashMap<>(size);
    }

    /**
     * 获取存储的值,线程安全
     * @param k key值
     * @return 缓存的值
     */
    public V get(K k) {
    	// 首先在新生代获取
        V v = this.eden.get(k);
        if (v == null) {
        	// 如果没有在新生代，去longterm获取
            synchronized (longterm) {
                v = this.longterm.get(k);
            }
            
            // 如果数据不为空，将数据put到eden区,缓存数据
            if (v != null) {
                this.eden.put(k, v);
            }
        }
        return v;
    }

    /**
     * 将一个数据put到缓存中
     * @param k
     * @param v
     */
    public void put(K k, V v) {
    	
    	// 判断是否eden区是否存在数据
        if (this.eden.size() >= size) {
        	
        	// 如果eden去分配完毕，那么僵数据copy到longterm去
            synchronized (longterm) {
                this.longterm.putAll(this.eden);
            }
            
            // 清空eden数据
            this.eden.clear();
        }
        
        // 将数据分配在eden区
        this.eden.put(k, v);
    }
}