| /* |
| * 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 org.apache.calcite.util.mapping; |
| |
| /** |
| * Describes the type of a mapping, from the most general |
| * {@link #MULTI_FUNCTION} (every element in the source and target domain can |
| * participate in many mappings) to the most restricted {@link #BIJECTION} (every |
| * element in the source and target domain must be paired with precisely one |
| * element in the other domain). |
| * |
| * <p>Some common types: |
| * |
| * <ul> |
| * <li>A surjection is a mapping if every target has at least one source; also |
| * known as an 'onto' mapping. |
| * <li>A mapping is a partial function if every source has at most one target. |
| * <li>A mapping is a function if every source has precisely one target. |
| * <li>An injection is a mapping where a target has at most one source; also |
| * somewhat confusingly known as a 'one-to-one' mapping. |
| * <li>A bijection is a mapping which is both an injection and a surjection. |
| * Every source has precisely one target, and vice versa. |
| * </ul> |
| * |
| * <p>Once you know what type of mapping you want, call |
| * {@link Mappings#create(MappingType, int, int)} to create an efficient |
| * implementation of that mapping. |
| */ |
| public enum MappingType { |
| // ordinal source target function inverse |
| // ======= ====== ====== ======== ================= |
| |
| // 0 1 1 true 0 Bijection |
| BIJECTION, |
| |
| // 1 <= 1 1 true 4 InverseSurjection |
| SURJECTION, |
| |
| // 2 >= 1 1 true 8 InverseInjection |
| INJECTION, |
| |
| // 3 any 1 true 12 InverseFunction |
| FUNCTION, |
| |
| /** |
| * An inverse surjection has a source for every target, and no source has |
| * more than one target. |
| */ |
| // 4 1 <= 1 partial 1 Surjection |
| INVERSE_SURJECTION, |
| |
| /** |
| * A partial surjection has no more than one source for any target, and no |
| * more than one target for any source. |
| */ |
| // 5 <= 1 <= 1 partial 5 PartialSurjection |
| PARTIAL_SURJECTION, |
| |
| // 6 >= 1 <= 1 partial 9 InversePartialInjection |
| PARTIAL_INJECTION, |
| |
| // 7 any <= 1 partial 13 InversePartialFunction |
| PARTIAL_FUNCTION, |
| |
| // 8 1 >= 1 multi 2 Injection |
| INVERSE_INJECTION, |
| |
| // 9 <= 1 >= 1 multi 6 PartialInjection |
| INVERSE_PARTIAL_INJECTION, |
| |
| // 10 >= 1 >= 1 multi 10 |
| TEN, |
| |
| // 11 any >= 1 multi 14 |
| ELEVEN, |
| |
| /** |
| * An inverse function has a source for every target, but a source might |
| * have 0, 1 or more targets. |
| * |
| * <p>Obeys the constraints {@link MappingType#isMandatorySource()}, |
| * {@link MappingType#isSingleSource()}. |
| * |
| * <p>Similar types: |
| * |
| * <ul> |
| * <li> {@link #INVERSE_SURJECTION} is stronger (a source may not have |
| * multiple targets); |
| * <li>{@link #INVERSE_PARTIAL_FUNCTION} is weaker (a target may have 0 or 1 |
| * sources). |
| * </ul> |
| */ |
| // 12 1 any multi 3 Function |
| INVERSE_FUNCTION, |
| |
| // 13 <= 1 any multi 7 PartialFunction |
| INVERSE_PARTIAL_FUNCTION, |
| |
| // 14 >= 1 any multi 11 |
| FOURTEEN, |
| |
| // 15 any any multi 15 MultiFunction |
| MULTI_FUNCTION; |
| |
| private final int inverseOrdinal; |
| |
| MappingType() { |
| this.inverseOrdinal = ((ordinal() & 3) << 2) |
| | ((ordinal() & 12) >> 2); |
| } |
| |
| public MappingType inverse() { |
| return MappingType.values()[this.inverseOrdinal]; |
| } |
| |
| /** |
| * Returns whether this mapping type is (possibly a weaker form of) a given |
| * mapping type. |
| * |
| * <p>For example, a {@link #BIJECTION} is a {@link #FUNCTION}, but not |
| * every {link #Function} is a {@link #BIJECTION}. |
| */ |
| public boolean isA(MappingType mappingType) { |
| return (ordinal() & mappingType.ordinal()) == ordinal(); |
| } |
| |
| /** |
| * A mapping is a total function if every source has precisely one target. |
| */ |
| public boolean isFunction() { |
| return (ordinal() & (OPTIONAL_TARGET | MULTIPLE_TARGET)) == 0; |
| } |
| |
| /** |
| * A mapping is a partial function if every source has at most one target. |
| */ |
| public boolean isPartialFunction() { |
| return (ordinal() & MULTIPLE_TARGET) == 0; |
| } |
| |
| /** |
| * A mapping is a surjection if it is a function and every target has at |
| * least one source. |
| */ |
| public boolean isSurjection() { |
| return (ordinal() & (OPTIONAL_TARGET | MULTIPLE_TARGET | OPTIONAL_SOURCE)) |
| == 0; |
| } |
| |
| /** |
| * A mapping is an injection if it is a function and no target has more than |
| * one source. (In other words, every source has precisely one target.) |
| */ |
| public boolean isInjection() { |
| return (ordinal() & (OPTIONAL_TARGET | MULTIPLE_TARGET | MULTIPLE_SOURCE)) |
| == 0; |
| } |
| |
| /** |
| * A mapping is a bijection if it is a surjection and it is an injection. |
| * (In other words, |
| */ |
| public boolean isBijection() { |
| return (ordinal() |
| & (OPTIONAL_TARGET | MULTIPLE_TARGET | OPTIONAL_SOURCE |
| | MULTIPLE_SOURCE)) == 0; |
| } |
| |
| /** |
| * Constraint that every source has at least one target. |
| */ |
| public boolean isMandatoryTarget() { |
| return !((ordinal() & OPTIONAL_TARGET) == OPTIONAL_TARGET); |
| } |
| |
| /** |
| * Constraint that every source has at most one target. |
| */ |
| public boolean isSingleTarget() { |
| return !((ordinal() & MULTIPLE_TARGET) == MULTIPLE_TARGET); |
| } |
| |
| /** |
| * Constraint that every target has at least one source. |
| */ |
| public boolean isMandatorySource() { |
| return !((ordinal() & OPTIONAL_SOURCE) == OPTIONAL_SOURCE); |
| } |
| |
| /** |
| * Constraint that every target has at most one source. |
| */ |
| public boolean isSingleSource() { |
| return !((ordinal() & MULTIPLE_SOURCE) == MULTIPLE_SOURCE); |
| } |
| |
| /** |
| * Allow less than one source for a given target. |
| */ |
| private static final int OPTIONAL_SOURCE = 1; |
| |
| /** |
| * Allow more than one source for a given target. |
| */ |
| private static final int MULTIPLE_SOURCE = 2; |
| |
| /** |
| * Allow less than one target for a given source. |
| */ |
| private static final int OPTIONAL_TARGET = 4; |
| |
| /** |
| * Allow more than one target for a given source. |
| */ |
| private static final int MULTIPLE_TARGET = 8; |
| } |