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

io.lettuce.core.Range Maven / Gradle / Ivy

Go to download

Advanced and thread-safe Java Redis client for synchronous, asynchronous, and reactive usage. Supports Cluster, Sentinel, Pipelining, Auto-Reconnect, Codecs and much more.

The newest version!
package io.lettuce.core;

import java.util.Objects;

import io.lettuce.core.internal.LettuceAssert;

/**
 * {@link Range} defines {@literal lower} and {@literal upper} boundaries to retrieve items from a sorted set.
 *
 * @author Mark Paluch
 * @since 4.3
 */
public class Range {

    private Boundary lower;

    private Boundary upper;

    private Range(Boundary lower, Boundary upper) {

        LettuceAssert.notNull(lower, "Lower boundary must not be null");
        LettuceAssert.notNull(upper, "Upper boundary must not be null");

        this.lower = lower;
        this.upper = upper;
    }

    /**
     * Create a new range from {@code lower} and {@code upper} boundary values. Both values are included (greater than or equals
     * and less than or equals).
     *
     * @param lower lower boundary, must not be {@code null}.
     * @param upper upper boundary, must not be {@code null}.
     * @param  value type
     * @return new {@link Range}
     */
    public static  Range create(T lower, T upper) {

        LettuceAssert.isTrue(!(lower instanceof Boundary),
                "Lower must not be a Boundary. Use #from(Boundary, Boundary) instead");
        LettuceAssert.isTrue(!(upper instanceof Boundary),
                "Upper must not be a Boundary. Use #from(Boundary, Boundary) instead");

        return new Range(Boundary.including(lower), Boundary.including(upper));
    }

    /**
     * Create a new range from {@code lower} and {@code upper} boundaries.
     *
     * @param lower lower boundary, must not be {@code null}.
     * @param upper upper boundary, must not be {@code null}.
     * @param  value type.
     * @return new {@link Range}
     */
    public static  Range from(Boundary lower, Boundary upper) {
        return new Range(lower, upper);
    }

    /**
     * @param  value type.
     * @return new {@link Range} with {@code lower} and {@code upper} set to {@link Boundary#unbounded()}.
     */
    public static  Range unbounded() {
        return new Range(Boundary.unbounded(), Boundary.unbounded());
    }

    /**
     * Greater than or equals {@code lower}.
     *
     * @param lower the lower boundary value.
     * @return {@code this} {@link Range} with {@code lower} applied.
     */
    public Range gte(T lower) {

        this.lower = Boundary.including(lower);
        return this;
    }

    /**
     * Greater than {@code lower}.
     *
     * @param lower the lower boundary value.
     * @return {@code this} {@link Range} with {@code lower} applied.
     */
    public Range gt(T lower) {

        this.lower = Boundary.excluding(lower);
        return this;
    }

    /**
     * Less than or equals {@code lower}.
     *
     * @param upper the upper boundary value.
     * @return {@code this} {@link Range} with {@code upper} applied.
     */
    public Range lte(T upper) {

        this.upper = Boundary.including(upper);
        return this;
    }

    /**
     * Less than {@code lower}.
     *
     * @param upper the upper boundary value.
     * @return {@code this} {@link Range} with {@code upper} applied.
     */
    public Range lt(T upper) {

        this.upper = Boundary.excluding(upper);
        return this;
    }

    /**
     * Return whether this {@link Range} is unbounded (i.e. upper and lower bounds are unbounded).
     *
     * @return whether this {@link Range} is unbounded
     * @since 6.0
     */
    public boolean isUnbounded() {
        return lower.isUnbounded() && upper.isUnbounded();
    }

    /**
     * @return the lower boundary.
     */
    public Boundary getLower() {
        return lower;
    }

    /**
     * @return the upper boundary.
     */
    public Boundary getUpper() {
        return upper;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (!(o instanceof Range))
            return false;
        Range range = (Range) o;
        return Objects.equals(lower, range.lower) && Objects.equals(upper, range.upper);
    }

    @Override
    public int hashCode() {
        return Objects.hash(lower, upper);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName()).append(" [");
        sb.append(lower).append(" to ").append(upper).append("]");
        return sb.toString();
    }

    /**
     * @author Mark Paluch
     */
    public static class Boundary {

        private static final Boundary UNBOUNDED = new Boundary<>(null, true);

        private final T value;

        private final boolean including;

        private Boundary(T value, boolean including) {
            this.value = value;
            this.including = including;
        }

        /**
         * Creates an unbounded (infinite) boundary that marks the beginning/end of the range.
         *
         * @return the unbounded boundary.
         * @param  inferred type.
         */
        @SuppressWarnings("unchecked")
        public static  Boundary unbounded() {
            return (Boundary) UNBOUNDED;
        }

        /**
         * Create a {@link Boundary} based on the {@code value} that includes the value when comparing ranges. Greater or
         * equals, less or equals. but not Greater or equal, less or equal to {@code value}.
         *
         * @param value must not be {@code null}.
         * @param  value type.
         * @return the {@link Boundary}.
         */
        public static  Boundary including(T value) {

            LettuceAssert.notNull(value, "Value must not be null");

            return new Boundary<>(value, true);
        }

        /**
         * Create a {@link Boundary} based on the {@code value} that excludes the value when comparing ranges. Greater or less
         * to {@code value} but not greater or equal, less or equal.
         *
         * @param value must not be {@code null}.
         * @param  value type.
         * @return the {@link Boundary}.
         */
        public static  Boundary excluding(T value) {

            LettuceAssert.notNull(value, "Value must not be null");

            return new Boundary<>(value, false);
        }

        /**
         * @return the value
         */
        public T getValue() {
            return value;
        }

        /**
         * @return {@code true} if the boundary includes the value.
         */
        public boolean isIncluding() {
            return including;
        }

        /**
         * @return {@code true} if the bound is unbounded.
         * @since 6.0
         */
        public boolean isUnbounded() {
            return this == UNBOUNDED;
        }

        /**
         * @return {@code true} if the bound is unbounded.
         * @since 6.0
         */
        public boolean isBounded() {
            return this != UNBOUNDED;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o)
                return true;
            if (!(o instanceof Boundary))
                return false;
            Boundary boundary = (Boundary) o;
            return including == boundary.including && Objects.equals(value, boundary.value);
        }

        @Override
        public int hashCode() {
            return Objects.hash(value, including);
        }

        @Override
        public String toString() {

            if (value == null) {
                return "[unbounded]";
            }

            StringBuilder sb = new StringBuilder();
            if (including) {
                sb.append('[');
            } else {
                sb.append('(');
            }

            sb.append(value);
            return sb.toString();
        }

    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy