[#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 final long[] events;
private int id; private int id;
private boolean overflown;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private volatile int wakenUp; private volatile int wakenUp;
@ -95,21 +94,23 @@ final class EpollEventLoop extends SingleThreadEventLoop {
private int nextId() { private int nextId() {
int id = this.id; int id = this.id;
if (id == Integer.MAX_VALUE) { 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; id = 0;
}
if (overflown) { for (AbstractEpollChannel ch: channels) {
// the ids had an overflow before so we need to make sure the id is not in use atm before assign id++;
// it. ch.id = id;
for (;;) { ids.put(ch.id, ch);
if (!ids.containsKey(++id)) { }
this.id = id; if (id == Integer.MAX_VALUE) {
break; throw new IllegalStateException("Could not scrub ids");
}
} }
} else {
this.id = ++id;
} }
this.id = ++id;
return id; return id;
} }