1 /*
2  * Created on Jan 9, 2014
3  * Created by Paul Gardner
4  *
5  * Copyright 2014 Azureus Software, Inc.  All rights reserved.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  */
19 
20 
21 package org.gudy.azureus2.core3.util;
22 
23 import java.util.Collections;
24 import java.util.Map;
25 import java.util.Set;
26 import java.util.TreeMap;
27 import java.util.concurrent.ConcurrentHashMap;
28 
29 public class
30 ConcurrentHashMapWrapper<S,T>
31 {
32 	/**
33 	 * ConcurrentHashMap doesn't support null keys or values so this is a hack to support them
34 	 */
35 
36 	private static final Object NULL = new Object();
37 
38 	private final S	S_NULL = (S)NULL;
39 	private final T	T_NULL = (T)NULL;
40 
41 	private final ConcurrentHashMap<S,T>	map;
42 
43 	public
ConcurrentHashMapWrapper( int initialCapacity )44 	ConcurrentHashMapWrapper(
45 		int	initialCapacity )
46 	{
47 		map = new ConcurrentHashMap<S,T>( initialCapacity );
48 	}
49 
50 	public
ConcurrentHashMapWrapper( int initialCapacity, float loadFactor, int concurrencyLevel )51 	ConcurrentHashMapWrapper(
52 		int		initialCapacity,
53 		float	loadFactor,
54 		int 	concurrencyLevel )
55 	{
56 		map = new ConcurrentHashMap<S,T>( initialCapacity, loadFactor, concurrencyLevel );
57 	}
58 
59 	public
ConcurrentHashMapWrapper()60 	ConcurrentHashMapWrapper()
61 	{
62 		map = new ConcurrentHashMap<S,T>();
63 	}
64 
65 	public
ConcurrentHashMapWrapper( Map<S,T> init_map )66 	ConcurrentHashMapWrapper(
67 		Map<S,T>	init_map )
68 	{
69 		map = new ConcurrentHashMap<S,T>( init_map.size());
70 
71 		putAll( init_map );
72 	}
73 
74 	public void
putAll( Map<S,T> from_map )75 	putAll(
76 		Map<S,T>	from_map )
77 	{
78 		for ( Map.Entry<S,T> entry: from_map.entrySet()){
79 
80 			S key 	= entry.getKey();
81 			T value	= entry.getValue();
82 
83 			if ( key == null ){
84 
85 				key = S_NULL;
86 			}
87 
88 			if ( value == null ){
89 
90 				value = T_NULL;
91 			}
92 
93 			map.put( key, value );
94 		}
95 	}
96 
97 	public T
put( S key, T value )98 	put(
99 		S	key,
100 		T	value )
101 	{
102 		if ( key == null ){
103 
104 			key = S_NULL;
105 		}
106 
107 		if ( value == null ){
108 
109 			value = T_NULL;
110 		}
111 
112 		T result = map.put( key, value );
113 
114 		if ( result == T_NULL ){
115 
116 			return( null );
117 
118 		}else{
119 
120 			return( result );
121 		}
122 	}
123 
124 	public T
get( S key )125 	get(
126 		S	key )
127 	{
128 		if ( key == null ){
129 
130 			key = S_NULL;
131 		}
132 
133 		T result = map.get( key );
134 
135 		if ( result == T_NULL ){
136 
137 			return( null );
138 
139 		}else{
140 
141 			return( result );
142 		}
143 	}
144 
145 	public T
remove( S key )146 	remove(
147 		S	key )
148 	{
149 		if ( key == null ){
150 
151 			key = S_NULL;
152 		}
153 
154 
155 		T result = map.remove( key );
156 
157 		if ( result == T_NULL ){
158 
159 			return( null );
160 
161 		}else{
162 
163 			return( result );
164 		}
165 	}
166 
167 	public boolean
containsKey( S key )168 	containsKey(
169 		S		key )
170 	{
171 		if ( key == null ){
172 
173 			key = S_NULL;
174 		}
175 
176 		return( map.containsKey( key ));
177 	}
178 
179 		/**
180 		 * NOT MODIFIABLE
181 		 * @return
182 		 */
183 	public Set<S>
keySet()184 	keySet()
185 	{
186 		Set<S>	result = map.keySet();
187 
188 		if ( result.contains( S_NULL )){
189 
190 			result.remove( S_NULL );
191 
192 			result.add( null );
193 		}
194 
195 		return( Collections.unmodifiableSet( result ));
196 	}
197 
198 	/**
199 	 * Helper for config writing
200 	 * @return
201 	 */
202 
203 	public TreeMap<S,T>
toTreeMap()204 	toTreeMap()
205 	{
206 		TreeMap<S,T>	result = new TreeMap<S,T>();
207 
208 		for ( Map.Entry<S,T> entry: map.entrySet()){
209 
210 			S key 	= entry.getKey();
211 			T value	= entry.getValue();
212 
213 			if ( key == S_NULL ){
214 
215 				key = null;
216 			}
217 
218 			if ( value == T_NULL ){
219 
220 				value = null;
221 			}
222 
223 			result.put( key, value );
224 		}
225 
226 		return( result );
227 	}
228 }
229