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 e6cf85d78d
commit 90047b0b5f

View File

@ -34,6 +34,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.
@ -63,6 +64,12 @@ public abstract class MultithreadEventExecutorGroup extends AbstractEventExecuto
} }
children = new EventExecutor[nThreads]; children = new EventExecutor[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 {
@ -116,7 +123,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();
} }
/** /**
@ -208,4 +215,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)];
}
}
} }