[#3377] Faster overflow guard when generate nextId in EpollEventLoop

Motivation:

The current way how the guard against overflow when generating the nextId() is pretty slow once an overflow happened.

Modifications:

Once a possible overflow is detected all ids used by the EpollEventLoop are scrubed and re-assigned to the registered Channels. This way we only need to do extra work each time an overflow is detected.

Result:

More consistent performance even after the first overflow was detected.
This commit is contained in:
Norman Maurer 2015-01-29 09:45:17 +01:00
parent e0f2e1e2a1
commit 94c6c83318

View File

@ -55,7 +55,6 @@ final class EpollEventLoop extends SingleThreadEventLoop {
private final long[] events;
private int id;
private boolean overflown;
@SuppressWarnings("unused")
private volatile int wakenUp;
@ -95,21 +94,23 @@ final class EpollEventLoop extends SingleThreadEventLoop {
private int nextId() {
int id = this.id;
if (id == Integer.MAX_VALUE) {
overflown = true;
// We used all possible ints in the past ( 1 - Integer.MAX_VALUE), time to scrub the stored channels
// and re-assign ids.
AbstractEpollChannel[] channels = ids.values(AbstractEpollChannel.class);
ids.clear();
id = 0;
}
if (overflown) {
// the ids had an overflow before so we need to make sure the id is not in use atm before assign
// it.
for (;;) {
if (!ids.containsKey(++id)) {
this.id = id;
break;
}
for (AbstractEpollChannel ch: channels) {
id++;
ch.id = id;
ids.put(ch.id, ch);
}
if (id == Integer.MAX_VALUE) {
throw new IllegalStateException("Could not scrub ids");
}
} else {
this.id = ++id;
}
this.id = ++id;
return id;
}