/* * Copyright 2012 Red Hat, Inc. and/or its affiliates. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA */ package org.infinispan.util.concurrent; import org.infinispan.util.concurrent.jdk8backported.ConcurrentHashMapV8; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; /** * A factory for ConcurrentMaps. * * @author Manik Surtani * @since 5.1 */ public class ConcurrentMapFactory { private static final ConcurrentMapCreator MAP_CREATOR; private static interface ConcurrentMapCreator { <K, V> ConcurrentMap<K, V> createConcurrentMap(); <K, V> ConcurrentMap<K, V> createConcurrentMap(int initialCapacity); <K, V> ConcurrentMap<K, V> createConcurrentMap(int initialCapacity, int concurrencyLevel); <K, V> ConcurrentMap<K, V> createConcurrentMap(int initialCapacity, float loadFactor, int concurrencyLevel); } private static class JdkConcurrentMapCreator implements ConcurrentMapCreator { @Override public <K, V> ConcurrentMap<K, V> createConcurrentMap() { return new ConcurrentHashMap<K, V>(); } @Override public <K, V> ConcurrentMap<K, V> createConcurrentMap(int initialCapacity) { return new ConcurrentHashMap<K, V>(initialCapacity); } @Override public <K, V> ConcurrentMap<K, V> createConcurrentMap(int initialCapacity, int concurrencyLevel) { return new ConcurrentHashMap<K, V>(initialCapacity, 0.75f, concurrencyLevel); } @Override public <K, V> ConcurrentMap<K, V> createConcurrentMap(int initialCapacity, float loadFactor, int concurrencyLevel) { return new ConcurrentHashMap<K, V>(initialCapacity, loadFactor, concurrencyLevel); } } private static class BackportedV8ConcurrentMapCreator implements ConcurrentMapCreator { @Override public <K, V> ConcurrentMap<K, V> createConcurrentMap() { return new ConcurrentHashMapV8<K, V>(); } @Override public <K, V> ConcurrentMap<K, V> createConcurrentMap(int initialCapacity) { return new ConcurrentHashMapV8<K, V>(initialCapacity); } @Override public <K, V> ConcurrentMap<K, V> createConcurrentMap(int initialCapacity, int concurrencyLevel) { return new ConcurrentHashMapV8<K, V>(initialCapacity, 0.75f, concurrencyLevel); } @Override public <K, V> ConcurrentMap<K, V> createConcurrentMap(int initialCapacity, float loadFactor, int concurrencyLevel) { return new ConcurrentHashMapV8<K, V>(initialCapacity, loadFactor, concurrencyLevel); } } static { boolean sunIncompatibleJvm; boolean jdk8; boolean allowExperimentalMap = Boolean.getBoolean("infinispan.unsafe.allow_jdk8_chm"); try { Class.forName("com.sun.unsafe.Unsafe"); sunIncompatibleJvm = false; } catch (ClassNotFoundException e) { sunIncompatibleJvm = true; } try { Class.forName("java.util.concurrent.atomic.LongAdder"); jdk8 = true; } catch (ClassNotFoundException e) { jdk8 = false; } if (jdk8 || sunIncompatibleJvm || !allowExperimentalMap) MAP_CREATOR = new JdkConcurrentMapCreator(); else MAP_CREATOR = new BackportedV8ConcurrentMapCreator(); } public static <K, V> ConcurrentMap<K, V> makeConcurrentMap() { return MAP_CREATOR.createConcurrentMap(); } public static <K, V> ConcurrentMap<K, V> makeConcurrentMap(int initCapacity) { return MAP_CREATOR.createConcurrentMap(initCapacity); } public static <K, V> ConcurrentMap<K, V> makeConcurrentMap(int initCapacity, int concurrencyLevel) { return MAP_CREATOR.createConcurrentMap(initCapacity, concurrencyLevel); } public static <K, V> ConcurrentMap<K, V> makeConcurrentMap(int initCapacity, float loadFactor, int concurrencyLevel) { return MAP_CREATOR.createConcurrentMap(initCapacity, loadFactor, concurrencyLevel); } }