blob: 072372e5c7c683c43b50188d45e1f2acf3879301 [file] [log] [blame]
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.core.common;
import static org.graalvm.compiler.core.common.CollectionsFactory.Mode.STANDARD;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
/**
* Factory for creating collection objects used during compilation.
*/
public class CollectionsFactory {
private static final ThreadLocal<Mode> tl = new ThreadLocal<>();
public static class ModeScope implements AutoCloseable {
private final Mode previousMode;
public ModeScope(Mode previousMode) {
this.previousMode = previousMode;
}
@Override
public void close() {
tl.set(previousMode);
}
}
/**
* Constants denoting what type of collections are {@link CollectionsFactory#getMode()
* currently} returned by the factory.
*/
public enum Mode {
/**
* Denotes standard collections such as {@link HashSet} and {@link HashMap}.
*/
STANDARD,
/**
* Denotes collections that have a deterministic iteration order over their keys/entries.
*/
DETERMINISTIC_ITERATION_ORDER;
}
/**
* Gets the current mode determining the type of collection objects created by this factory.
*/
public static Mode getMode() {
Mode mode = tl.get();
return mode == null ? Mode.STANDARD : mode;
}
/**
* Updates the mode for the current thread.
*
* @return an object which when {@linkplain ModeScope#close() closed} will revert the mode of
* the current thread to the state before calling this method
*/
public static ModeScope changeMode(Mode mode) {
Mode previousMode = tl.get();
tl.set(mode);
return new ModeScope(previousMode);
}
public static <K, V> HashMap<K, V> newMap() {
return getMode() == STANDARD ? new HashMap<>() : new LinkedHashMap<>();
}
public static <K, V> HashMap<K, V> newMap(Map<K, V> m) {
return getMode() == STANDARD ? new HashMap<>(m) : new LinkedHashMap<>(m);
}
public static <K, V> HashMap<K, V> newMap(int initialCapacity) {
return getMode() == STANDARD ? new HashMap<>(initialCapacity) : new LinkedHashMap<>(initialCapacity);
}
public static <K, V> Map<K, V> newIdentityMap() {
return getMode() == STANDARD ? new IdentityHashMap<>() : new LinkedIdentityHashMap<>();
}
public static <K, V> Map<K, V> newIdentityMap(int expectedMaxSize) {
return getMode() == STANDARD ? new IdentityHashMap<>(expectedMaxSize) : new LinkedIdentityHashMap<>();
}
public static <K, V> Map<K, V> newIdentityMap(Map<K, V> m) {
return getMode() == STANDARD ? new IdentityHashMap<>(m) : new LinkedIdentityHashMap<>(m);
}
/**
* Creates a set. If the current thread is {@linkplain CollectionsFactory#getMode() using}
* {@link Mode#DETERMINISTIC_ITERATION_ORDER} collections, the returned set will have an
* iteration order determined by the order in which elements are inserted in the set.
*/
public static <E> Set<E> newSet() {
return CollectionsFactory.getMode() == Mode.STANDARD ? new HashSet<>() : new LinkedHashSet<>();
}
/**
* @see #newSet()
*/
public static <E> Set<E> newSet(Collection<? extends E> c) {
return CollectionsFactory.getMode() == Mode.STANDARD ? new HashSet<>(c) : new LinkedHashSet<>(c);
}
}