package org.glassfish.grizzly.nio;
import java.io.IOException;
import java.nio.channels.SelectableChannel;
import java.util.concurrent.atomic.AtomicInteger;
import org.glassfish.grizzly.CompletionHandler;
import org.glassfish.grizzly.Connection;
public final class RoundRobinConnectionDistributor
extends AbstractNIOConnectionDistributor {
private final Iterator it;
public RoundRobinConnectionDistributor(final NIOTransport transport) {
this(transport, false, false);
}
public RoundRobinConnectionDistributor(final NIOTransport transport,
final boolean useDedicatedAcceptor) {
this(transport, useDedicatedAcceptor, false);
}
public RoundRobinConnectionDistributor(final NIOTransport transport,
final boolean useDedicatedAcceptor, final boolean isServerOnly) {
super(transport);
this.it = useDedicatedAcceptor ?
(isServerOnly ? new ServDedicatedIterator() : new DedicatedIterator()) :
(isServerOnly ? new ServSharedIterator() : new SharedIterator());
}
@Override
public void registerChannel(final SelectableChannel channel,
final int interestOps, final Object attachment) throws IOException {
transport.getSelectorHandler().registerChannel(it.next(),
channel, interestOps, attachment);
}
@Override
public void registerChannelAsync(
final SelectableChannel channel, final int interestOps,
final Object attachment,
final CompletionHandler<RegisterChannelResult> completionHandler) {
transport.getSelectorHandler().registerChannelAsync(
it.next(), channel, interestOps, attachment, completionHandler);
}
@Override
public void registerServiceChannelAsync(
final SelectableChannel channel, final int interestOps,
final Object attachment,
final CompletionHandler<RegisterChannelResult> completionHandler) {
transport.getSelectorHandler().registerChannelAsync(
it.nextService(), channel, interestOps,
attachment, completionHandler);
}
private interface Iterator {
SelectorRunner next();
SelectorRunner nextService();
}
private final class DedicatedIterator implements Iterator {
private final AtomicInteger counter = new AtomicInteger();
@Override
public SelectorRunner next() {
final SelectorRunner[] runners = getTransportSelectorRunners();
if (runners.length == 1) {
return runners[0];
}
return runners[((counter.getAndIncrement() & 0x7fffffff) % (runners.length - 1)) + 1];
}
@Override
public SelectorRunner nextService() {
return getTransportSelectorRunners()[0];
}
}
private final class SharedIterator implements Iterator {
private final AtomicInteger counter = new AtomicInteger();
@Override
public SelectorRunner next() {
final SelectorRunner[] runners = getTransportSelectorRunners();
if (runners.length == 1) {
return runners[0];
}
return runners[(counter.getAndIncrement() & 0x7fffffff) % runners.length];
}
@Override
public SelectorRunner nextService() {
return next();
}
}
private final class ServDedicatedIterator implements Iterator {
private int counter;
@Override
public SelectorRunner next() {
final SelectorRunner[] runners = getTransportSelectorRunners();
if (runners.length == 1) {
return runners[0];
}
return runners[((counter++ & 0x7fffffff) % (runners.length - 1)) + 1];
}
@Override
public SelectorRunner nextService() {
return getTransportSelectorRunners()[0];
}
}
private final class ServSharedIterator implements Iterator {
private int counter;
@Override
public SelectorRunner next() {
final SelectorRunner[] runners = getTransportSelectorRunners();
if (runners.length == 1) {
return runners[0];
}
return runners[(counter++ & 0x7fffffff) % runners.length];
}
@Override
public SelectorRunner nextService() {
return next();
}
}
}