com.hazelcast.org.apache.calcite.rel.metadata.CachingRelMetadataProvider Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you 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.hazelcast.org.apache.calcite.rel.metadata;
import com.hazelcast.org.apache.calcite.plan.RelOptPlanner;
import com.hazelcast.org.apache.calcite.rel.RelNode;
import com.hazelcast.com.google.common.collect.ImmutableList;
import com.hazelcast.com.google.common.collect.Multimap;
import com.hazelcast.org.checkerframework.checker.nullness.qual.Nullable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.hazelcast.org.apache.calcite.linq4j.Nullness.castNonNull;
import static java.util.Objects.requireNonNull;
/**
* Implementation of the {@link RelMetadataProvider}
* interface that caches results from an underlying provider.
*/
@Deprecated // to be removed before 2.0
public class CachingRelMetadataProvider implements RelMetadataProvider {
//~ Instance fields --------------------------------------------------------
private final Map cache = new HashMap<>();
private final RelMetadataProvider underlyingProvider;
private final RelOptPlanner planner;
//~ Constructors -----------------------------------------------------------
public CachingRelMetadataProvider(
RelMetadataProvider underlyingProvider,
RelOptPlanner planner) {
this.underlyingProvider = underlyingProvider;
this.planner = planner;
}
//~ Methods ----------------------------------------------------------------
@Deprecated // to be removed before 2.0
@Override public <@Nullable M extends @Nullable Metadata> @Nullable UnboundMetadata apply(
Class extends RelNode> relClass,
final Class extends M> metadataClass) {
final UnboundMetadata function =
underlyingProvider.apply(relClass, metadataClass);
if (function == null) {
return null;
}
// TODO jvs 30-Mar-2006: Use meta-metadata to decide which metadata
// query results can stay fresh until the next Ice Age.
return (rel, mq) -> {
final Metadata metadata = requireNonNull(function.bind(rel, mq),
() -> "metadata must not be null, relClass=" + relClass
+ ", metadataClass=" + metadataClass);
return metadataClass.cast(
Proxy.newProxyInstance(metadataClass.getClassLoader(),
new Class[]{metadataClass},
new CachingInvocationHandler(metadata)));
};
}
@Deprecated // to be removed before 2.0
@Override public Multimap> handlers(
MetadataDef def) {
return underlyingProvider.handlers(def);
}
@Override public List> handlers(
Class extends MetadataHandler>> handlerClass) {
return underlyingProvider.handlers(handlerClass);
}
//~ Inner Classes ----------------------------------------------------------
/** An entry in the cache. Consists of the cached object and the timestamp
* when the entry is valid. If read at a later timestamp, the entry will be
* invalid and will be re-computed as if it did not exist. The net effect is a
* lazy-flushing cache. */
private static class CacheEntry {
long timestamp;
@Nullable Object result;
}
/** Implementation of {@link InvocationHandler} for calls to a
* {@link CachingRelMetadataProvider}. Each request first looks in the cache;
* if the cache entry is present and not expired, returns the cache entry,
* otherwise computes the value and stores in the cache. */
private class CachingInvocationHandler implements InvocationHandler {
private final Metadata metadata;
CachingInvocationHandler(Metadata metadata) {
this.metadata = requireNonNull(metadata, "metadata");
}
@Override public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
// Compute hash key.
final ImmutableList.Builder
© 2015 - 2024 Weber Informatics LLC | Privacy Policy