package org.rhq.enterprise.server.resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.resource.composite.ResourceFacets;
/**
* @author Joseph Marques
*/
public class ResourceFacetsCache {
private final Log log = LogFactory.getLog(ResourceFacetsCache.class);
/*
* Do not need concurrent collections as long as the cache does not take direct modifications. The algorithm below
* is lockless because when the cache needs to be reloaded the collection is fully constructed BEFORE replacing the
* reference to the private member variable. In this way, the private member variable become a true read-only
* construct. Furthermore, concurrent access to the contents of the cache is safe because the ResourceFacets object
* is immutable.
*/
private Map<Integer, ResourceFacets> cache;
private static ResourceFacetsCache singleton = new ResourceFacetsCache();
private ResourceFacetsCache() {
cache = new HashMap<Integer, ResourceFacets>();
}
public static ResourceFacetsCache getSingleton() {
return singleton;
}
public ResourceFacets getResourceFacets(int resourceTypeId) {
/*
* concurrent access is safe because we're accessing an (effectively) read-only cache object whose contents
* are composed solely of immutable objects
*/
return cache.get(resourceTypeId);
}
public void reload(List<ResourceFacets> facets) {
try {
Map<Integer, ResourceFacets> reloadedFacets;
reloadedFacets = new HashMap<Integer, ResourceFacets>();
for (ResourceFacets facet : facets) {
reloadedFacets.put(facet.getResourceTypeId(), facet);
}
cache = reloadedFacets;
} catch (Throwable t) {
log.error("Could not reload ResourceFacets cache", t);
}
}
}