Zzutop is an important part of the Zzutop project, and this article documents the process of achieving it.

1, Redis ZSet

——–Set:

——–ZSet:

You can see that ZSet has an extra score, which is obviously going to be used for sorting correlations.

The data structure of an ordered set is shown below:

  • A fraction is a floating point number, represented in Java using a double precision
  • Value is also a String data type and a hash based storage structure
  • Like Set, it is unique for each element, but the score can be the same for different elements
  • Collections are implemented through hash tables, so the complexity of adding, removing, and searching is O(1)O(1)O(1)
  • The largest number of elements in the set is 232−12^{32}-1232−1 (over 4 billion)
  • The element depends on a key to indicate which ordered collection it belongs to

2. Spring-data-redis encapsulation of Redis ZSet

Spring encapsulates Redis ZSet elements, score ranges, and restrictions.

Element encapsulation: ——————–

TypedTuple – org. Springframework. Data. Redis. Core. ZSetOperations interface of the internal interface:

public interface TypedTuple<V> extends Comparable<ZSetOperations.TypedTuple<V>> {
        @Nullable
        V getValue(a);

        @Nullable
        Double getScore(a);

        static <V> ZSetOperations.TypedTuple<V> of(V value, @Nullable Double score) {
            return newDefaultTypedTuple(value, score); }}Copy the code

TypedTuple getValue() gets the value and getScore() gets the score, but it’s just an interface, not an implementation class. Spring-data-redis provides a default implementation class, DefaultTypedTuple, which also implements the TypedTuple interface. By default, Spring encapsulates the values and scores of ordered collections with scores in this class. So you can read the corresponding value and score from this class object.

Scope encapsulation: ——————–

Range — interface org. Springframework. Data. Redis. Connection. RedisZSetCommands under static inner class:

    public static class Range {
        @Nullable
        RedisZSetCommands.Range.Boundary min;
        @Nullable
        RedisZSetCommands.Range.Boundary max;

        public Range(a) {}public static RedisZSetCommands.Range range(a) {
            return new RedisZSetCommands.Range();
        }

        public static RedisZSetCommands.Range unbounded(a) {
            RedisZSetCommands.Range range = new RedisZSetCommands.Range();
            range.min = RedisZSetCommands.Range.Boundary.infinite();
            range.max = RedisZSetCommands.Range.Boundary.infinite();
            return range;
        }

        public RedisZSetCommands.Range gte(Object min) {
            Assert.notNull(min, "Min already set for range.");
            this.min = new RedisZSetCommands.Range.Boundary(min, true);
            return this;
        }

        public RedisZSetCommands.Range gt(Object min) {
            Assert.notNull(min, "Min already set for range.");
            this.min = new RedisZSetCommands.Range.Boundary(min, false);
            return this;
        }

        public RedisZSetCommands.Range lte(Object max) {
            Assert.notNull(max, "Max already set for range.");
            this.max = new RedisZSetCommands.Range.Boundary(max, true);
            return this;
        }

        public RedisZSetCommands.Range lt(Object max) {
            Assert.notNull(max, "Max already set for range.");
            this.max = new RedisZSetCommands.Range.Boundary(max, false);
            return this;
        }

        @Nullable
        public RedisZSetCommands.Range.Boundary getMin(a) {
            return this.min;
        }

        @Nullable
        public RedisZSetCommands.Range.Boundary getMax(a) {
            return this.max;
        }

        public static class Boundary {
            @Nullable
            Object value;
            boolean including;

            static RedisZSetCommands.Range.Boundary infinite(a) {
                return new RedisZSetCommands.Range.Boundary((Object)null.true);
            }

            Boundary(@Nullable Object value, boolean including) {
                this.value = value;
                this.including = including;
            }

            @Nullable
            public Object getValue(a) {
                return this.value;
            }

            public boolean isIncluding(a) {
                return this.including; }}}Copy the code

It has a static range() method that you can use to generate a range object, but you need to be aware of the range object’s methods to control the range.

Limiting encapsulation: ——————–

Limit — interface org. Springframework. Data. Redis. Connection. Under RedisZSetCommands inner class:

It is a simple POJO that has two properties, getter and setter methods, as shown in the following code:

/ /...
public interface RedisZSetCommands {
    / /...
public class Limit {
    int offset;
    int count;
// Setter and getter methods
}
/ /...
}
Copy the code

Offset represents the number from which to start, while count limits the total number returned

3. How to apply it in the project?

Problem: The trending topic entity includes not only scores, but also a set of attributes. Does the value in ZSet correspond to this set of attributes?

To do this:

  • The value was too long in the subsequent search for the score
  • Will the value repeat in the later stage