/* * Created on Jan 9, 2014 * Created by Paul Gardner * * Copyright 2014 Azureus Software, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License only. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ package org.gudy.azureus2.core3.util; import java.util.Collections; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; public class ConcurrentHashMapWrapper<S,T> { /** * ConcurrentHashMap doesn't support null keys or values so this is a hack to support them */ private static final Object NULL = new Object(); private final S S_NULL = (S)NULL; private final T T_NULL = (T)NULL; private final ConcurrentHashMap<S,T> map; public ConcurrentHashMapWrapper( int initialCapacity ) { map = new ConcurrentHashMap<S,T>( initialCapacity ); } public ConcurrentHashMapWrapper( int initialCapacity, float loadFactor, int concurrencyLevel ) { map = new ConcurrentHashMap<S,T>( initialCapacity, loadFactor, concurrencyLevel ); } public ConcurrentHashMapWrapper() { map = new ConcurrentHashMap<S,T>(); } public ConcurrentHashMapWrapper( Map<S,T> init_map ) { map = new ConcurrentHashMap<S,T>( init_map.size()); putAll( init_map ); } public void putAll( Map<S,T> from_map ) { for ( Map.Entry<S,T> entry: from_map.entrySet()){ S key = entry.getKey(); T value = entry.getValue(); if ( key == null ){ key = S_NULL; } if ( value == null ){ value = T_NULL; } map.put( key, value ); } } public T put( S key, T value ) { if ( key == null ){ key = S_NULL; } if ( value == null ){ value = T_NULL; } T result = map.put( key, value ); if ( result == T_NULL ){ return( null ); }else{ return( result ); } } public T get( S key ) { if ( key == null ){ key = S_NULL; } T result = map.get( key ); if ( result == T_NULL ){ return( null ); }else{ return( result ); } } public T remove( S key ) { if ( key == null ){ key = S_NULL; } T result = map.remove( key ); if ( result == T_NULL ){ return( null ); }else{ return( result ); } } public boolean containsKey( S key ) { if ( key == null ){ key = S_NULL; } return( map.containsKey( key )); } /** * NOT MODIFIABLE * @return */ public Set<S> keySet() { Set<S> result = map.keySet(); if ( result.contains( S_NULL )){ result.remove( S_NULL ); result.add( null ); } return( Collections.unmodifiableSet( result )); } /** * Helper for config writing * @return */ public TreeMap<S,T> toTreeMap() { TreeMap<S,T> result = new TreeMap<S,T>(); for ( Map.Entry<S,T> entry: map.entrySet()){ S key = entry.getKey(); T value = entry.getValue(); if ( key == S_NULL ){ key = null; } if ( value == T_NULL ){ value = null; } result.put( key, value ); } return( result ); } }