1015N/A/*
1015N/A * CDDL HEADER START
1015N/A *
1015N/A * The contents of this file are subject to the terms of the
1015N/A * Common Development and Distribution License (the "License").
1015N/A * You may not use this file except in compliance with the License.
1015N/A *
1015N/A * See LICENSE.txt included in this distribution for the specific
1015N/A * language governing permissions and limitations under the License.
1015N/A *
1015N/A * When distributing Covered Code, include this CDDL HEADER in each
1015N/A * file and include the License file at LICENSE.txt.
1015N/A * If applicable, add the following below this CDDL HEADER, with the
1015N/A * fields enclosed by brackets "[]" replaced with your own identifying
1015N/A * information: Portions Copyright [yyyy] [name of copyright owner]
1015N/A *
1015N/A * CDDL HEADER END
1015N/A */
1015N/A
1015N/A/*
1015N/A * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
1015N/A * Use is subject to license terms.
1015N/A */
1015N/A
1015N/Apackage org.opensolaris.opengrok.util;
1015N/A
1015N/Aimport java.util.HashMap;
1019N/Aimport java.util.Map;
1015N/A
1015N/A/**
1015N/A * <p>
1015N/A * Helper class that interns objects, that is, returns a canonical
1015N/A * representation of the objects. This works similar to
1015N/A * {@link java.lang.String#intern}, but it stores the canonical objects on
1015N/A * the heap instead of in the permgen space to address bug #15956.
1015N/A * </p>
1015N/A *
1015N/A * <p>
1015N/A * Instances of this class are not thread safe.
1015N/A * </p>
1015N/A *
1015N/A * <p>
1015N/A * In contrast to {@link java.lang.String#intern}, this class does not attempt
1015N/A * to make objects that are not referenced anymore eligible for garbage
1015N/A * collection. Hence, references to instances of this class should not be
1015N/A * held longer than necessary.
1015N/A * </p>
1015N/A *
1015N/A * @param <T> the type of the objects being interned by the instance
1015N/A */
1015N/Apublic class Interner<T> {
1015N/A
1015N/A /** Map of interned objects. Key and value contain the same object. */
1019N/A private final Map<T, T> map = new HashMap<T, T>();
1015N/A
1015N/A /**
1015N/A * <p>
1015N/A * Intern an object and return a canonical instance of it. For two objects
1015N/A * {@code o1} and {@code o2}, the following always evaluates to
1015N/A * {@code true}:
1015N/A * </p>
1015N/A *
1015N/A * <pre>
1015N/A * ( o1 == null ) ?
1015N/A * ( intern(o1) == null ) :
1015N/A * o1.equals(o2) == ( intern(o1) == intern(o2) )
1015N/A * </pre>
1015N/A *
1015N/A * @param instance the object to intern
1015N/A * @return a canonical representation of {@code instance}
1015N/A */
1015N/A public T intern(T instance) {
1015N/A if (instance == null) {
1015N/A return null;
1015N/A }
1015N/A
1015N/A T interned = map.get(instance);
1015N/A
1015N/A if (interned == null) {
1015N/A interned = instance;
1015N/A map.put(interned, interned);
1015N/A }
1015N/A
1015N/A return interned;
1015N/A }
1015N/A}