Use bitwise operations to choose next EventExecutor if number of EventExecutors is power of two

This commit is contained in:
Norman Maurer 2014-03-10 19:53:16 +01:00
parent ae20f278ff
commit 072c5e3cc6

View File

@ -33,6 +33,7 @@ public abstract class MultithreadEventExecutorGroup extends AbstractEventExecuto
private final AtomicInteger childIndex = new AtomicInteger(); private final AtomicInteger childIndex = new AtomicInteger();
private final AtomicInteger terminatedChildren = new AtomicInteger(); private final AtomicInteger terminatedChildren = new AtomicInteger();
private final Promise<?> terminationFuture = new DefaultPromise(GlobalEventExecutor.INSTANCE); private final Promise<?> terminationFuture = new DefaultPromise(GlobalEventExecutor.INSTANCE);
private final EventExecutorChooser chooser;
/** /**
* Create a new instance. * Create a new instance.
@ -51,6 +52,12 @@ public abstract class MultithreadEventExecutorGroup extends AbstractEventExecuto
} }
children = new SingleThreadEventExecutor[nThreads]; children = new SingleThreadEventExecutor[nThreads];
if (isPowerOfTwo(children.length)) {
chooser = new PowerOfTwoEventExecutorChooser();
} else {
chooser = new GenericEventExecutorChooser();
}
for (int i = 0; i < nThreads; i ++) { for (int i = 0; i < nThreads; i ++) {
boolean success = false; boolean success = false;
try { try {
@ -100,7 +107,7 @@ public abstract class MultithreadEventExecutorGroup extends AbstractEventExecuto
@Override @Override
public EventExecutor next() { public EventExecutor next() {
return children[Math.abs(childIndex.getAndIncrement() % children.length)]; return chooser.next();
} }
@Override @Override
@ -201,4 +208,26 @@ public abstract class MultithreadEventExecutorGroup extends AbstractEventExecuto
} }
return isTerminated(); return isTerminated();
} }
private static boolean isPowerOfTwo(int val) {
return (val & -val) == val;
}
private interface EventExecutorChooser {
EventExecutor next();
}
private final class PowerOfTwoEventExecutorChooser implements EventExecutorChooser {
@Override
public EventExecutor next() {
return children[childIndex.getAndIncrement() & children.length - 1];
}
}
private final class GenericEventExecutorChooser implements EventExecutorChooser {
@Override
public EventExecutor next() {
return children[Math.abs(childIndex.getAndIncrement() % children.length)];
}
}
} }