CollectionsFactory.java revision 12651:6ef01bd40ce2
144963Sjb/*
244963Sjb * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
344963Sjb * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
444963Sjb *
544963Sjb * This code is free software; you can redistribute it and/or modify it
644963Sjb * under the terms of the GNU General Public License version 2 only, as
744963Sjb * published by the Free Software Foundation.
844963Sjb *
944963Sjb * This code is distributed in the hope that it will be useful, but WITHOUT
1044963Sjb * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1144963Sjb * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1244963Sjb * version 2 for more details (a copy is included in the LICENSE file that
1344963Sjb * accompanied this code).
1444963Sjb *
1544963Sjb * You should have received a copy of the GNU General Public License version
1644963Sjb * 2 along with this work; if not, write to the Free Software Foundation,
1744963Sjb * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1844963Sjb *
1944963Sjb * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2044963Sjb * or visit www.oracle.com if you need additional information or have any
2144963Sjb * questions.
2244963Sjb */
2344963Sjbpackage org.graalvm.compiler.core.common;
2444963Sjb
2544963Sjbimport static org.graalvm.compiler.core.common.CollectionsFactory.Mode.STANDARD;
2644963Sjb
2744963Sjbimport java.util.Collection;
2844963Sjbimport java.util.HashMap;
2944963Sjbimport java.util.HashSet;
3044963Sjbimport java.util.IdentityHashMap;
3144963Sjbimport java.util.LinkedHashMap;
3250476Speterimport java.util.LinkedHashSet;
3344963Sjbimport java.util.Map;
3444963Sjbimport java.util.Set;
3544963Sjb
3644963Sjb/**
3744963Sjb * Factory for creating collection objects used during compilation.
3844963Sjb */
3944963Sjbpublic class CollectionsFactory {
4053812Salfred
4153812Salfred    private static final ThreadLocal<Mode> tl = new ThreadLocal<>();
4244963Sjb
4344963Sjb    public static class ModeScope implements AutoCloseable {
4444963Sjb        private final Mode previousMode;
4544963Sjb
4644963Sjb        public ModeScope(Mode previousMode) {
4744963Sjb            this.previousMode = previousMode;
4844963Sjb        }
4944963Sjb
5044963Sjb        @Override
5144963Sjb        public void close() {
5244963Sjb            tl.set(previousMode);
5344963Sjb        }
5444963Sjb    }
5544963Sjb
5644963Sjb    /**
5744963Sjb     * Constants denoting what type of collections are {@link CollectionsFactory#getMode()
5844963Sjb     * currently} returned by the factory.
59     */
60    public enum Mode {
61        /**
62         * Denotes standard collections such as {@link HashSet} and {@link HashMap}.
63         */
64        STANDARD,
65
66        /**
67         * Denotes collections that have a deterministic iteration order over their keys/entries.
68         */
69        DETERMINISTIC_ITERATION_ORDER;
70    }
71
72    /**
73     * Gets the current mode determining the type of collection objects created by this factory.
74     */
75    public static Mode getMode() {
76        Mode mode = tl.get();
77        return mode == null ? Mode.STANDARD : mode;
78    }
79
80    /**
81     * Updates the mode for the current thread.
82     *
83     * @return an object which when {@linkplain ModeScope#close() closed} will revert the mode of
84     *         the current thread to the state before calling this method
85     */
86    public static ModeScope changeMode(Mode mode) {
87        Mode previousMode = tl.get();
88        tl.set(mode);
89        return new ModeScope(previousMode);
90    }
91
92    public static <K, V> HashMap<K, V> newMap() {
93        return getMode() == STANDARD ? new HashMap<>() : new LinkedHashMap<>();
94    }
95
96    public static <K, V> HashMap<K, V> newMap(Map<K, V> m) {
97        return getMode() == STANDARD ? new HashMap<>(m) : new LinkedHashMap<>(m);
98    }
99
100    public static <K, V> HashMap<K, V> newMap(int initialCapacity) {
101        return getMode() == STANDARD ? new HashMap<>(initialCapacity) : new LinkedHashMap<>(initialCapacity);
102    }
103
104    public static <K, V> Map<K, V> newIdentityMap() {
105        return getMode() == STANDARD ? new IdentityHashMap<>() : new LinkedIdentityHashMap<>();
106    }
107
108    public static <K, V> Map<K, V> newIdentityMap(int expectedMaxSize) {
109        return getMode() == STANDARD ? new IdentityHashMap<>(expectedMaxSize) : new LinkedIdentityHashMap<>();
110    }
111
112    public static <K, V> Map<K, V> newIdentityMap(Map<K, V> m) {
113        return getMode() == STANDARD ? new IdentityHashMap<>(m) : new LinkedIdentityHashMap<>(m);
114    }
115
116    /**
117     * Creates a set. If the current thread is {@linkplain CollectionsFactory#getMode() using}
118     * {@link Mode#DETERMINISTIC_ITERATION_ORDER} collections, the returned set will have an
119     * iteration order determined by the order in which elements are inserted in the set.
120     */
121    public static <E> Set<E> newSet() {
122        return CollectionsFactory.getMode() == Mode.STANDARD ? new HashSet<>() : new LinkedHashSet<>();
123    }
124
125    /**
126     * @see #newSet()
127     */
128    public static <E> Set<E> newSet(Collection<? extends E> c) {
129        return CollectionsFactory.getMode() == Mode.STANDARD ? new HashSet<>(c) : new LinkedHashSet<>(c);
130    }
131
132}
133