LintCode Memcache

原题网址:http://www.lintcode.com/en/problem/memcache/

Implement a memcache which support the following features:

  1. get(curtTime, key). Get the key's value, return 2147483647 if key does not exist.
  2. set(curtTime, key, value, ttl). Set the key-value pair in memcache with a time to live (ttl). The key will be valid from curtTime to curtTime + ttl - 1 and it will be expired after ttl seconds. if ttl is 0, the key lives forever until out of memory.
  3. delete(curtTime, key). Delete the key.
  4. incr(curtTime, key, delta). Increase the key's value by delta return the new value. Return 2147483647 if key does not exist.
  5. decr(curtTime, key, delta). Decrease the key's value by delta return the new value. Return 2147483647 if key does not exist.

It's guaranteed that the input is given with increasingcurtTime.

Clarification

Actually, a real memcache server will evict keys if memory is not sufficient, and it also supports variety of value types like string and integer. In our case, let's make it simple, we can assume that we have enough memory and all of the values are integers.

Search "LRU" & "LFU" on google to get more information about how memcache evict data.

Try the following problem to learn LRU cache:
http://www.lintcode.com/problem/lru-cache

Example
get(1, 0)
>> 2147483647
set(2, 1, 1, 2)
get(3, 1)
>> 1
get(4, 1)
>> 2147483647
incr(5, 1, 1)
>> 2147483647
set(6, 1, 3, 0)
incr(7, 1, 1)
>> 4
decr(8, 1, 1)
>> 3
get(9, 1)
>> 3
delete(10, 1)
get(11, 1)
>> 2147483647
incr(12, 1, 1)
>> 2147483647

方法:使用哈希映射保存键值对,使用有序映射保存时间戳数据。

public class Memcache {
    private Map<Integer, Cache> map = new HashMap<>();
    private TreeMap<Integer, List<Cache>> tm = new TreeMap<>();

    public Memcache() {
        // Initialize your data structure here.
    }
    
    private void expire(int curtTime) {
        SortedMap<Integer, List<Cache>> hm = tm.headMap(curtTime);
        for(int key : hm.keySet()) {
            for(Cache cache : hm.get(key)) {
                map.remove(cache.key);
            }
            tm.remove(key);
        }
    }

    public int get(int curtTime, int key) {
        // Write your code here
        expire(curtTime);
        Cache cache = map.get(key);
        if (cache == null) return Integer.MAX_VALUE;
        return cache.val;
        
    }

    public void set(int curtTime, int key, int value, int ttl) {
        // Write your code here
        expire(curtTime);
        Cache cache = map.get(key);
        if (cache == null) {
            cache = new Cache(key, value, ttl == 0 ? Integer.MAX_VALUE : curtTime + ttl - 1);
            map.put(key, cache);
            List<Cache> list = tm.get(cache.ttl);
            if (list == null) {
                list = new ArrayList<Cache>();
                tm.put(cache.ttl, list);
            }
            list.add(cache);
        } else {
            cache.val = value;
            List<Cache> list = tm.get(cache.ttl);
            for(int i = 0; i < list.size(); i++) {
                if (list.get(i).key == key) {
                    list.remove(i);
                    break;
                }
            }
            cache.ttl = ttl == 0 ? Integer.MAX_VALUE : curtTime + ttl - 1;
            list = tm.get(cache.ttl);
            if (list == null) {
                list = new ArrayList<Cache>();
                tm.put(cache.ttl, list);
            }
            list.add(cache);
        }
    }

    public void delete(int curtTime, int key) {
        // Write your code here
        expire(curtTime);
        Cache cache = map.get(key);
        if (cache == null) return;
        List<Cache> list = tm.get(cache.ttl);
        for(int i = 0; i < list.size(); i++) {
            if (list.get(i).key == key) {
                list.remove(i);
                break;
            }
        }
        map.remove(key);
    }
    
    public int incr(int curtTime, int key, int delta) {
        // Write your code here
        expire(curtTime);
        Cache cache = map.get(key);
        if (cache == null) return Integer.MAX_VALUE;
        cache.val += delta;
        return cache.val;
    }

    public int decr(int curtTime, int key, int delta) {
        // Write your code here
        expire(curtTime);
        Cache cache = map.get(key);
        if (cache == null) return Integer.MAX_VALUE;
        cache.val -= delta;
        return cache.val;
    }
}

class Cache {
    int key;
    int val;
    int ttl;
    Cache(int key, int val, int ttl) {
        this.key = key;
        this.val = val;
        this.ttl = ttl;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值