All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alicp.jetcache.embedded.LinkedHashMapCache Maven / Gradle / Ivy

The newest version!
/**
 * Created on  13-09-12 19:02
 */
package com.alicp.jetcache.embedded;

import com.alicp.jetcache.CacheResultCode;
import com.alicp.jetcache.CacheValueHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author huangli
 */
public class LinkedHashMapCache extends AbstractEmbeddedCache {

    private static Logger logger = LoggerFactory.getLogger(LinkedHashMapCache.class);

    public LinkedHashMapCache(EmbeddedCacheConfig config) {
        super(config);
        addToCleaner();
    }

    protected void addToCleaner() {
        Cleaner.add(this);
    }

    @Override
    protected InnerMap createAreaCache() {
        return new LRUMap(config.getLimit());
    }

    @Override
    public  T unwrap(Class clazz) {
        if (clazz.equals(LinkedHashMap.class)) {
            return (T) innerMap;
        }
        throw new IllegalArgumentException(clazz.getName());
    }

    public void cleanExpiredEntry() {
        ((LRUMap) innerMap).cleanExpiredEntry();
    }

    final class LRUMap extends LinkedHashMap implements InnerMap {

        private final int max;
        private final ReentrantLock lock = new ReentrantLock();

        public LRUMap(int max) {
            super((int) (max * 1.4f), 0.75f, true);
            this.max = max;
//            this.lockObj = lockObj;
        }

        @Override
        protected boolean removeEldestEntry(Map.Entry eldest) {
            return size() > max;
        }

        void cleanExpiredEntry() {
            lock.lock();
            long t = System.currentTimeMillis();
            try {
                for (Iterator it = entrySet().iterator(); it.hasNext(); ) {
                    Map.Entry en = (Map.Entry) it.next();
                    Object value = en.getValue();
                    if (value != null) {
                        CacheValueHolder h;
                        try {
                            h = (CacheValueHolder) value;
                        } catch (ClassCastException e) {
                            // assert false
                            logger.error("value of key " + en.getKey() + " is not a CacheValueHolder. type=" + value.getClass());
                            it.remove();
                            continue;
                        }
                        if (t >= h.getExpireTime()) {
                            it.remove();
                        }
                    } else {
                        // assert false
                        logger.error("key " + en.getKey() + " is null");
                    }
                }
            } finally {
                lock.unlock();
            }
        }

        @Override
        public Object getValue(Object key) {
            lock.lock();
            try{
                return get(key);
            }finally {
                lock.unlock();
            }
        }

        @Override
        public Map getAllValues(Collection keys) {
            lock.lock();
            Map values = new HashMap();
            try{
                for (Object key : keys) {
                    Object v = get(key);
                    if (v != null) {
                        values.put(key, v);
                    }
                }
            }finally {
                lock.unlock();
            }
            return values;
        }

        @Override
        public void putValue(Object key, Object value) {
            lock.lock();
            try{
                put(key, value);
            }finally {
                lock.unlock();
            }
        }

        @Override
        public void putAllValues(Map map) {
            lock.lock();
            try{
                Set set = map.entrySet();
                for (Map.Entry en : set) {
                    put(en.getKey(), en.getValue());
                }
            }finally {
                lock.unlock();
            }
        }

        @Override
        public boolean removeValue(Object key) {
            lock.lock();
            try{
                return remove(key) != null;
            }finally {
                lock.unlock();
            }
        }

        @Override
        public void removeAllValues(Collection keys) {
            lock.lock();
            try{
                for (Object k : keys) {
                    remove(k);
                }
            }finally {
                lock.unlock();
            }
        }

        @Override
        @SuppressWarnings("unchecked")
        public boolean putIfAbsentValue(Object key, Object value) {
            lock.lock();
            try{
                CacheValueHolder h = (CacheValueHolder) get(key);
                if (h == null || parseHolderResult(h).getResultCode() == CacheResultCode.EXPIRED) {
                    put(key, value);
                    return true;
                } else {
                    return false;
                }
            }finally {
                lock.unlock();
            }
        }
    }


}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy