/* * Copyright 2011 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.google.gwt.dev.javac; import com.google.gwt.core.ext.TreeLogger; import com.google.gwt.core.ext.UnableToCompleteException; import com.google.gwt.dev.javac.MemoryUnitCache.UnitCacheEntry; import com.google.gwt.thirdparty.guava.common.collect.Maps; import java.util.Map; /** * This cache stores {@link CompilationUnit} instances in a Map. * * Only one unit is cached per resource path. If the contentId of the unit * changes, the old unit is discarded and replaced with the new unit. */ public class MemoryUnitCache implements UnitCache { /** * Storage for a compilation unit in the map. */ protected static class UnitCacheEntry { private final UnitOrigin origin; private final CompilationUnit unit; protected UnitCacheEntry(CompilationUnit unit, UnitOrigin source) { this.unit = unit; this.origin = source; } public UnitOrigin getOrigin() { return origin; } public CompilationUnit getUnit() { return unit; } } /** * Track how the unit was loaded. Useful in {@link PersistentUnitCache} for * consolidating old cache files. * */ protected static enum UnitOrigin { /** * Unit was loaded from persistent store. */ PERSISTENT, /** * Unit was introduced by an add due to a run-time compile. */ RUN_TIME } /** * References to all {@link CompilationUnit} objects loaded from the * persistent store, and any new ones added to the store as well. * * The key is resource path. */ protected final Map<String, UnitCacheEntry> unitMap = Maps.newHashMap(); /** * References {@link CompilationUnit} objects by {@link ContentId}, which is * composed of the type name and a hash on the source code contents. */ protected final Map<ContentId, UnitCacheEntry> unitMapByContentId = Maps.newHashMap(); /** * Adds a new entry into the cache. */ @Override public void add(CompilationUnit newUnit) { UnitCacheEntry newEntry = new UnitCacheEntry(newUnit, UnitOrigin.RUN_TIME); String resourcePath = newUnit.getResourcePath(); UnitCacheEntry oldEntry = unitMap.get(resourcePath); if (oldEntry != null) { remove(oldEntry.getUnit()); } unitMap.put(resourcePath, newEntry); unitMapByContentId.put(newUnit.getContentId(), newEntry); } /** * This method is a no-op for an in-memory cache. */ @Override public synchronized void cleanup(final TreeLogger logger) { // do nothing. } @Override public void clear() throws UnableToCompleteException { unitMap.clear(); unitMapByContentId.clear(); } @Override public CompilationUnit find(ContentId contentId) { UnitCacheEntry entry = unitMapByContentId.get(contentId); if (entry != null) { return entry.getUnit(); } return null; } @Override public CompilationUnit find(String resourcePath) { UnitCacheEntry entry = unitMap.get(resourcePath); if (entry != null) { return entry.getUnit(); } return null; } @Override public void remove(CompilationUnit unit) { unitMap.remove(unit.getResourcePath()); unitMapByContentId.remove(unit.getContentId()); } }