org.redisson.reactive.RedissonListReactive Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of redisson Show documentation
Show all versions of redisson Show documentation
Redis based In-Memory Data Grid for Java
/**
* Copyright 2018 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 static org.redisson.client.protocol.RedisCommands.LINDEX;
import static org.redisson.client.protocol.RedisCommands.LREM_SINGLE;
import static org.redisson.client.protocol.RedisCommands.RPUSH;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import org.redisson.RedissonList;
import org.redisson.api.RFuture;
import org.redisson.api.RListAsync;
import org.redisson.api.RListReactive;
import org.redisson.client.codec.Codec;
import org.redisson.client.protocol.RedisCommands;
import org.redisson.client.protocol.convertor.LongReplayConvertor;
import org.redisson.command.CommandReactiveExecutor;
import reactor.fn.BiFunction;
import reactor.fn.Function;
import reactor.fn.Supplier;
import reactor.rx.Stream;
import reactor.rx.Streams;
import reactor.rx.subscription.ReactiveSubscription;
/**
* Distributed and concurrent implementation of {@link java.util.List}
*
* @author Nikita Koksharov
*
* @param the type of elements held in this collection
*/
public class RedissonListReactive extends RedissonExpirableReactive implements RListReactive {
private final RListAsync instance;
public RedissonListReactive(CommandReactiveExecutor commandExecutor, String name) {
super(commandExecutor, name, new RedissonList(commandExecutor, name, null));
this.instance = (RListAsync) super.instance;
}
public RedissonListReactive(Codec codec, CommandReactiveExecutor commandExecutor, String name) {
super(codec, commandExecutor, name, new RedissonList(codec, commandExecutor, name, null));
this.instance = (RListAsync) super.instance;
}
@Override
public Publisher size() {
return commandExecutor.readReactive(getName(), codec, RedisCommands.LLEN_INT, getName());
}
@Override
public Publisher descendingIterator() {
return iterator(-1, false);
}
@Override
public Publisher iterator() {
return iterator(0, true);
}
@Override
public Publisher descendingIterator(int startIndex) {
return iterator(startIndex, false);
}
@Override
public Publisher iterator(int startIndex) {
return iterator(startIndex, true);
}
private Publisher iterator(final int startIndex, final boolean forward) {
return new Stream() {
@Override
public void subscribe(final Subscriber t) {
t.onSubscribe(new ReactiveSubscription(this, t) {
private int currentIndex = startIndex;
@Override
protected void onRequest(final long n) {
final ReactiveSubscription m = this;
get(currentIndex).subscribe(new Subscriber() {
V currValue;
@Override
public void onSubscribe(Subscription s) {
s.request(Long.MAX_VALUE);
}
@Override
public void onNext(V value) {
currValue = value;
m.onNext(value);
if (forward) {
currentIndex++;
} else {
currentIndex--;
}
}
@Override
public void onError(Throwable error) {
m.onError(error);
}
@Override
public void onComplete() {
if (currValue == null) {
m.onComplete();
return;
}
if (n-1 == 0) {
return;
}
onRequest(n-1);
}
});
}
});
}
};
}
@Override
public Publisher add(V e) {
return commandExecutor.writeReactive(getName(), codec, RPUSH, getName(), encode(e));
}
@Override
public Publisher remove(final Object o) {
return reactive(new Supplier>() {
@Override
public RFuture get() {
return instance.removeAsync(o);
}
});
}
protected Publisher remove(Object o, int count) {
return commandExecutor.writeReactive(getName(), codec, LREM_SINGLE, getName(), count, encode(o));
}
@Override
public Publisher containsAll(final Collection c) {
return reactive(new Supplier>() {
@Override
public RFuture get() {
return instance.containsAllAsync(c);
}
});
}
@Override
public Publisher addAll(Publisher c) {
return new PublisherAdder(this) {
@Override
public Integer sum(Integer first, Integer second) {
return second;
}
}.addAll(c);
}
@Override
public Publisher addAll(Collection c) {
if (c.isEmpty()) {
return size();
}
List