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

org.redisson.reactive.RedissonMapReactiveIterator Maven / Gradle / Ivy

There is a newer version: 3.9.1
Show newest version
/**
 * Copyright 2014 Nikita Koksharov, Nickolay Borbit
 *
 * Licensed 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.redisson.reactive;

import java.net.InetSocketAddress;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import org.redisson.client.protocol.decoder.MapScanResult;
import org.redisson.client.protocol.decoder.ScanObjectEntry;

import io.netty.buffer.ByteBuf;
import reactor.rx.Stream;
import reactor.rx.subscription.ReactiveSubscription;

public class RedissonMapReactiveIterator {

    private final RedissonMapReactive map;

    public RedissonMapReactiveIterator(RedissonMapReactive map) {
        this.map = map;
    }

    public Publisher stream() {
        return new Stream() {

            @Override
            public void subscribe(final Subscriber t) {
                t.onSubscribe(new ReactiveSubscription(this, t) {

                    private Map firstValues;
                    private long iterPos = 0;
                    private InetSocketAddress client;

                    private long currentIndex;

                    @Override
                    protected void onRequest(final long n) {
                        currentIndex = n;
                        nextValues();
                    }

                    private Map convert(Map map) {
                        Map result = new HashMap(map.size());
                        for (Entry entry : map.entrySet()) {
                            result.put(entry.getKey().getBuf(), entry.getValue().getBuf());
                        }
                        return result;
                    }

                    protected void nextValues() {
                        final ReactiveSubscription m = this;
                        map.scanIteratorReactive(client, iterPos).subscribe(new Subscriber>() {

                            @Override
                            public void onSubscribe(Subscription s) {
                                s.request(Long.MAX_VALUE);
                            }

                            @Override
                            public void onNext(MapScanResult res) {
                                client = res.getRedisClient();
                                if (iterPos == 0 && firstValues == null) {
                                    firstValues = convert(res.getMap());
                                } else if (convert(res.getMap()).equals(firstValues)) {
                                    m.onComplete();
                                    currentIndex = 0;
                                    return;
                                }

                                iterPos = res.getPos();
                                for (Entry entry : res.getMap().entrySet()) {
                                    M val = getValue(entry);
                                    m.onNext(val);
                                    currentIndex--;
                                    if (currentIndex == 0) {
                                        m.onComplete();
                                        return;
                                    }
                                }
                            }

                            @Override
                            public void onError(Throwable error) {
                                m.onError(error);
                            }

                            @Override
                            public void onComplete() {
                                if (currentIndex == 0) {
                                    return;
                                }
                                nextValues();
                            }
                        });
                    }
                });
            }

        };
    }


    M getValue(final Entry entry) {
        return (M)new AbstractMap.SimpleEntry((K)entry.getKey().getObj(), (V)entry.getValue().getObj()) {

            @Override
            public V setValue(V value) {
                Publisher publisher = map.put((K) entry.getKey().getObj(), value);
                return ((Stream)publisher).next().poll();
            }

        };
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy