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

com.redis.spring.batch.reader.StructPostOperator Maven / Gradle / Ivy

The newest version!
package com.redis.spring.batch.reader;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.function.UnaryOperator;

import com.redis.lettucemod.timeseries.Sample;
import com.redis.spring.batch.common.KeyValue;
import com.redis.spring.batch.util.CodecUtils;

import io.lettuce.core.ScoredValue;
import io.lettuce.core.StreamMessage;
import io.lettuce.core.codec.RedisCodec;
import io.lettuce.core.internal.LettuceAssert;

public class StructPostOperator implements UnaryOperator> {

    private final Function toStringValueFunction;

    public StructPostOperator(RedisCodec codec) {
        this.toStringValueFunction = CodecUtils.toStringValueFunction(codec);
    }

    @Override
    public KeyValue apply(KeyValue t) {
        if (t != null) {
            t.setValue(value(t));
        }
        return t;
    }

    private Object value(KeyValue t) {
        if (t.getValue() == null) {
            return null;
        }
        switch (t.getType()) {
            case HASH:
                return map(t);
            case SET:
                return set(t);
            case ZSET:
                return zset(t);
            case STREAM:
                return stream(t);
            case TIMESERIES:
                return timeSeries(t);
            default:
                return t.getValue();
        }
    }

    @SuppressWarnings("unchecked")
    private HashSet set(KeyValue t) {
        return new HashSet<>((List) t.getValue());
    }

    @SuppressWarnings("unchecked")
    private List timeSeries(KeyValue t) {
        List samples = new ArrayList<>();
        for (List sample : (List>) t.getValue()) {
            LettuceAssert.isTrue(sample.size() == 2, "Invalid list size: " + sample.size());
            Long timestamp = (Long) sample.get(0);
            samples.add(Sample.of(timestamp, toDouble((V) sample.get(1))));
        }
        return samples;
    }

    private String toString(V value) {
        return toStringValueFunction.apply(value);
    }

    private double toDouble(V value) {
        return Double.parseDouble(toString(value));
    }

    @SuppressWarnings("unchecked")
    private Map map(KeyValue t) {
        List list = (List) t.getValue();
        return map(list);
    }

    @SuppressWarnings("unchecked")
    private Map map(List list) {
        LettuceAssert.isTrue(list.size() % 2 == 0, "List size must be a multiple of 2");
        Map map = new HashMap<>();
        for (int i = 0; i < list.size(); i += 2) {
            map.put((K) list.get(i), (V) list.get(i + 1));
        }
        return map;
    }

    @SuppressWarnings("unchecked")
    private Set> zset(KeyValue t) {
        List list = (List) t.getValue();
        LettuceAssert.isTrue(list.size() % 2 == 0, "List size must be a multiple of 2");
        Set> values = new HashSet<>();
        for (int i = 0; i < list.size(); i += 2) {
            double score = toDouble((V) list.get(i + 1));
            values.add(ScoredValue.just(score, (V) list.get(i)));
        }
        return values;
    }

    @SuppressWarnings("unchecked")
    private List> stream(KeyValue t) {
        List> messages = new ArrayList<>();
        for (List message : (List>) t.getValue()) {
            LettuceAssert.isTrue(message.size() == 2, "Invalid list size: " + message.size());
            String id = toString((V) message.get(0));
            Map body = map((List) message.get(1));
            messages.add(new StreamMessage<>(t.getKey(), id, body));
        }
        return messages;
    }

}