How to Implement CacheMap with automatic expiration of entries?

会有一股神秘感。 提交于 2021-01-01 02:17:41

问题


Hi everyone I want to implement cache map in java in which map entries expire after given time.

I have interface like this, I have to implement these methods, but I am not understand how actually start.

    public class CacheMapImpl implements CacheMap<Integer, String> {

    @Override
    public void setTimeToLive(long timeToLive) {


    }

    @Override
    public long getTimeToLive() {

        return 0;
    }

    @Override
    public String put(Integer key, String value) {

        return null;
    }

    @Override
    public void clearExpired() {


    }

    @Override
    public void clear() {


    }

    @Override
    public boolean containsKey(Object key) {

        return false;
    }

    @Override
    public boolean containsValue(Object value) {

        return false;
    }

    @Override
    public String get(Object key) {

        return null;
    }

    @Override
    public boolean isEmpty() {

        return false;
    }

    @Override
    public String remove(Object key) {

        return null;
    }

    @Override
    public int size() {

        return 0;
    }

}

Please tell me how to implement these methods, how to start write little bit code for me, kindly update my cachemap interface with code.


回答1:


You have to manage an internal map with the same key. User your put method to add the new value to your map and also add a value for your internal times map. You can store a Long as a value, which is the concrete time for that value.

Then, start a new thread in background thatc will check all times for all keys in the internal map and remove those that are 'old' entries from both, internal map and your main map.

Here is the code. As I see your Map implements an interface with some methods provided for clear the expired values, I understand you don't need an automatic way to remove expired values. So, the code should be something like:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class CacheMapImpl implements CacheMap<Integer, String> {

    private Map<Integer, Long> timesCache = new HashMap<Integer, Long>();
    private Map<Integer, String> values = new HashMap<Integer, String>();

    /** Time for the elemens to keep alive in the map in milliseconds. */
    long timeToLive = 0;

    @Override
    public void setTimeToLive(long timeToLive) {
        this.timeToLive = timeToLive;
    }

    @Override
    public long getTimeToLive() {

        return this.timeToLive;
    }

    @Override
    public String put(Integer key, String value) {
        values.put(key, value);
        timesCache.put(key, System.currentTimeMillis());
        return value;
    }

    @Override
    public void clearExpired() {

        // Just remove if timeToLive has been set before...
        if (timeToLive > 0) {
            List<Integer> keysToClear = new ArrayList<Integer>();
            long currentTime = System.currentTimeMillis();

            // Check what keys to remove
            for (Entry<Integer, Long> e : timesCache.entrySet()) {
                if ((currentTime - e.getValue().longValue()) > this.timeToLive) {
                    keysToClear.add(e.getKey());
                }
            }

            // Remove the expired keys
            for (Integer key : keysToClear) {
                this.timesCache.remove(key);
                this.values.remove(key);
            }
        }

    }

    @Override
    public void clear() {
        this.timesCache.clear();
        this.values.clear();
    }

    @Override
    public boolean containsKey(Object key) {

        return this.values.containsKey(key);
    }

    @Override
    public boolean containsValue(Object value) {

        return this.values.containsValue(value);
    }

    @Override
    public String get(Object key) {

        return this.values.get(key);
    }

    @Override
    public boolean isEmpty() {

        return this.values.isEmpty();
    }

    @Override
    public String remove(Object key) {
        String rto = null;
        if (containsKey(key)) {
            this.values.remove(key);
            this.timesCache.remove(key);
            rto = key.toString();
        }
        return rto;
    }

    @Override
    public int size() {

        return this.values.size();
    }

}



回答2:


How about this

package map;

import java.util.Map;

import lombok.Getter;

public class TimeOutCacheMap<K, V> {



Long timeout;

    @Getter
    private static class MapValue<V> {
        private Long timeOut;
        private V v;

        public MapValue(Long timeout, V v) {
            this.timeOut = timeout;
            this.v = v;
        }
    }

    public TimeOutCacheMap(Long timeoutInMilliSeconds, Class<? extends Map> mapClazz) {
        if (timeoutInMilliSeconds > 5000000) {
            throw new RuntimeException("Timeout can be upto 5000000");
        }
        this.timeout = timeoutInMilliSeconds;
        try {
            map = mapClazz.newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private Map<K, MapValue<V>> map;


    public V put(K k, V v) {
        if (k == null) {
            throw new RuntimeException("Invalid key");
        }
        Long currentTime = System.currentTimeMillis();
        Long timeOutValue = currentTime + this.timeout;
        MapValue<V> newV = new MapValue<V>(timeOutValue, v);
        MapValue<V> oldV = map.put(k, newV);
        return ((oldV == null) ? null : oldV.getV());
    }

    public V get(K k) {
        if (k == null) {
            throw new RuntimeException("Invalid key");
        }
        Long currentTime = System.currentTimeMillis();
        MapValue<V> mapValue = map.get(k);
        if (mapValue!=null &&  mapValue.getTimeOut() != null && mapValue.getTimeOut() >= currentTime) {
            return mapValue.getV();
        } else {
            map.remove(k);
            return null;
        }
    }
}


来源:https://stackoverflow.com/questions/36564256/how-to-implement-cachemap-with-automatic-expiration-of-entries

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!