ConditionalRemover.java
/*
* Copyright 2024 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.keycloak.models.sessions.infinispan.changes.remote.remover;
import org.infinispan.client.hotrod.RemoteCache;
import org.infinispan.commons.util.concurrent.AggregateCompletionStage;
import org.keycloak.models.sessions.infinispan.changes.remote.updater.Updater;
import org.keycloak.models.sessions.infinispan.remote.transaction.RemoteChangeLogTransaction;
/**
* It handles conditional remove operations.
* <p>
* This class is preferred to remove an unknown amount of entries by its key and/or value state. The implement may use
* queries (delete statements) or perform a full cache scan to find the entries to remove.
* <p>
* The method {@link #willRemove(Updater)} is invoked by {@link RemoteChangeLogTransaction} before perform any change
* tracked by the {@link Updater}. This is an optimization to prevent sending changes that would be removed by this
* {@link ConditionalRemover}.
*
* @param <K> The key's type stored in the {@link RemoteCache}.
* @param <V> The value's type stored in the {@link RemoteCache}.
*/
public interface ConditionalRemover<K, V> {
/**
* @param key The entry's key to test.
* @param value The entry's value to test.
* @return {@code true} if the entry will be removed from the {@link RemoteCache}.
*/
boolean willRemove(K key, V value);
/**
* @param updater The {@link Updater} to test.
* @return {@code true} if the entry tracked by the {@link Updater} will be removed from the {@link RemoteCache}.
*/
default boolean willRemove(Updater<K, V> updater) {
// The value can be null if the entry updated is marked as deleted.
// In that case, we don't have the value to check for the condition and will let the transaction perform the removal.
return updater.getValue() != null && willRemove(updater.getKey(), updater.getValue());
}
/**
* Executes the conditional removes in the {@link RemoteCache}.
*
* @param cache The {@link RemoteCache} to perform the remove operations.
* @param stage The {@link AggregateCompletionStage} to add any incomplete tasks.
*/
void executeRemovals(RemoteCache<K, V> cache, AggregateCompletionStage<Void> stage);
}