-
Notifications
You must be signed in to change notification settings - Fork 434
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
Add GC & threshold to the ARP cache. #234
Conversation
c532d8c
to
53fd624
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this
src/iface/neighbor.rs
Outdated
ManagedMap::Borrowed(_) => { | ||
unreachable!() | ||
} | ||
#[cfg(any(feature = "std", feature = "alloc"))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a duplicate if run_gc
is prefixed by the same cfg
.
src/iface/neighbor.rs
Outdated
} | ||
|
||
#[cfg(any(feature = "std", feature = "alloc"))] | ||
pub fn run_gc(&mut self, timestamp: Instant) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you make it clearer that this is only run with the Owned
variant. IMO a doc comment or changing the name to run_owned_gc
would be sufficient.
src/iface/neighbor.rs
Outdated
Cache::new_with_gc_thresh(storage, Cache::GC_THRESH) | ||
} | ||
|
||
pub fn new_with_gc_thresh<T>(storage: T, gc_thresh: usize) -> Cache<'a> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would with_limit
be more readable. 🚲 🏠
src/iface/neighbor.rs
Outdated
} | ||
#[cfg(any(feature = "std", feature = "alloc"))] | ||
ManagedMap::Owned(ref mut map) => { | ||
net_trace!("In the Owned Case"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this necessary? Or was this just used for debugging?
53fd624
to
d05215f
Compare
@dlrobertson, awesome, thanks for the review. updated! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
cool! @dlrobertson do you have any ides for other issues that might be good to get started on next? thanks |
src/iface/neighbor.rs
Outdated
@@ -51,6 +51,7 @@ pub(crate) enum Answer { | |||
pub struct Cache<'a> { | |||
storage: ManagedMap<'a, IpAddress, Neighbor>, | |||
silent_until: Instant, | |||
gc_thresh: usize |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gc_threshold
, please
src/iface/neighbor.rs
Outdated
@@ -60,23 +61,59 @@ impl<'a> Cache<'a> { | |||
/// Neighbor entry lifetime, in milliseconds. | |||
pub(crate) const ENTRY_LIFETIME: Duration = Duration { millis: 60_000 }; | |||
|
|||
/// Default number of entries in the cache before GC kicks in | |||
pub(crate) const GC_THRESH: usize = 1024; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also here
src/iface/neighbor.rs
Outdated
let mut storage = storage.into(); | ||
storage.clear(); | ||
|
||
Cache { storage, silent_until: Instant::from_millis(0) } | ||
Cache { storage, gc_thresh: gc_thresh, silent_until: Instant::from_millis(0) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use gc_thresh
instead of gc_thresh: gc_thresh
.
src/iface/neighbor.rs
Outdated
} | ||
|
||
#[cfg(any(feature = "std", feature = "alloc"))] | ||
pub fn run_owned_gc(&mut self, timestamp: Instant) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this really be pub
?
src/iface/neighbor.rs
Outdated
unreachable!() | ||
} | ||
ManagedMap::Owned(ref mut map) => { | ||
map.iter_mut() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe .into_iter()
so that we don't need to clone values? If the naive form doesn't pass borrow checker, use swap
.
src/iface/neighbor.rs
Outdated
} | ||
|
||
pub(crate) fn fill(&mut self, protocol_addr: IpAddress, hardware_addr: EthernetAddress, | ||
timestamp: Instant) { | ||
debug_assert!(protocol_addr.is_unicast()); | ||
debug_assert!(hardware_addr.is_unicast()); | ||
|
||
match self.storage { | ||
ManagedMap::Borrowed(_) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit
ManagedMap::Borrowed(_) => (),
src/iface/neighbor.rs
Outdated
#[cfg(any(feature = "std", feature = "alloc"))] | ||
ManagedMap::Owned(_) => { | ||
if self.storage.len() >= self.gc_thresh { | ||
self.run_owned_gc(timestamp); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be more readable to have a static method that runs GC on a BTreeMap
instead of self
? That way we don't have the match
with the unreachable
statement. Just a thought.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
d05215f
to
5a974dc
Compare
@whitequark @dlrobertson Updated. The problem with the static btree approach is that you can't assign |
I think a doc comment could solve this. |
5a974dc
to
d91f114
Compare
Ah, realized something with the test failure. This isn't going to work with the case where we are using I also don't like that i have to add Thinking it might make sense to just switch back to the non-static |
Here's what I had originally for reference (with updates for the other PR comments here): https://github.com/m-labs/smoltcp/compare/master...squidarth:ss-83-arp-cache-eviction-2?expand=1 |
IMO adding a
I think you have two other alternatives here that would be a bit cleaner.
#[cfg(feature = "std")]
use std::collections::BTreeMap;
#[cfg(all(not(feature = "std"), feature = "alloc"))]
use alloc::btree_map::BTreeMap; |
aaded5f
to
3fbc626
Compare
@dlrobertson Great, updated!
Yep, and now that I've inlined it, I don't need to import |
src/iface/neighbor.rs
Outdated
.filter(|(_, v)| timestamp < v.expires_at) | ||
.collect(); | ||
|
||
replace(map, new_btree_map); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 last nit: use core::mem
so that this becomes mem::replace
, then it becomes more clear that core::mem::replace
is being used here.
👍 sounds good, updated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Looks good to me.
@whitequark any other feedback for this patch? |
Sorry for the delay on this--looks good! Thanks @squidarth! @m-labs-homu r+ |
📌 Commit 4f783ce has been approved by |
Closes: #234 Approved by: whitequark
Closes: #234 Approved by: whitequark
Closes: #234 Approved by: whitequark
💔 Test failed - status-travis |
@m-labs-homu retry |
Closes: #234 Approved by: whitequark
Closes: #234 Approved by: whitequark
Closes: #234 Approved by: whitequark
💔 Test failed - status-travis |
Oh--can you please squash the commits? |
4f783ce
to
fba1afd
Compare
@m-labs-homu retry |
@squidarth: 🔑 Insufficient privileges: not in try users |
@m-labs-homu r=whitequark |
📌 Commit fba1afd has been approved by |
☀️ Test successful - status-travis |
@squidarth Thanks for working on this! |
Implementation of solution discussed in: #83
Main things to look at:
I figured this only really makes sense for the
ManagedMap::Owned
case, so I conditionally compile for thealloc
case. Let me know if this is wrongThere weren't any tests in the
neighbor.rs
file that use theOwned
case, so I had to start usingBTreeMap
. I'm not totally sure what the downsides of this are, so let me know if there's anything I should be aware of.The reason I needed to upgrade the version of
managed
is so that we could havelen
operator on ManagedMap.Manual Testing
I did manually test this with the
httpclient
example (i changed around whererun_gc
gets run in order to make it do something) and checked that the sizes were correct.thanks for taking a look at this!