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

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

There is a newer version: 4.0.7
Show 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.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 ListToKeyValueStruct implements UnaryOperator> {

    private final Function toStringValueFunction;

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

    @Override
    public KeyValue apply(KeyValue item) {
        if (item == null || item.getValue() == null) {
            return item;
        }
        switch (item.getType()) {
            case KeyValue.HASH:
                item.setValue(map(item.getValue()));
                break;
            case KeyValue.SET:
                item.setValue(new HashSet<>(item.getValue()));
                break;
            case KeyValue.ZSET:
                item.setValue(zset(item.getValue()));
                break;
            case KeyValue.STREAM:
                item.setValue(stream(item.getKey(), item.getValue()));
                break;
            case KeyValue.TIMESERIES:
                item.setValue(timeSeries(item.getValue()));
                break;
            default:
                // do nothing
                break;
        }
        return item;
    }

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

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

    @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) {
            K key = (K) list.get(i);
            V value = (V) list.get(i + 1);
            map.put(key, value);
        }
        return map;
    }

    @SuppressWarnings("unchecked")
    private Set> zset(List list) {
        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));
            V value = (V) list.get(i);
            values.add(ScoredValue.just(score, value));
        }
        return values;
    }

    @SuppressWarnings("unchecked")
    private List> stream(K key, List list) {
        List> messages = new ArrayList<>();
        for (Object object : list) {
            List entry = (List) object;
            LettuceAssert.isTrue(entry.size() == 2, "Invalid list size: " + entry.size());
            String id = toStringValueFunction.apply((V) entry.get(0));
            Map body = map((List) entry.get(1));
            messages.add(new StreamMessage<>(key, id, body));
        }
        return messages;
    }

}