All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.org.apache.calcite.rel.hint.RelHint 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.hint;

import com.hazelcast.com.google.common.base.Preconditions;
import com.hazelcast.com.google.common.collect.ImmutableList;
import com.hazelcast.com.google.common.collect.ImmutableMap;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.annotation.Nullable;

/**
 * Represents hint within a relation expression.
 *
 * 

Every hint has a {@code inheritPath} (integers list) which records its propagate path * from the root node, * number `0` represents the hint is propagated from the first(left) child, * number `1` represents the hint is propagated from the second(right) child. * *

Given a relational expression tree with initial attached hints: * *

 *            Filter (Hint1)
 *                |
 *               Join
 *              /    \
 *            Scan  Project (Hint2)
 *                     |
 *                    Scan2
 * 
* *

The plan would have hints path as follows * (assumes each hint can be propagated to all child nodes): *

    *
  • Filter would have hints {Hint1[]}
  • *
  • Join would have hints {Hint1[0]}
  • *
  • Scan would have hints {Hint1[0, 0]}
  • *
  • Project would have hints {Hint1[0,1], Hint2[]}
  • *
  • Scan2 would have hints {[Hint1[0, 1, 0], Hint2[0]}
  • *
* *

The {@code listOptions} and {@code kvOptions} are supposed to contain the same information, * they are mutually exclusive, that means, they can not both be non-empty. * *

The RelHint is immutable. */ public class RelHint { //~ Instance fields -------------------------------------------------------- public final ImmutableList inheritPath; public final String hintName; public final List listOptions; public final Map kvOptions; //~ Constructors ----------------------------------------------------------- /** * Creates a {@code RelHint}. * * @param inheritPath Hint inherit path * @param hintName Hint name * @param listOption Hint options as string list * @param kvOptions Hint options as string key value pair */ private RelHint( Iterable inheritPath, String hintName, @Nullable List listOption, @Nullable Map kvOptions) { Objects.requireNonNull(inheritPath); Objects.requireNonNull(hintName); this.inheritPath = ImmutableList.copyOf(inheritPath); this.hintName = hintName; this.listOptions = listOption == null ? ImmutableList.of() : ImmutableList.copyOf(listOption); this.kvOptions = kvOptions == null ? ImmutableMap.of() : ImmutableMap.copyOf(kvOptions); } //~ Methods ---------------------------------------------------------------- /** Creates a hint builder with specified hint name. */ public static Builder builder(String hintName) { return new Builder(hintName); } /** * Returns a copy of this hint with specified inherit path. * * @param inheritPath Hint path * @return the new {@code RelHint} */ public RelHint copy(List inheritPath) { Objects.requireNonNull(inheritPath); return new RelHint(inheritPath, hintName, listOptions, kvOptions); } @Override public boolean equals(Object obj) { if (!(obj instanceof RelHint)) { return false; } final RelHint that = (RelHint) obj; return this.hintName.equals(that.hintName) && this.inheritPath.equals(that.inheritPath) && Objects.equals(this.listOptions, that.listOptions) && Objects.equals(this.kvOptions, that.kvOptions); } @Override public int hashCode() { return Objects.hash(this.hintName, this.inheritPath, this.listOptions, this.kvOptions); } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("[") .append(this.hintName) .append(" inheritPath:") .append(this.inheritPath); if (this.listOptions.size() > 0 || this.kvOptions.size() > 0) { builder.append(" options:"); if (this.listOptions.size() > 0) { builder.append(this.listOptions.toString()); } else { builder.append(this.kvOptions.toString()); } } builder.append("]"); return builder.toString(); } //~ Inner Class ------------------------------------------------------------ /** Builder for {@link RelHint}. */ public static class Builder { private String hintName; private List inheritPath; private List listOptions; private Map kvOptions; private Builder(String hintName) { this.listOptions = new ArrayList<>(); this.kvOptions = new LinkedHashMap<>(); this.hintName = hintName; this.inheritPath = ImmutableList.of(); } /** Sets up the inherit path with given integer list. */ public Builder inheritPath(Iterable inheritPath) { this.inheritPath = ImmutableList.copyOf(Objects.requireNonNull(inheritPath)); return this; } /** Sets up the inherit path with given integer array. */ public Builder inheritPath(Integer... inheritPath) { this.inheritPath = Arrays.asList(inheritPath); return this; } /** Add a hint option as string. */ public Builder hintOption(String hintOption) { Objects.requireNonNull(hintOption); Preconditions.checkState(this.kvOptions.size() == 0, "List options and key value options can not be mixed in"); this.listOptions.add(hintOption); return this; } /** Add multiple string hint options. */ public Builder hintOptions(Iterable hintOptions) { Objects.requireNonNull(hintOptions); Preconditions.checkState(this.kvOptions.size() == 0, "List options and key value options can not be mixed in"); this.listOptions = ImmutableList.copyOf(hintOptions); return this; } /** Add a hint option as string key-value pair. */ public Builder hintOption(String optionKey, String optionValue) { Objects.requireNonNull(optionKey); Objects.requireNonNull(optionValue); Preconditions.checkState(this.listOptions.size() == 0, "List options and key value options can not be mixed in"); this.kvOptions.put(optionKey, optionValue); return this; } /** Add multiple string key-value pair hint options. */ public Builder hintOptions(Map kvOptions) { Objects.requireNonNull(kvOptions); Preconditions.checkState(this.listOptions.size() == 0, "List options and key value options can not be mixed in"); this.kvOptions = kvOptions; return this; } public RelHint build() { return new RelHint(this.inheritPath, this.hintName, this.listOptions, this.kvOptions); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy