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