com.facebook.buck.core.rules.resolver.impl.ActionGraphBuilderMetadataCache.java Source code

Java tutorial

Introduction

Here is the source code for com.facebook.buck.core.rules.resolver.impl.ActionGraphBuilderMetadataCache.java

Source

/*
 * Copyright 2012-present Facebook, 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.facebook.buck.core.rules.resolver.impl;

import com.facebook.buck.core.description.BaseDescription;
import com.facebook.buck.core.description.MetadataProvidingDescription;
import com.facebook.buck.core.model.BuildTarget;
import com.facebook.buck.core.model.targetgraph.TargetGraph;
import com.facebook.buck.core.model.targetgraph.TargetNode;
import com.facebook.buck.core.rules.ActionGraphBuilder;
import com.facebook.buck.util.types.Pair;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import java.util.Optional;
import java.util.concurrent.ExecutionException;

/** Implementation of the metadata system for ActionGraphBuilders. */
final class ActionGraphBuilderMetadataCache {
    private final ActionGraphBuilder graphBuilder;
    private final TargetGraph targetGraph;
    private final LoadingCache<Pair<BuildTarget, Class<?>>, Optional<?>> metadataCache;

    ActionGraphBuilderMetadataCache(ActionGraphBuilder graphBuilder, TargetGraph targetGraph, int initialCapacity) {
        // Precondition (not checked): graphBuilder has the same targetGraph as the one passed in
        this.graphBuilder = graphBuilder;
        this.targetGraph = targetGraph;
        this.metadataCache = CacheBuilder.newBuilder().initialCapacity(initialCapacity)
                .build(new MetadataCacheLoader());
    }

    @SuppressWarnings("unchecked")
    <T> Optional<T> requireMetadata(BuildTarget target, Class<T> metadataClass) {
        try {
            return (Optional<T>) metadataCache.get(new Pair<>(target, metadataClass));
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
    }

    private final class MetadataCacheLoader extends CacheLoader<Pair<BuildTarget, Class<?>>, Optional<?>> {
        @Override
        public Optional<?> load(Pair<BuildTarget, Class<?>> key) {
            TargetNode<?> node = targetGraph.get(key.getFirst());
            return load(node, key.getSecond());
        }

        @SuppressWarnings("unchecked")
        private <T, U> Optional<U> load(TargetNode<T> node, Class<U> metadataClass) {
            T arg = node.getConstructorArg();
            if (metadataClass.isAssignableFrom(arg.getClass())) {
                return Optional.of(metadataClass.cast(arg));
            }

            BaseDescription<?> description = node.getDescription();
            if (!(description instanceof MetadataProvidingDescription)) {
                return Optional.empty();
            }
            MetadataProvidingDescription<T> metadataProvidingDescription = (MetadataProvidingDescription<T>) description;
            return metadataProvidingDescription.createMetadata(node.getBuildTarget(), graphBuilder,
                    node.getCellNames(), arg, node.getSelectedVersions(), metadataClass);
        }
    }
}