/******************************************************************************* * Copyright (c) 2012 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributor: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.util; import java.util.Hashtable; import java.util.Iterator; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; /** * * Even a huge workspace contains much less than 100000 paths, whereas even in a middle * workspace with about 10000 paths as much as 250000 instances of Path are kept in various * caches. * * @author Viacheslav Kabanovich * */ public class UniquePaths { static UniquePaths instance = new UniquePaths(); public static UniquePaths getInstance() { return instance; } Hashtable<IPath, IPath> paths = new Hashtable<IPath, IPath>(); private UniquePaths() {} /** * IResource.getFullPath() and IResource.getLocation() return new object * at each invocation. All clients that need storing resource paths, * may obtain the single instance stored by this class. * This significantly decreases the number of stored objects. * * @param path object returned by IResource.getFullPath() or IResource.getLocation() * @return unique object equal to the given path. */ public synchronized IPath intern(IPath path) { IPath result = paths.get(path); if(result == null) { paths.put(path, path); result = path; } return result; } /** * When a resource is removed from workspace, the cash of stored * paths should be cleaned from obsolete elements. * * @param removed */ public synchronized void clean(IResource removed) { IPath fullPath = removed.getFullPath(); IPath location = removed.getLocation(); Iterator<IPath> it = paths.keySet().iterator(); while(it.hasNext()) { IPath p = it.next(); if(fullPath.isPrefixOf(p)) { it.remove(); } else if(location != null && location.isPrefixOf(p)) { it.remove(); } } } }