/******************************************************************************* * Copyright (c) 2016 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 * * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.openshift.internal.ui.models; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; import org.jboss.tools.openshift.internal.core.Trace; import com.openshift.restclient.model.IResource; class ResourceCache { private Map<String, Map<String, IResource>> cache = new HashMap<String, Map<String, IResource>>(); public void dispose() { flush(); } public void flush() { synchronized (cache) { cache.clear(); } } public void flush(String namespace) { synchronized (cache) { cache.remove(namespace); } } /** * Key for caching an object * * @param resource * @return */ private String getCacheKey(IResource resource) { return getCacheKey(resource.getKind(), resource.getName()); } private String getCacheKey(String kind, String name) { return kind+"/"+name; } @SuppressWarnings("unchecked") public <T extends IResource> T getResource(String namespace, String kind, String name) { synchronized (cache) { Map<String, IResource> projectResources = cache.get(namespace); if (projectResources != null) { return (T) projectResources.get(getCacheKey(kind, name)); } return null; } } @SuppressWarnings("unchecked") public <T extends IResource> Collection<T> getResources(String namespace, String kind) { synchronized (cache) { Map<String, IResource> projectResources = cache.get(namespace); if (projectResources != null) { return projectResources.values().stream().filter(r -> kind.equals(r.getKind())).map(r -> (T) r) .collect(Collectors.toList()); } return Collections.emptyList(); } } @SuppressWarnings("unchecked") public <T extends IResource> Collection<T> getResources(String namespace) { synchronized (cache) { Map<String, IResource> projectResources = cache.get(namespace); if (projectResources != null) { return new ArrayList<T>((Collection<T>) projectResources.values()); } return Collections.emptyList(); } } /** * * @param resource * @return true if cached; false otherwise */ public boolean add(IResource resource) { if (resource == null) return false; synchronized (cache) { if (getCachedVersion(resource) != null) { Trace.debug("-->Returning early since already processed {0}", resource); return false; } putIntoCache(resource); } return true; } private void removeFromCache(IResource resource) { Map<String, IResource> projectResources = cache.get(getNamespace(resource)); if (projectResources != null) { projectResources.remove(getCacheKey(resource)); if (projectResources.isEmpty()) { cache.remove(getNamespace(resource)); } } } private void putIntoCache(IResource resource) { Map<String, IResource> projectResources = cache.get(getNamespace(resource)); if (projectResources == null) { projectResources = new HashMap<String, IResource>(); cache.put(getNamespace(resource), projectResources); } projectResources.put(getCacheKey(resource), resource); } public String getNamespace(IResource resource) { return resource.getNamespace(); } public IResource getCachedVersion(IResource resource) { return getResource(getNamespace(resource), resource.getKind(), resource.getName()); } /** * * @param resource * @return true if removed; false otherwise */ public boolean remove(IResource resource) { if (resource == null) return false; synchronized (cache) { removeFromCache(resource); } return true; } /** * * @param resource * @return true if updated; false otherwise */ public boolean update(IResource resource) { if (resource == null) return false; synchronized (cache) { if (isUpToDate(resource)) { Trace.debug("-->Returning early since already have this change: {0}", resource); return false; } putIntoCache(resource); } return true; } public boolean isUpToDate(IResource resource) { IResource cachedVersion = getCachedVersion(resource); return cachedVersion != null && Integer.parseInt(cachedVersion.getResourceVersion()) >= Integer .parseInt(resource.getResourceVersion()); } }