kafka Versions 源码

  • 2022-10-20
  • 浏览 (228)

kafka Versions 代码

文件路径:/generator/src/main/java/org/apache/kafka/message/Versions.java

/*
 * 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.kafka.message;

import java.util.Objects;

/**
 * A version range.
 *
 * A range consists of two 16-bit numbers: the lowest version which is accepted, and the highest.
 * Ranges are inclusive, meaning that both the lowest and the highest version are valid versions.
 * The only exception to this is the NONE range, which contains no versions at all.
 *
 * Version ranges can be represented as strings.
 *
 * A single supported version V is represented as "V".
 * A bounded range from A to B is represented as "A-B".
 * All versions greater than A is represented as "A+".
 * The NONE range is represented as an the string "none".
 */
public final class Versions {
    private final short lowest;
    private final short highest;

    public static Versions parse(String input, Versions defaultVersions) {
        if (input == null) {
            return defaultVersions;
        }
        String trimmedInput = input.trim();
        if (trimmedInput.length() == 0) {
            return defaultVersions;
        }
        if (trimmedInput.equals(NONE_STRING)) {
            return NONE;
        }
        if (trimmedInput.endsWith("+")) {
            return new Versions(Short.parseShort(
            trimmedInput.substring(0, trimmedInput.length() - 1)),
                Short.MAX_VALUE);
        } else {
            int dashIndex = trimmedInput.indexOf("-");
            if (dashIndex < 0) {
                short version = Short.parseShort(trimmedInput);
                return new Versions(version, version);
            }
            return new Versions(
                Short.parseShort(trimmedInput.substring(0, dashIndex)),
                Short.parseShort(trimmedInput.substring(dashIndex + 1)));
        }
    }

    public static final Versions ALL = new Versions((short) 0, Short.MAX_VALUE);

    public static final Versions NONE = new Versions();

    public static final String NONE_STRING = "none";

    private Versions() {
        this.lowest = 0;
        this.highest = -1;
    }

    public Versions(short lowest, short highest) {
        if ((lowest < 0) || (highest < 0)) {
            throw new RuntimeException("Invalid version range " +
                lowest + " to " + highest);
        }
        this.lowest = lowest;
        this.highest = highest;
    }

    public short lowest() {
        return lowest;
    }

    public short highest() {
        return highest;
    }

    public boolean empty() {
        return lowest > highest;
    }

    @Override
    public String toString() {
        if (empty()) {
            return NONE_STRING;
        } else if (lowest == highest) {
            return String.valueOf(lowest);
        } else if (highest == Short.MAX_VALUE) {
            return String.format("%d+", lowest);
        } else {
            return String.format("%d-%d", lowest, highest);
        }
    }

    /**
     * Return the intersection of two version ranges.
     *
     * @param other     The other version range.
     * @return          A new version range.
     */
    public Versions intersect(Versions other) {
        short newLowest = lowest > other.lowest ? lowest : other.lowest;
        short newHighest = highest < other.highest ? highest : other.highest;
        if (newLowest > newHighest) {
            return Versions.NONE;
        }
        return new Versions(newLowest, newHighest);
    }

    /**
     * Return a new version range that trims some versions from this range, if possible.
     * We can't trim any versions if the resulting range would be disjoint.
     *
     * Some examples:
     * 1-4.trim(1-2) = 3-4
     * 3+.trim(4+) = 3
     * 4+.trim(3+) = none
     * 1-5.trim(2-4) = null
     *
     * @param other                 The other version range.
     * @return                      A new version range.
     */
    public Versions subtract(Versions other) {
        if (other.lowest() <= lowest) {
            if (other.highest >= highest) {
                // Case 1: other is a superset of this.  Trim everything.
                return Versions.NONE;
            } else if (other.highest < lowest) {
                // Case 2: other is a disjoint version range that is lower than this.  Trim nothing.
                return this;
            } else {
                // Case 3: trim some values from the beginning of this range.
                //
                // Note: it is safe to assume that other.highest() + 1 will not overflow.
                // The reason is because if other.highest() were Short.MAX_VALUE,
                // other.highest() < highest could not be true.
                return new Versions((short) (other.highest() + 1), highest);
            }
        } else if (other.highest >= highest) {
            int newHighest = other.lowest - 1;
            if (newHighest < 0) {
                // Case 4: other was NONE.  Trim nothing.
                return this;
            } else if (newHighest < highest) {
                // Case 5: trim some values from the end of this range.
                return new Versions(lowest, (short) newHighest);
            } else {
                // Case 6: other is a disjoint range that is higher than this.  Trim nothing.
                return this;
            }
        } else {
            // Case 7: the difference between this and other would be two ranges, not one.
            return null;
        }
    }

    public boolean contains(short version) {
        return version >= lowest && version <= highest;
    }

    public boolean contains(Versions other) {
        if (other.empty()) {
            return true;
        }
        return !((lowest > other.lowest) || (highest < other.highest));
    }

    @Override
    public int hashCode() {
        return Objects.hash(lowest, highest);
    }

    @Override
    public boolean equals(Object other) {
        if (!(other instanceof Versions)) {
            return false;
        }
        Versions otherVersions = (Versions) other;
        return lowest == otherVersions.lowest &&
               highest == otherVersions.highest;
    }
}

相关信息

kafka 源码目录

相关文章

kafka ApiMessageTypeGenerator 源码

kafka ClauseGenerator 源码

kafka CodeBuffer 源码

kafka EntityType 源码

kafka FieldSpec 源码

kafka FieldType 源码

kafka HeaderGenerator 源码

kafka IsNullConditional 源码

kafka JsonConverterGenerator 源码

kafka MessageClassGenerator 源码

0  赞