1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.util.concurrent;
17
18 import io.netty.util.internal.UnstableApi;
19
20 import java.util.concurrent.atomic.AtomicInteger;
21 import java.util.concurrent.atomic.AtomicLong;
22
23
24
25
26 @UnstableApi
27 public final class DefaultEventExecutorChooserFactory implements EventExecutorChooserFactory {
28
29 public static final DefaultEventExecutorChooserFactory INSTANCE = new DefaultEventExecutorChooserFactory();
30
31 private DefaultEventExecutorChooserFactory() { }
32
33 @Override
34 public EventExecutorChooser newChooser(EventExecutor[] executors) {
35 if (isPowerOfTwo(executors.length)) {
36 return new PowerOfTwoEventExecutorChooser(executors);
37 } else {
38 return new GenericEventExecutorChooser(executors);
39 }
40 }
41
42 private static boolean isPowerOfTwo(int val) {
43 return (val & -val) == val;
44 }
45
46 private static final class PowerOfTwoEventExecutorChooser implements EventExecutorChooser {
47 private final AtomicInteger idx = new AtomicInteger();
48 private final EventExecutor[] executors;
49
50 PowerOfTwoEventExecutorChooser(EventExecutor[] executors) {
51 this.executors = executors;
52 }
53
54 @Override
55 public EventExecutor next() {
56 return executors[idx.getAndIncrement() & executors.length - 1];
57 }
58 }
59
60 private static final class GenericEventExecutorChooser implements EventExecutorChooser {
61
62
63
64 private final AtomicLong idx = new AtomicLong();
65 private final EventExecutor[] executors;
66
67 GenericEventExecutorChooser(EventExecutor[] executors) {
68 this.executors = executors;
69 }
70
71 @Override
72 public EventExecutor next() {
73 return executors[(int) Math.abs(idx.getAndIncrement() % executors.length)];
74 }
75 }
76 }