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

groovyx.gpars.dataflow.Select Maven / Gradle / Ivy

Go to download

The Groovy and Java high-level concurrency library offering actors, dataflow, CSP, agents, parallel collections, fork/join and more

There is a newer version: 1.2.1
Show newest version
// GPars - Groovy Parallel Systems
//
// Copyright © 2008-11  The original author or authors
//
// 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 groovyx.gpars.dataflow;

import groovyx.gpars.actor.impl.MessageStream;
import groovyx.gpars.dataflow.impl.GuardedSelectRequest;
import groovyx.gpars.dataflow.impl.SelectBase;
import groovyx.gpars.group.PGroup;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * A Select allows the user to select a value from multiple channels, which have a value available for read at the moment.
 * It can either pick a channel randomly, when using the plain select method, or with precedence towards channels with lower position indexes,
 * when the prioritySelect method is used.
 * If a value is not available immediately in any of the channels, Select will wait for the first value to arrive in any of the channels.
 * 

* Both 'select' and 'prioritySelect' methods come in two flavours - blocking, which wait till a value is available in a channel, * and messaging, which send out a message to the specified message handler, as soon as a message is available. * Optionally, all methods allow the user to specify a boolean mask, assigning each select 's input channel a flag indicating, * whether it should be included in the select operation. This is useful when handling state to selectively block some inputs * in some states. * * @author Vaclav Pech * Date: 30th Sep 2010 */ @SuppressWarnings({"MethodNamesDifferingOnlyByCase"}) public class Select { private final SelectBase selectBase; /** * @param pGroup The group, the thread pool of which should be used for notification message handlers * @param channels The input channels to select from */ @SuppressWarnings({"OverloadedVarargsMethod"}) public Select(final PGroup pGroup, final DataflowReadChannel... channels) { selectBase = new SelectBase(pGroup, Arrays.asList(channels)); } /** * @param pGroup The group, the thread pool of which should be used for notification message handlers * @param channels The list of input channels to select from */ public Select(final PGroup pGroup, final List> channels) { //noinspection unchecked selectBase = new SelectBase(pGroup, channels); } /** * Selects a value from a single randomly chosen input channel, which has a value available for read. * * @return The read value. It will be of SelectResult type, holding the actual value as well as the channel index. * @throws InterruptedException If the current thread gets interrupted */ public SelectResult select() throws InterruptedException { return select(-1, null); } /** * Selects a value from a single randomly chosen input channel, which has a value available for read. * Only the channels marked with 'true' in the supplied mask will be considered. * * @param mask A list of boolean values indicating, whether the input channel with the same position index should be included in the selection or not * @return The read value. It will be of SelectResult type, holding the actual value as well as the channel index. * @throws InterruptedException If the current thread gets interrupted */ public SelectResult select(final List mask) throws InterruptedException { return select(-1, mask); } /** * Selects a value from a single randomly chosen input channel, which has a value available for read. * The read value is send to the supplied messageStream * * @param messageStream A message stream accepting the selected value. The message will be of SelectResult type, holding the actual value as well as the channel index. * @throws InterruptedException If the current thread gets interrupted */ public void select(final MessageStream messageStream) throws InterruptedException { select(messageStream, -1, null); } /** * Selects a value from a single randomly chosen input channel, which has a value available for read. * The read value is send to the supplied messageStream * * @param messageStream A message stream accepting the selected value. The message will be of SelectResult type, holding the actual value as well as the channel index. * @param mask A list of boolean values indicating, whether the input channel with the same position index should be included in the selection or not * @throws InterruptedException If the current thread gets interrupted */ public void select(final MessageStream messageStream, final List mask) throws InterruptedException { select(messageStream, -1, mask); } /** * Selects a value from a single input channel, which has a value available for read. Channels with lower position index are preferred. * * @return The read value. It will be of SelectResult type, holding the actual value as well as the channel index. * @throws InterruptedException If the current thread gets interrupted */ public SelectResult prioritySelect() throws InterruptedException { return select(0, null); } /** * Selects a value from a single input channel, which has a value available for read. Channels with lower position index are preferred. * Only the channels marked with 'true' in the supplied mask will be considered. * * @param mask A list of boolean values indicating, whether the input channel with the same position index should be included in the selection or not * @return The read value. It will be of SelectResult type, holding the actual value as well as the channel index. * @throws InterruptedException If the current thread gets interrupted */ public SelectResult prioritySelect(final List mask) throws InterruptedException { return select(0, mask); } /** * Selects a value from a single input channel, which has a value available for read. Channels with lower position index are preferred. * The read value is send to the supplied messageStream * * @param messageStream A message stream accepting the selected value. The message will be of SelectResult type, holding the actual value as well as the channel index. * @throws InterruptedException If the current thread gets interrupted */ public void prioritySelect(final MessageStream messageStream) throws InterruptedException { select(messageStream, 0, null); } /** * Selects a value from a single input channel, which has a value available for read. Channels with lower position index are preferred. * The read value is send to the supplied messageStream * * @param messageStream A message stream accepting the selected value. The message will be of SelectResult type, holding the actual value as well as the channel index. * @param mask A list of boolean values indicating, whether the input channel with the same position index should be included in the selection or not * @throws InterruptedException If the current thread gets interrupted */ public void prioritySelect(final MessageStream messageStream, final List mask) throws InterruptedException { select(messageStream, 0, mask); } /** * Selects a value from a single randomly chosen input channel, which has a value available for read. * * @return The read value. It will be of SelectResult type, holding the actual value as well as the channel index. * @throws InterruptedException If the current thread gets interrupted */ public final SelectResult call() throws InterruptedException { return select(); } /** * Selects a value from a single randomly chosen input channel, which has a value available for read. * Only the channels marked with 'true' in the supplied mask will be considered. * * @param mask A list of boolean values indicating, whether the input channel with the same position index should be included in the selection or not * @return The read value. It will be of SelectResult type, holding the actual value as well as the channel index. * @throws InterruptedException If the current thread gets interrupted */ public final SelectResult call(final List mask) throws InterruptedException { return select(mask); } /** * Selects a value from a single randomly chosen input channel, which has a value available for read. * The read value is send to the supplied messageStream * * @param messageStream A message stream accepting the selected value. The message will be of SelectResult type, holding the actual value as well as the channel index. * @throws InterruptedException If the current thread gets interrupted */ public final void call(final MessageStream messageStream) throws InterruptedException { select(messageStream); } /** * Selects a value from a single randomly chosen input channel, which has a value available for read. * The read value is send to the supplied messageStream * * @param messageStream A message stream accepting the selected value. The message will be of SelectResult type, holding the actual value as well as the channel index. * @param mask A list of boolean values indicating, whether the input channel with the same position index should be included in the selection or not * @throws InterruptedException If the current thread gets interrupted */ public final void call(final MessageStream messageStream, final List mask) throws InterruptedException { select(messageStream, mask); } /** * Invokes the internal select base with a SelectRequest instance ensuring a message is sent, once a value has been selected */ private void select(final MessageStream messageStream, final int startIndex, final List mask) throws InterruptedException { selectBase.doSelect(startIndex, new GuardedSelectRequest(mask) { @Override public void valueFound(final int index, final T value) { messageStream.send(new SelectResult(index, value)); } }); } /** * Invokes the internal select base with a SelectRequest instance ensuring the current thread can continue returning the correct value, once a value has been selected */ private SelectResult select(final int startIndex, final List mask) throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); final int[] foundIndex = new int[1]; @SuppressWarnings({"unchecked"}) final T[] foundValue = (T[]) new Object[1]; selectBase.doSelect(startIndex, new GuardedSelectRequest(mask) { @Override public void valueFound(final int index, final T value) { foundIndex[0] = index; foundValue[0] = value; latch.countDown(); } }); latch.await(); return new SelectResult(foundIndex[0], foundValue[0]); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy