/* * Copyright (c) 2014, the Dart project authors. * * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html * * 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.dart.engine.internal.index.file; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.util.concurrent.Uninterruptibles; import com.google.dart.engine.context.AnalysisContext; import java.util.concurrent.TimeUnit; /** * A {@link NodeManager} that caches {@link IndexNode} accessed from another {@link NodeManager}. * <p> * By default up to 64 nodes are cached for 5 seconds. * * @coverage dart.engine.index */ public class CachingNodeManager implements NodeManager { /** * A {@link Thread} that performs {@link #cache} clean up. */ private class CleanUpThread extends Thread { public CleanUpThread() { super("IndexNode cache clean up thread"); setDaemon(true); } @Override public void run() { while (true) { cache.cleanUp(); Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); } } } private final NodeManager manager; private final Cache<String, IndexNode> cache; public CachingNodeManager(NodeManager manager) { this.manager = manager; { CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder(); cache = builder.maximumSize(64).expireAfterAccess(5, TimeUnit.SECONDS).build(); } new CleanUpThread().start(); } @Override public void clear() { manager.clear(); cache.invalidateAll(); } @Override public ContextCodec getContextCodec() { return manager.getContextCodec(); } @Override public ElementCodec getElementCodec() { return manager.getElementCodec(); } @Override public int getLocationCount() { return manager.getLocationCount(); } @Override public IndexNode getNode(String name) { IndexNode node = cache.getIfPresent(name); if (node == null) { node = manager.getNode(name); if (node != null) { cache.put(name, node); } } return node; } @Override public StringCodec getStringCodec() { return manager.getStringCodec(); } @Override public IndexNode newNode(AnalysisContext context) { return manager.newNode(context); } @Override public void putNode(String name, IndexNode node) { cache.put(name, node); manager.putNode(name, node); } @Override public void removeNode(String name) { cache.invalidate(name); manager.removeNode(name); } }