Skip to content

Commit

Permalink
AFSelector: Use single ConcurrentHashMap for registered/selected keys
Browse files Browse the repository at this point in the history
Since we already have a ConcurrentHashMap, let's make use of the value,
which now indicates the "selected" state.

Introduce MapValueSet, which is a view over elements of the
"keysRegistered" map, and precisely only those elements that have a
certain value.

For each call to select, we increment the expected value, and then set
only the actually selected entries to that value, so we don't have to
clear the entire map.

#145
  • Loading branch information
kohlschuetter committed Nov 9, 2023
1 parent 5e8a6e6 commit 2d66d65
Show file tree
Hide file tree
Showing 2 changed files with 344 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

final class AFSelector extends AbstractSelector {
private final AFPipe selectorPipe;
Expand All @@ -41,13 +42,15 @@ final class AFSelector extends AbstractSelector {
private final ByteBuffer pipeMsgWakeUp = ByteBuffer.allocate(1);
private final ByteBuffer pipeMsgReceiveBuffer = ByteBuffer.allocateDirect(256);

private final Map<AFSelectionKey, Boolean> keysRegistered = new ConcurrentHashMap<>();
private final Map<AFSelectionKey, Integer> keysRegistered = new ConcurrentHashMap<>();
private final Set<AFSelectionKey> keysRegisteredKeySet = keysRegistered.keySet();
private final Set<SelectionKey> keysRegisteredPublic = Collections.unmodifiableSet(
keysRegisteredKeySet);

private final Map<SelectionKey, SelectionKey> selectedKeysSet = new ConcurrentHashMap<>();
private final Set<SelectionKey> selectedKeysPublic = new UngrowableSet<>(selectedKeysSet.keySet());
private final AtomicInteger selectCount = new AtomicInteger(0);
private final MapValueSet<SelectionKey, Integer> selectedKeysSet =
new MapValueSet<SelectionKey, Integer>(keysRegistered, selectCount::get, 0);
private final Set<SelectionKey> selectedKeysPublic = new UngrowableSet<>(selectedKeysSet);

private PollFd pollFd = null;

Expand All @@ -63,7 +66,7 @@ protected SelectionKey register(AbstractSelectableChannel ch, int ops, Object at
AFSelectionKey key = new AFSelectionKey(this, ch, ops, att);
synchronized (this) {
pollFd = null;
keysRegistered.put(key, Boolean.TRUE);
selectedKeysSet.markRemoved(key);
}
return key;
}
Expand Down Expand Up @@ -106,12 +109,15 @@ public int select() throws IOException {
@SuppressWarnings("PMD.CognitiveComplexity")
private int select0(int timeout) throws IOException {
PollFd pfd;

int selectId = updateSelectCount();

synchronized (this) {
if (!isOpen()) {
throw new ClosedSelectorException();
}

pfd = pollFd = initPollFd(pollFd);
selectedKeysSet.clear();
}
int num;
try {
Expand All @@ -121,7 +127,6 @@ private int select0(int timeout) throws IOException {
end();
}
synchronized (this) {
selectedKeysSet.clear();
pfd = pollFd;
if (pfd != null) {
AFSelectionKey[] keys = pfd.keys;
Expand All @@ -138,7 +143,7 @@ private int select0(int timeout) throws IOException {
}
if (num > 0) {
consumeAllBytesAfterPoll();
setOpsReady(pfd); // updates keysSelected and numKeysSelected
setOpsReady(pfd, selectId); // updates keysSelected and numKeysSelected
}
return selectedKeysSet.size();
}
Expand Down Expand Up @@ -178,14 +183,24 @@ private synchronized void consumeAllBytesAfterPoll() throws IOException {
}
}

private synchronized void setOpsReady(PollFd pfd) {
private int updateSelectCount() {
int selectId = selectCount.incrementAndGet();
if (selectId == 0) {
// overflow (unlikely)
selectedKeysSet.markAllRemoved();
selectId = selectCount.incrementAndGet();
}
return selectId;
}

private void setOpsReady(PollFd pfd, int selectId) {
if (pfd != null) {
for (int i = 1; i < pfd.rops.length; i++) {
int rops = pfd.rops[i];
AFSelectionKey key = pfd.keys[i];
key.setOpsReady(rops);
if (rops != 0) {
selectedKeysSet.put(key, key);
keysRegistered.computeIfPresent(key, (k, v) -> selectId);
}
}
}
Expand Down
Loading

0 comments on commit 2d66d65

Please sign in to comment.