package cz.cuni.amis.utils;

import java.util.HashMap;
import java.util.Map;

/**
 * All maps are unsycnhronized!
 * 
 * @author Jimmy
 *
 * @param <PRIMARY_KEY>
 * @param <SECONDARY_KEY>
 * @param <ITEM>
 */
public class HashMapMap<PRIMARY_KEY, SECONDARY_KEY, ITEM> {
	
	private Map<PRIMARY_KEY, Map<SECONDARY_KEY, ITEM>> maps = 
		new HashMap<PRIMARY_KEY, Map<SECONDARY_KEY, ITEM>>();
	
	public HashMapMap() {
	}
	
	public Map<SECONDARY_KEY, ITEM> get(PRIMARY_KEY primaryKey) {
		synchronized(maps) {
			Map<SECONDARY_KEY, ITEM> map = maps.get(primaryKey);
			if (map != null) return map;
			map = new HashMap<SECONDARY_KEY, ITEM>();
			maps.put(primaryKey, map);
			return map;
		}
	}
	
	public ITEM get(PRIMARY_KEY primaryKey, SECONDARY_KEY secondaryKey) {
		Map<SECONDARY_KEY, ITEM> map = get(primaryKey);
		synchronized(map) {
			return map.get(secondaryKey);
		}
	}
	
	public void put(PRIMARY_KEY primaryKey, SECONDARY_KEY secondaryKey, ITEM item) {
		Map<SECONDARY_KEY, ITEM> map = get(primaryKey);
		synchronized(map) {
			map.put(secondaryKey, item);
		}
	}
	
	public Map<SECONDARY_KEY, ITEM> remove(PRIMARY_KEY primaryKey) {
		synchronized(maps) {
			if (maps.get(primaryKey) != null) {
				return maps.remove(primaryKey);
			} else {
				return new HashMap<SECONDARY_KEY, ITEM>();
			}
		}
		
	}

	public ITEM remove(PRIMARY_KEY primaryKey, SECONDARY_KEY secondaryKey) {
		Map<SECONDARY_KEY, ITEM> map = get(primaryKey);
		synchronized(map) {
			return map.remove(secondaryKey);
		}
		
	}

}
