package com.pictc.cache;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class DefaultCacheProvider<K,V>  extends AbstractCache<K,V> implements TanukiCache<K,V>{
	
    private final HashMap<K, V> cache;
    
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    
    private final Lock readLock = lock.readLock();
    
    private final Lock writeLock = lock.writeLock();
    
	public DefaultCacheProvider(String cache_name) {
		super(cache_name);
		cache = new HashMap<K, V>();
	}


	@Override
	public void save(K key, V value) {
        writeLock.lock();
        try {
        	if(cache.containsKey(key)) cache.remove(key);
            cache.put(key, value);
        } finally {
            writeLock.unlock();
        }
	}


	@Override
	public void remove(K key) {
        writeLock.lock();
        try {
            cache.remove(key);
        } finally {
            writeLock.unlock();
        }
	}


	@Override
	public V get(K key) {
		readLock.lock();
        try {
            return cache.get(key);
        } finally {
            readLock.unlock();
        }
	}


	@Override
	public boolean containsKey(K key) {
        readLock.lock();
        try {
            return cache.containsKey(key);
        } finally {
            readLock.unlock();
        }
	}


	@Override
	public void clear() {
        writeLock.lock();
        try {
            cache.clear();
        } finally {
            writeLock.unlock();
        }
	}

	@Override
	public List<V> values() {
		return new ArrayList<V>(cache.values());
	}

	@Override
	public void save(K key, V value, long time, TimeUnit unit) {
        writeLock.lock();
        try {
            cache.put(key, value);
            setExpire(key, time, unit);
        } finally {
            writeLock.unlock();
        }
	}

	@Override
	public Set<K> keys() {
		return cache.keySet();
	}

	@Override
	public boolean setExpire(K key, long time, TimeUnit unit) {
		// TODO Auto-generated method stub
		return false;
	}
}
