| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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.apache.cassandra.simulator; |
| |
| import java.util.function.Supplier; |
| |
| import org.apache.cassandra.simulator.Action.Modifiers; |
| |
| import static org.apache.cassandra.simulator.Action.Modifiers.INFINITE_STREAM; |
| import static org.apache.cassandra.simulator.Action.Modifiers.INFINITE_STREAM_ITEM; |
| import static org.apache.cassandra.simulator.Action.Modifiers.NONE; |
| import static org.apache.cassandra.simulator.Action.Modifiers.RELIABLE; |
| import static org.apache.cassandra.simulator.Action.Modifiers.STREAM; |
| import static org.apache.cassandra.simulator.Action.Modifiers.STREAM_ITEM; |
| import static org.apache.cassandra.simulator.Action.Modifiers.STRICT; |
| import static org.apache.cassandra.utils.LazyToString.lazy; |
| |
| public class Actions |
| { |
| public static class LambdaAction extends Action |
| { |
| private Supplier<ActionList> perform; |
| |
| public LambdaAction(Object description, Supplier<ActionList> perform) |
| { |
| this(description, Modifiers.NONE, perform); |
| } |
| |
| public LambdaAction(Object description, Modifiers self, Supplier<ActionList> perform) |
| { |
| this(description, self, Modifiers.NONE, perform); |
| } |
| |
| public LambdaAction(Object description, Modifiers self, Modifiers children, Supplier<ActionList> perform) |
| { |
| this(description, OrderOn.NONE, self, children, perform); |
| } |
| |
| public LambdaAction(Object description, OrderOn orderOn, Modifiers self, Modifiers children, Supplier<ActionList> perform) |
| { |
| super(description, orderOn, self, children); |
| this.perform = perform; |
| } |
| |
| protected ActionList performSimple() |
| { |
| ActionList result = perform.get(); |
| perform = null; |
| return result; |
| } |
| } |
| |
| /** |
| * Should always be performed eventually. |
| */ |
| public static class ReliableAction extends LambdaAction |
| { |
| public ReliableAction(Object description, Supplier<ActionList> perform, boolean transitive) |
| { |
| this(description, RELIABLE, transitive ? RELIABLE : NONE, perform); |
| } |
| |
| public ReliableAction(Object description, Modifiers self, Modifiers children, Supplier<ActionList> perform) |
| { |
| this(description, OrderOn.NONE, self, children, perform); |
| } |
| |
| public ReliableAction(Object description, OrderOn orderOn, Modifiers self, Modifiers children, Supplier<ActionList> perform) |
| { |
| super(description, orderOn, self, children, perform); |
| assert !is(Modifier.DROP); |
| assert children.is(Modifier.RELIABLE); |
| } |
| |
| public static ReliableAction transitively(Object description, Supplier<ActionList> action) |
| { |
| return new ReliableAction(description, action, true); |
| } |
| } |
| |
| /** |
| * Should always be performed in strict order, i.e. all of this action's child actions should complete before |
| * the next action scheduled by the same actor is invoked. |
| */ |
| public static class StrictAction extends LambdaAction |
| { |
| public StrictAction(Object description, Supplier<ActionList> perform, boolean transitive) |
| { |
| super(description, STRICT, transitive ? STRICT : NONE, perform); |
| } |
| |
| public static StrictAction of(Object description, Supplier<ActionList> action) |
| { |
| return new StrictAction(description, action, false); |
| } |
| } |
| |
| public static Action of(Object description, Supplier<ActionList> action) |
| { |
| return new LambdaAction(description, action); |
| } |
| |
| public static Action of(Modifiers self, Modifiers children, Object description, Supplier<ActionList> action) |
| { |
| return new LambdaAction(description, self, children, action); |
| } |
| |
| public static Action of(OrderOn orderOn, Modifiers self, Modifiers children, Object description, Supplier<ActionList> action) |
| { |
| return new LambdaAction(description, orderOn, self, children, action); |
| } |
| |
| public static Action empty(String message) |
| { |
| return of(message, ActionList::empty); |
| } |
| |
| public static Action empty(Modifiers modifiers, Object message) |
| { |
| return of(modifiers, NONE, message, ActionList::empty); |
| } |
| |
| public static Action stream(int concurrency, Supplier<Action> actions) { return stream(new OrderOn.Strict(actions, concurrency), actions); } |
| public static Action stream(OrderOn on, Supplier<Action> actions) { return of(OrderOn.NONE, STREAM, NONE, on, () -> ActionList.of(streamNextSupplier(STREAM, STREAM_ITEM, on, 0, on, actions))); } |
| public static Action infiniteStream(int concurrency, Supplier<Action> actions) { return infiniteStream(new OrderOn.Strict(actions, concurrency), actions); } |
| public static Action infiniteStream(OrderOn on, Supplier<Action> actions) { return of(OrderOn.NONE, INFINITE_STREAM, NONE, on, () -> ActionList.of(streamNextSupplier(INFINITE_STREAM, INFINITE_STREAM_ITEM, on, 0, on, actions))); } |
| private static ActionList next(Modifiers modifiers, Object description, int sequence, OrderOn on, Supplier<Action> actions) |
| { |
| Action next = actions.get(); |
| if (next == null) |
| return ActionList.empty(); |
| return ActionList.of(next, streamNextSupplier(modifiers, modifiers, description, sequence + 1, on, actions)); |
| } |
| |
| private static Action streamNextSupplier(Modifiers modifiers, Modifiers nextModifiers, Object description, int sequence, OrderOn on, Supplier<Action> actions) |
| { |
| return Actions.of(on, modifiers, NONE, |
| lazy(() -> description + " " + sequence), () -> next(nextModifiers, description, sequence, on, actions)); |
| } |
| |
| |
| } |