View Javadoc

1   package cz.cuni.amis.utils.maps;
2   
3   import java.util.Collections;
4   import java.util.HashMap;
5   import java.util.Map;
6   
7   
8   /**
9    * 
10   * Three-level thread-safe hash map, implemented via synchronized maps (Collections.synchronizedMap)
11   * 
12   * @author srlok
13   *
14   * @param <PRIMARY_KEY>
15   * @param <SECONDARY_KEY>
16   * @param <TERTIARY_KEY>
17   * @param <ITEM>
18   */
19  public class HashTriMap<PRIMARY_KEY,SECONDARY_KEY,TERTIARY_KEY,ITEM>
20  	extends HashMap<PRIMARY_KEY, Map<SECONDARY_KEY, Map<TERTIARY_KEY,ITEM>>>
21  {
22  	
23  	/**
24  	 * 
25  	 */
26  	private static final long serialVersionUID = 1L;
27  
28  	private int secondaryCapacity;
29  	private int tertiaryCapacity;
30  	
31  	public HashTriMap()
32  	{
33  		secondaryCapacity = 16;
34  		tertiaryCapacity = 16;
35  	}
36  	
37  	public HashTriMap( int primaryCapacity, int secondaryCapacity, int tertiaryCapacity)
38  	{
39  		super(primaryCapacity);
40  		this.secondaryCapacity = secondaryCapacity;
41  		this.tertiaryCapacity = tertiaryCapacity;
42  	}
43  	
44  	
45  	/**
46  	 * Returns a HashMap<SECONDARY_KEY,HashMap<TERTIARY_KEY,ITEM>>
47  	 * Never returns null, if the map under primary key doesn't exist, an empty one is added and returned.
48  	 * @param primaryKey
49  	 * @return
50  	 */
51  	@SuppressWarnings("unchecked")
52  	@Override
53  	public Map<SECONDARY_KEY, Map<TERTIARY_KEY,ITEM>> get(Object primaryKey)
54  	{
55  		Map<SECONDARY_KEY, Map<TERTIARY_KEY,ITEM>> result = super.get(primaryKey);
56  		if (result != null) { return result; };
57  		result = Collections.synchronizedMap( new HashMapMap<SECONDARY_KEY,TERTIARY_KEY,ITEM>(secondaryCapacity, tertiaryCapacity) );
58  		super.put( (PRIMARY_KEY)primaryKey,result);
59  		return result;
60  	}
61  	
62  	/**
63  	 * Returns the requested map, never returns null.
64  	 * If the map does not exist an empty map is created and returned.
65  	 * @param primaryKey
66  	 * @param secondaryKey
67  	 * @return
68  	 */
69  	public Map<TERTIARY_KEY,ITEM> get(PRIMARY_KEY primaryKey, SECONDARY_KEY secondaryKey)
70  	{
71  		Map<TERTIARY_KEY, ITEM> result = get(primaryKey).get(secondaryKey);
72  		if (result != null) { return result; };
73  		result = Collections.synchronizedMap( new HashMap<TERTIARY_KEY,ITEM>(tertiaryCapacity));
74  		get(primaryKey).put(secondaryKey, result);
75  		return result;
76  	}
77  	
78  	/**
79  	 * Returns item specified, returns null if item does not appear in the map.
80  	 * @param primaryKey
81  	 * @param secondaryKey
82  	 * @param tertiaryKey
83  	 * @return
84  	 */
85  	public ITEM get(PRIMARY_KEY primaryKey, SECONDARY_KEY secondaryKey, TERTIARY_KEY tertiaryKey)
86  	{
87  		return get(primaryKey,secondaryKey).get(tertiaryKey);
88  	}
89  	
90  	/**
91  	 * Puts the item into the map.
92  	 * @param primaryKey
93  	 * @param secondaryKey
94  	 * @param tertiaryKey
95  	 * @param item
96  	 */
97  	public void put(PRIMARY_KEY primaryKey, SECONDARY_KEY secondaryKey, TERTIARY_KEY tertiaryKey, ITEM item)
98  	{
99  		get(primaryKey,secondaryKey).put(tertiaryKey, item);
100 	}
101 	
102 	/**
103 	 * Removes the requested map. If the map doesn't exist, returns an empty map.
104 	 */
105 	@Override
106 	public Map<SECONDARY_KEY, Map<TERTIARY_KEY,ITEM>> remove(Object primaryKey)
107 	{
108 		Map<SECONDARY_KEY, Map<TERTIARY_KEY,ITEM>> result = super.remove(primaryKey);
109 		if (result != null) { return result; };
110 		return Collections.synchronizedMap( new HashMapMap<SECONDARY_KEY, TERTIARY_KEY, ITEM>(secondaryCapacity, tertiaryCapacity) );
111 	}
112 	
113 	/**
114 	 * removes the map under primary and secondary key, if the map does not exist,
115 	 * the data structure is not changed and a new map is returned.
116 	 * @param primaryKey
117 	 * @param secondaryKey
118 	 * @return
119 	 */
120 	public Map<TERTIARY_KEY,ITEM> remove(PRIMARY_KEY primaryKey, SECONDARY_KEY secondaryKey)
121 	{
122 		Map<TERTIARY_KEY,ITEM> result = get(primaryKey).remove(secondaryKey);
123 		if ( result != null) { return result; };
124 		return Collections.synchronizedMap( new HashMap<TERTIARY_KEY, ITEM> (tertiaryCapacity));
125 	}
126 	
127 	/**
128 	 * Returns the item under specified keys and removes it from the map,
129 	 * returns null if item is not present in the map.
130 	 * @param primaryKey
131 	 * @param secondaryKey
132 	 * @param tertiaryKey
133 	 * @return
134 	 */
135 	public ITEM remove(PRIMARY_KEY primaryKey, SECONDARY_KEY secondaryKey, TERTIARY_KEY tertiaryKey)
136 	{
137 		return get(primaryKey,secondaryKey).remove(tertiaryKey);
138 	}
139 }