Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a single array in SelectedSelectionKeySet #6083

Closed
wants to merge 1 commit into from

Conversation

Scottmitch
Copy link
Member

Motivation:
SelectedSelectionKeySet currently uses 2 arrays internally and users are expected to call flip() to access the underlying array and switch the active array. However we do not concurrently use 2 arrays at the same time and we can get away with using a single array if we are careful about when we reset the elements of the array.

Modifications:

  • Introduce SelectedSelectionKeySetSelector which wraps a Selector and ensures we reset the underlying SelectedSelectionKeySet data structures before we select
  • The loop bounds in NioEventLoop#processSelectedKeysOptimized can be defined more precisely because we know the real size of the underlying array

Result:
Fixes #6058

@Scottmitch Scottmitch self-assigned this Dec 1, 2016
@Scottmitch
Copy link
Member Author

@lightningMan @normanmaurer - FYI

@lightningMan
Copy link

lightningMan commented Dec 2, 2016 via email

@johnou
Copy link
Contributor

johnou commented Dec 2, 2016

@lightningMan Scott is letting you know that he refactored SelectedSelectionKeySet, you can review the code here https://github.com/netty/netty/pull/6083/files

@lightningMan
Copy link

lightningMan commented Dec 2, 2016

@johnou thank you for your friendly reminder, I have reviewed the code ^^

@normanmaurer
Copy link
Member

@Scottmitch I am still not 100 % convinced we need these change and I am a bit concerned about introduce a regression as we also have no tests for this class (as we had none before as well).

So let me cut a release first without this and then we can pick this one up and see... Ok ?

@Scottmitch
Copy link
Member Author

Yip I'm fine with delaying this until 4.1.8.

"Need" is a loaded statement :) Things work today so I guess in that sense I agree, however this simplifies and removes complexity that doesn't seem useful. SelectedSelectionKeySetSelector.java introduced in this PR ensures that we reset the array backing the Set at the appropriate time, and so in theory this should help with correctness (unless there are bugs in my implementation). Bounding the iteration and removing duplicate null checks may also clarify functionality.

@normanmaurer
Copy link
Member

@Scottmitch haha fair enough :) So let us pick this up as first thing after the release 👍

@normanmaurer
Copy link
Member

@Scottmitch if you want to pull this in can you please at least add a testcase for the Set impl ?

@Scottmitch
Copy link
Member Author

@normanmaurer - Fair enough. I added a few unit tests to verify expected behavior. Let me know if you want more.

}
selectedKeys[i] = null;
}
this.selectedKeys.reset(i + 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no null check and break while iterating in reset, intentional?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. We know the explicit size of the array and we check for null on insertion into the set.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right but the previous impl stopped iterating on the first non null element found presumably to avoid iterating the full set and burn less cpu cycles?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current code and the previous code should be logically equivalent but have the following differences:

  • the previous implementation didn't utilize the size of the set when iterating. We now have a fixed/known boundary to iterate to (size) instead of conditional based on the next element contents.
  • This set doesn't allow null elements to be added, so checking each element for null is not necessary.

I pushed some updated code to make the relationship with this.selectedKeys more clear.

for (; start < size; ++start) {
keys[start] = null;
}
size = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does setting size to 0 when start is non 0 make sense?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so. As we iterate over the array in NioEventLoop we null entries out. This method is used if we decide we are done iterating over the array and want to make the set ready for re-use. Do you see an issue here?

Copy link
Contributor

@johnou johnou Feb 12, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no issue comes to mind at the moment, just unexpected that size of the set might be 0 when there are non null entries in the set.

Copy link
Member Author

@Scottmitch Scottmitch Feb 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

general use of this methods may result in non null entries being in the set when the size is zero, but keep in mind this class is package private and so is this method. This shouldn't happen in practice based upon the narrow use case of this class (as we iterate we null elements out, and if we decide to prematurely stop iteration we call this method to null out the remaining elements #6083 (comment)).

@Scottmitch Scottmitch force-pushed the nio_optimized_improve branch 2 times, most recently from 8c87137 to ee85e88 Compare February 13, 2017 01:39
@@ -0,0 +1,66 @@
/*
* Copyright 2013 The Netty Project
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2017

void reset(int start) {
for (; start < size; ++start) {
keys[start] = null;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use Arrays.fill(...) ?

@@ -0,0 +1,80 @@
/*
* Copyright 2016 The Netty Project
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2017 ?

Motivation:
SelectedSelectionKeySet currently uses 2 arrays internally and users are expected to call flip() to access the underlying array and switch the active array. However we do not concurrently use 2 arrays at the same time and we can get away with using a single array if we are careful about when we reset the elements of the array.

Modifications:
- Introduce SelectedSelectionKeySetSelector which wraps a Selector and ensures we reset the underlying SelectedSelectionKeySet data structures before we select
- The loop bounds in NioEventLoop#processSelectedKeysOptimized can be defined more precisely because we know the real size of the underlying array

Result:
Fixes netty#6058
@Scottmitch
Copy link
Member Author

@normanmaurer - comments addressed PTAL

@Scottmitch
Copy link
Member Author

4.1 (795f318) 4.0 (26124f6)

@Scottmitch Scottmitch closed this Feb 16, 2017
@Scottmitch Scottmitch deleted the nio_optimized_improve branch February 16, 2017 23:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants