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

org.redisson.RedissonBuckets Maven / Gradle / Ivy

Go to download

Easy Redis Java client and Real-Time Data Platform. Valkey compatible. Sync/Async/RxJava3/Reactive API. Client side caching. Over 50 Redis based Java objects and services: JCache API, Apache Tomcat, Hibernate, Spring, Set, Multimap, SortedSet, Map, List, Queue, Deque, Semaphore, Lock, AtomicLong, Map Reduce, Bloom filter, Scheduler, RPC

There is a newer version: 3.40.2
Show newest version
/**
 * Copyright (c) 2013-2024 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;

import org.redisson.api.RBuckets;
import org.redisson.api.RFuture;
import org.redisson.client.codec.Codec;
import org.redisson.client.codec.StringCodec;
import org.redisson.client.protocol.RedisCommand;
import org.redisson.client.protocol.RedisCommands;
import org.redisson.codec.CompositeCodec;
import org.redisson.command.CommandAsyncExecutor;
import org.redisson.connection.decoder.BucketsDecoder;
import org.redisson.connection.decoder.MapGetAllDecoder;
import org.redisson.misc.CompletableFutureWrapper;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 
 * @author Nikita Koksharov
 *
 */
public class RedissonBuckets implements RBuckets {

    protected final Codec codec;
    protected final CommandAsyncExecutor commandExecutor;

    public RedissonBuckets(CommandAsyncExecutor commandExecutor) {
        this(commandExecutor.getServiceManager().getCfg().getCodec(), commandExecutor);
    }
    
    public RedissonBuckets(Codec codec, CommandAsyncExecutor commandExecutor) {
        super();
        this.codec = commandExecutor.getServiceManager().getCodec(codec);
        this.commandExecutor = commandExecutor;
    }

    @Override
    public  Map get(String... keys) {
        RFuture> future = getAsync(keys);
        return commandExecutor.get(future);
    }

    @Override
    public boolean trySet(Map buckets) {
        RFuture future = trySetAsync(buckets);
        return commandExecutor.get(future);
    }

    @Override
    public void set(Map buckets) {
        commandExecutor.get(setAsync(buckets));
    }

    @Override
    public  RFuture> getAsync(String... keys) {
        if (keys.length == 0) {
            return new CompletableFutureWrapper<>(Collections.emptyMap());
        }

        List keysList = Arrays.stream(keys)
                                        .map(k -> commandExecutor.getServiceManager().getConfig().getNameMapper().map(k))
                                        .collect(Collectors.toList());

        Codec commandCodec = new CompositeCodec(StringCodec.INSTANCE, codec, codec);
        
        RedisCommand> command = new RedisCommand<>("MGET", new MapGetAllDecoder(keysList, 0));
        return commandExecutor.readBatchedAsync(commandCodec, command, new SlotCallback, Map>() {

            @Override
            public Map onResult(Collection> result) {
                return result.stream()
                        .flatMap(c -> c.entrySet().stream())
                        .filter(e -> e.getKey() != null && e.getValue() != null)
                        .map(e -> {
                            String key = commandExecutor.getServiceManager().getConfig().getNameMapper().unmap((String) e.getKey());
                            return new AbstractMap.SimpleEntry<>(key, (V) e.getValue());
                        }).collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));
            }

            @Override
            public RedisCommand> createCommand(List keys) {
                return new RedisCommand<>("MGET", new BucketsDecoder(keys));
            }
        }, keysList.toArray(new Object[0]));
    }

    @Override
    public RFuture trySetAsync(Map buckets) {
        if (buckets.isEmpty()) {
            return new CompletableFutureWrapper<>(false);
        }

        Map mappedBuckets = map(buckets);

        return commandExecutor.writeBatchedAsync(codec, RedisCommands.MSETNX, new BooleanSlotCallback() {
            @Override
            public Object[] createParams(List keys) {
                List params = new ArrayList<>(keys.size());
                for (Object key : keys) {
                    params.add(key);
                    try {
                        params.add(codec.getValueEncoder().encode(mappedBuckets.get(key)));
                    } catch (IOException e) {
                        throw new IllegalArgumentException(e);
                    }
                }
                return params.toArray();
            }
        }, mappedBuckets.keySet().toArray(new Object[0]));
    }

    private Map map(Map buckets) {
        return buckets.entrySet().stream().collect(
                Collectors.toMap(e -> commandExecutor.getServiceManager().getConfig().getNameMapper().map(e.getKey()),
                        e -> e.getValue()));
    }

    @Override
    public RFuture setAsync(Map buckets) {
        if (buckets.isEmpty()) {
            return new CompletableFutureWrapper<>((Void) null);
        }

        Map mappedBuckets = map(buckets);

        return commandExecutor.writeBatchedAsync(codec, RedisCommands.MSET, new VoidSlotCallback() {
            @Override
            public Object[] createParams(List keys) {
                List params = new ArrayList<>(keys.size());
                for (Object key : keys) {
                    params.add(key);
                    try {
                        params.add(codec.getValueEncoder().encode(mappedBuckets.get(key)));
                    } catch (IOException e) {
                        throw new IllegalArgumentException(e);
                    }
                }
                return params.toArray();
            }
        }, mappedBuckets.keySet().toArray(new Object[0]));
    }

}