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

org.infinispan.server.resp.commands.set.SMOVE Maven / Gradle / Ivy

There is a newer version: 15.1.4.Final
Show newest version
package org.infinispan.server.resp.commands.set;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;

import org.infinispan.multimap.impl.EmbeddedSetCache;
import org.infinispan.server.resp.Resp3Handler;
import org.infinispan.server.resp.RespCommand;
import org.infinispan.server.resp.RespRequestHandler;
import org.infinispan.server.resp.commands.Resp3Command;
import org.infinispan.server.resp.logging.Log;
import org.infinispan.server.resp.serialization.Resp3Response;

import io.netty.channel.ChannelHandlerContext;

/**
 * SMOVE implementation
 * 

* Atomicity warning: * Derogating to the above description, this implementation is not atomic: * is it possible that, moving an existing element in source, at a given * time a client * can observe that element doesn't exists both in source and destination. * @since 15.0 * @see Redis documentation */ public class SMOVE extends RespCommand implements Resp3Command { public SMOVE() { super(4, 1, 2, 1); } @Override public CompletionStage perform(Resp3Handler handler, ChannelHandlerContext ctx, List arguments) { final var source = arguments.get(0); final var destination = arguments.get(1); final var element = arguments.get(2); boolean sameList = Arrays.equals(source, destination); EmbeddedSetCache esc = handler.getEmbeddedSetCache(); if (!sameList) { // warn when different sets Log.SERVER.smoveConsistencyMessage(); return handler.stageToReturn(moveElement(esc, element, source, destination), ctx, Resp3Response.INTEGER); } return handler.stageToReturn(esc.get(source) .thenApply((bucket) -> bucket.contains(element) ? 1L : 0L), ctx, Resp3Response.INTEGER); } private CompletionStage moveElement(EmbeddedSetCache cache, byte[] element, byte[] srcKey, byte[] destKey) { // Check whether the destination set is a set structure. // Under concurrent load, this might malfunction as the entry is created concurrently elsewhere. return cache.exists(destKey) .thenCompose(ignore -> removeAndAdd(cache, element, srcKey, destKey)); } private CompletionStage removeAndAdd(EmbeddedSetCache cache, byte[] element, byte[] srcKey, byte[] destKey) { return cache.remove(srcKey, element) .thenCompose(removed -> { if (removed == 0) return CompletableFuture.completedFuture(0L); return cache.add(destKey, element); }); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy