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