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

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

There is a newer version: 3.45.1
Show newest version
/**
 * Copyright 2016 Nikita Koksharov
 *
 * 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.Collection;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

import org.reactivestreams.Publisher;
import org.redisson.RedissonMap;
import org.redisson.api.MapOptions;
import org.redisson.api.RFuture;
import org.redisson.api.RMapAsync;
import org.redisson.api.RMapReactive;
import org.redisson.client.RedisClient;
import org.redisson.client.codec.Codec;
import org.redisson.client.codec.MapScanCodec;
import org.redisson.client.protocol.RedisCommands;
import org.redisson.client.protocol.decoder.MapScanResult;
import org.redisson.client.protocol.decoder.ScanObjectEntry;
import org.redisson.command.CommandReactiveExecutor;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * Distributed and concurrent implementation of {@link java.util.concurrent.ConcurrentMap}
 * and {@link java.util.Map}
 *
 * @author Nikita Koksharov
 *
 * @param  key
 * @param  value
 */
public class RedissonMapReactive extends RedissonExpirableReactive implements RMapReactive, MapReactive {

    private final RMapAsync instance;

    public RedissonMapReactive(CommandReactiveExecutor commandExecutor, String name, MapOptions options) {
        super(commandExecutor, name);
        instance = new RedissonMap(codec, commandExecutor, name, null, options);
    }

    public RedissonMapReactive(Codec codec, CommandReactiveExecutor commandExecutor, String name, MapOptions options) {
        super(codec, commandExecutor, name);
        instance = new RedissonMap(codec, commandExecutor, name, null, options);
    }

    @Override
    public Publisher loadAll(final boolean replaceExistingValues, final int parallelism) {
        return reactive(new Supplier>() {
            @Override
            public RFuture get() {
                return instance.loadAllAsync(replaceExistingValues, parallelism);
            }
        });
    }

    @Override
    public Publisher loadAll(final Set keys, final boolean replaceExistingValues, final int parallelism) {
        return reactive(new Supplier>() {
            @Override
            public RFuture get() {
                return instance.loadAllAsync(keys, replaceExistingValues, parallelism);
            }
        });
    }
    
    @Override
    public Publisher fastPutIfAbsent(final K key, final V value) {
        return reactive(new Supplier>() {
            @Override
            public RFuture get() {
                return instance.fastPutIfAbsentAsync(key, value);
            }
        });
    }

    @Override
    public Publisher> readAllKeySet() {
        return reactive(new Supplier>>() {
            @Override
            public RFuture> get() {
                return instance.readAllKeySetAsync();
            }
        });
    }

    @Override
    public Publisher> readAllValues() {
        return reactive(new Supplier>>() {
            @Override
            public RFuture> get() {
                return instance.readAllValuesAsync();
            }
        });
    }

    @Override
    public Publisher>> readAllEntrySet() {
        return reactive(new Supplier>>>() {
            @Override
            public RFuture>> get() {
                return instance.readAllEntrySetAsync();
            }
        });
    }

    @Override
    public Publisher> readAllMap() {
        return reactive(new Supplier>>() {
            @Override
            public RFuture> get() {
                return instance.readAllMapAsync();
            }
        });
    }
    
    @Override
    public Publisher valueSize(final K key) {
        return reactive(new Supplier>() {
            @Override
            public RFuture get() {
                return instance.valueSizeAsync(key);
            }
        });
    }

    @Override
    public Publisher size() {
        return reactive(new Supplier>() {
            @Override
            public RFuture get() {
                return instance.sizeAsync();
            }
        });
    }

    @Override
    public Publisher containsKey(final Object key) {
        return reactive(new Supplier>() {
            @Override
            public RFuture get() {
                return instance.containsKeyAsync(key);
            }
        });
    }

    @Override
    public Publisher containsValue(final Object value) {
        return reactive(new Supplier>() {
            @Override
            public RFuture get() {
                return instance.containsValueAsync(value);
            }
        });
    }

    @Override
    public Publisher> getAll(final Set keys) {
        return reactive(new Supplier>>() {
            @Override
            public RFuture> get() {
                return instance.getAllAsync(keys);
            }
        });
    }

    @Override
    public Publisher putAll(final Map map) {
        return reactive(new Supplier>() {
            @Override
            public RFuture get() {
                return instance.putAllAsync(map);
            }
        });
    }

    @Override
    public Publisher putIfAbsent(final K key, final V value) {
        return reactive(new Supplier>() {
            @Override
            public RFuture get() {
                return instance.putIfAbsentAsync(key, value);
            }
        });
    }

    @Override
    public Publisher remove(final Object key, final Object value) {
        return reactive(new Supplier>() {
            @Override
            public RFuture get() {
                return instance.removeAsync(key, value);
            }
        });
    }

    @Override
    public Publisher replace(final K key, final V oldValue, final V newValue) {
        return reactive(new Supplier>() {
            @Override
            public RFuture get() {
                return instance.replaceAsync(key, oldValue, newValue);
            }
        });
    }

    @Override
    public Publisher replace(final K key, final V value) {
        return reactive(new Supplier>() {
            @Override
            public RFuture get() {
                return instance.replaceAsync(key, value);
            }
        });
    }

    @Override
    public Publisher get(final K key) {
        return reactive(new Supplier>() {
            @Override
            public RFuture get() {
                return instance.getAsync(key);
            }
        });
    }

    @Override
    public Publisher put(final K key, final V value) {
        return reactive(new Supplier>() {
            @Override
            public RFuture get() {
                return instance.putAsync(key, value);
            }
        });
    }


    @Override
    public Publisher remove(final K key) {
        return reactive(new Supplier>() {
            @Override
            public RFuture get() {
                return instance.removeAsync(key);
            }
        });
    }

    @Override
    public Publisher fastPut(final K key, final V value) {
        return reactive(new Supplier>() {
            @Override
            public RFuture get() {
                return instance.fastPutAsync(key, value);
            }
        });
    }

    @Override
    public Publisher fastRemove(final K ... keys) {
        return reactive(new Supplier>() {
            @Override
            public RFuture get() {
                return instance.fastRemoveAsync(keys);
            }
        });
    }

    public Publisher> scanIteratorReactive(RedisClient client, long startPos) {
        return commandExecutor.readReactive(client, getName(), new MapScanCodec(codec), RedisCommands.HSCAN, getName(), startPos);
    }

    @Override
    public Publisher> entryIterator() {
        return Flux.create(new RedissonMapReactiveIterator>(this));
    }

    @Override
    public Publisher valueIterator() {
        return Flux.create(new RedissonMapReactiveIterator(this) {
            @Override
            V getValue(Entry entry) {
                return (V) entry.getValue().getObj();
            }
        });
    }

    @Override
    public Publisher keyIterator() {
        return Flux.create(new RedissonMapReactiveIterator(this) {
            @Override
            K getValue(Entry entry) {
                return (K) entry.getKey().getObj();
            }
        });
    }

    @Override
    public Publisher addAndGet(final K key, final Number value) {
        return reactive(new Supplier>() {
            @Override
            public RFuture get() {
                return instance.addAndGetAsync(key, value);
            }
        });
    }

    @Override
    public boolean equals(Object o) {
        if (o == this)
            return true;

        if (o instanceof Map) {
            final Map m = (Map) o;
            if (m.size() != Mono.from(size()).block()) {
                return false;
            }

            return Flux.from(entryIterator()).map(mapFunction(m)).reduce(true, booleanAnd()).block();
        } else if (o instanceof RMapReactive) {
            final RMapReactive m = (RMapReactive) o;
            if (Mono.from(m.size()).block() != Mono.from(size()).block()) {
                return false;
            }

            return Flux.from(entryIterator()).map(mapFunction(m)).reduce(true, booleanAnd()).block();
        }

        return true;
    }

    private BiFunction booleanAnd() {
        return new BiFunction() {

            @Override
            public Boolean apply(Boolean t, Boolean u) {
                return t & u;
            }
        };
    }

    private Function, Boolean> mapFunction(final Map m) {
        return new Function, Boolean>() {
            @Override
            public Boolean apply(Entry e) {
                K key = e.getKey();
                V value = e.getValue();
                if (value == null) {
                    if (!(m.get(key)==null && m.containsKey(key)))
                        return false;
                } else {
                    if (!value.equals(m.get(key)))
                        return false;
                }
                return true;
            }
        };
    }

    private Function, Boolean> mapFunction(final RMapReactive m) {
        return new Function, Boolean>() {
            @Override
            public Boolean apply(Entry e) {
                Object key = e.getKey();
                Object value = e.getValue();
                if (value == null) {
                    if (!(Mono.from(m.get(key)).block() ==null && Mono.from(m.containsKey(key)).block()))
                        return false;
                } else {
                    if (!value.equals(Mono.from(m.get(key)).block()))
                        return false;
                }
                return true;
            }
        };
    }

    @Override
    public int hashCode() {
        return Flux.from(entryIterator()).map(new Function, Integer>() {
            @Override
            public Integer apply(Entry t) {
                return t.hashCode();
            }
        }).reduce(0, new BiFunction() {

            @Override
            public Integer apply(Integer t, Integer u) {
                return t + u;
            }
        }).block();
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy